Menü
Bedava
kayıt
ev  /  Gezginler/ Uygulamaların sunucu tarafında nasıl çalıştığı. Mobil Uygulama Geliştirme: Sunucu Senkronizasyonu

Uygulamaların sunucu tarafında nasıl çalıştığı. Mobil Uygulama Geliştirme: Sunucu Senkronizasyonu

Bir istemci-sunucu uygulamasının sunucu tarafının geliştirilmesi, mimarinin tasarımı ile başlar. Çok şey mimariye bağlıdır: uygulamanın genişletilebilirliğinden performansına ve destek/bakım kolaylığına kadar.

Öncelikle verilerin sunucuya nasıl yerleştirileceğini ve istemciden gelen isteklerin nasıl işleneceğini belirlemeniz gerekir. Ayrıca sunucu verilerinin önbelleğe alınmasının organizasyonu hakkında da düşünmeniz gerekir.

Veri alışverişi protokollerinin ve veri aktarım formatlarının belirlenmesi gereklidir.

API (uygulama programlama arabirimi), bir uygulama programlama arabirimidir. Daha anlaşılır bir dilde, bu, sunucunun anladığı ve doğru cevabı verebileceği bir dizi istektir. API, sunucu tarafı mantığının işlevselliğini tanımlarken API, bu işlevselliğin tam olarak nasıl uygulandığından soyutlamanıza izin verir. Diğer bir deyişle API, genel istemci/sunucu altyapısının gerekli bir parçasıdır.

JSON ve XML'i karşılaştırın. Uygulama türüne bağlı olarak bir protokol örneği sağlayın.

çoklu kullanım

Modern programlamanın en önemli yönlerinden biri çoklu kullanımdır. Multithreading yardımı ile aynı anda çeşitli görevleri gerçekleştirecek bir uygulamada birden fazla thread atayabiliyoruz.

Çoklu iş parçacığı, bir platformun (örneğin, bir işletim sistemi, sanal makine, vb.) veya bir işletim sisteminde oluşturulan bir işlemin "paralel" çalışan, yani önceden belirlenmiş bir zamanında sipariş verin.

Çoklu iş parçacığının özü, yürütülebilir bir işlem düzeyinde yarı çoklu görevdir, yani tüm iş parçacıkları işlemin adres alanında yürütülür. Ayrıca, bir işlemdeki tüm iş parçacıklarının yalnızca ortak bir adres alanı değil, aynı zamanda ortak dosya tanımlayıcıları da vardır. Çalışan bir işlemin en az bir (ana) iş parçacığı vardır.

Çoklu iş parçacığı (bir programlama doktrini olarak), çoklu görev uygulayan işletim sistemlerinin de çoklu iş parçacığı uygulama eğiliminde olmasına rağmen, çoklu görev veya çoklu işlem ile karıştırılmamalıdır.

Programlamada çoklu iş parçacığının avantajları şunları içerir:

Ortak bir adres alanı kullanımı nedeniyle bazı durumlarda programın basitleştirilmesi.

Süreçle ilgili olarak akış oluşturmaya daha az zaman harcanır.

İşlemci hesaplamalarının ve G/Ç işlemlerinin paralel hale getirilmesi nedeniyle süreç verimliliğinin arttırılması.

Akış(thread), yönetilen bir yürütülebilir kod birimidir. İş parçacığı tabanlı çoklu görev ortamında, çalışan tüm işlemlerin bir ana iş parçacığı olması gerekir, ancak daha fazlası da olabilir. Bu, birden fazla görevin bir programda eşzamansız olarak gerçekleştirilebileceği anlamına gelir. Örneğin, bu iki görev farklı iş parçacıklarında gerçekleştirildiğinden, yazdırma sırasında metin düzenleyicide metin düzenleme.

Geleneksel bir işlemcide akış denetimi, işletim sistemi tarafından gerçekleştirilir. Bir iş parçacığı, bir donanım kesintisi, bir sistem çağrısı veya işletim sistemi tarafından kendisine ayrılan süre dolana kadar yürütülür. Bundan sonra işlemci, iş parçacığının durumunu (bağlamını) kaydeden veya yürütme için de ayrılan başka bir iş parçacığının durumuna geçen işletim sistemi koduna geçer. Bu tür çoklu iş parçacığıyla, bağlamları değiştiren işletim sistemi koduna oldukça fazla sayıda işlemci döngüsü harcanır. Donanımda iş parçacığı desteği uygulanırsa, işlemcinin kendisi iş parçacıkları arasında geçiş yapabilecek ve ideal olarak her saat döngüsü için aynı anda birkaç iş parçacığı yürütebilecektir.

- Geçici çoklu kullanım (tek iş parçacığı)

- Eşzamanlı çoklu kullanım (aynı anda birden çok iş parçacığı)

Yaygın bir programlama ve kod yürütme modeli olarak çoklu iş parçacığı, tek bir işlem içinde birden çok iş parçacığının yürütülmesine izin verir. Bu yürütme dizileri, işlemin kaynaklarını paylaşır, ancak bağımsız olarak da çalışabilirler. Çok iş parçacıklı programlama modeli, geliştiricilere paralel yürütme için uygun bir soyutlama sağlar. Bununla birlikte, teknolojinin belki de en ilginç uygulaması, çok işlemcili bir sistemde paralel yürütülmesine izin veren tek bir işleme uygulanmasıdır.

Çok iş parçacıklı bir programın bu avantajı, birden çok işlemciye sahip bilgisayar sistemlerinde, birden çok çekirdeğe sahip bir işlemcide veya bir makine kümesinde daha hızlı çalışmasına olanak tanır - çünkü program yürütme iş parçacıkları doğal olarak süreçlerin gerçekten paralel yürütülmesine izin verir. Bu durumda, programcının yarış koşullarından ve diğer sezgisel olmayan davranışlardan kaçınmak için çok dikkatli olması gerekir. Verileri düzgün bir şekilde işlemek için, veriyi doğru sırada işlemek için yürütme iş parçacıkları sıklıkla randevu prosedüründen geçmelidir. Yürütme iş parçacıkları ayrıca, güncelleme işlemi sırasında paylaşılan verilerin aynı anda değiştirilmesini veya okunmasını önlemek için mutekslere (genellikle semaforlar kullanılarak uygulanır) ihtiyaç duyabilir. Bu tür ilkellerin dikkatsiz kullanımı bir çıkmaza yol açabilir.

Tek işlemcili sistemler için bile geçerli olan çoklu iş parçacığının başka bir kullanımı, bir uygulamanın girdiye yanıt verme yeteneğidir. Tek iş parçacıklı programlarda, ana iş parçacığı uzun süren bir görev tarafından engellenirse, tüm uygulama dondurulabilir. Bu tür zaman alıcı görevleri, ana iş parçacığı ile paralel çalışan bir çalışan iş parçacığına taşıyarak, görevler arka planda çalışırken uygulamaların kullanıcı girişine yanıt vermeye devam etmesi mümkün hale gelir. Öte yandan, çoğu durumda, bir programın hassasiyetini korumanın tek yolu çoklu iş parçacığı değildir. Aynısı, eşzamansız G / Ç veya UNIX üzerindeki sinyaller yoluyla da elde edilebilir.

Toplamda iki tür çoklu görev vardır: süreçlere dayalı ve akışlara dayalı... İşlem ve iş parçacığı tabanlı çoklu görev arasındaki fark şu şekilde özetlenebilir: süreç tabanlı çoklu görev, programların paralel yürütülmesi için düzenlenir ve iş parçacığı tabanlı çoklu görev, aynı programın ayrı bölümlerinin paralel yürütülmesi içindir.

Toplamda, iki tür akış ayırt edilir:

Ön plan konuları veya ön plan. Varsayılan olarak, Thread.Start() yöntemiyle oluşturulan her iş parçacığı otomatik olarak ön plan iş parçacığı olur. Bu tür iş parçacıkları, mevcut uygulamanın sonlandırılmaya karşı korunmasını sağlar. CLR, tüm ön plan iş parçacıkları bitene kadar uygulamayı durdurmaz.

Arka plan konuları Bu tür iş parçacığına arka plan programı iş parçacığı da denir ve CLR tarafından herhangi bir zamanda göz ardı edilebilecek genişletilebilir yürütme yolları olarak yorumlanır. Bu nedenle, tüm ön plan iş parçacıkları sonlandırılırsa, uygulama etki alanı kaldırıldığında tüm arka plan iş parçacıkları otomatik olarak yok edilir. Arka plan iş parçacıkları oluşturmak için IsBackground özelliğini true olarak ayarlayın.

İpliklerin durumlarından bahsedin: koşuyor, askıya alınıyor, koşuyor, ancak bir şey bekliyor.

İş parçacığı senkronizasyon sorunu ve paylaşılan kaynaklar.

Konuların etkileşimi

Çok iş parçacıklı bir ortamda, aynı verilerin veya aygıtların paralel yürütme iş parçacıkları tarafından kullanılmasıyla ilgili sorunlar genellikle ortaya çıkar. Bu tür sorunları çözmek için, muteksler, semaforlar, kritik bölümler ve olaylar gibi iş parçacıklarının etkileşim yöntemleri kullanılır.

muteks Herhangi bir iş parçacığı ile meşgul olmadığında özel bir sinyal durumuna ayarlanmış bir senkronizasyon nesnesidir. Bu nesne herhangi bir zamanda yalnızca bir iş parçacığına sahiptir, bu nedenle bu tür nesnelerin adı (İngilizce karşılıklı özel erişimden) - paylaşılan bir kaynağa eşzamanlı erişim hariç tutulur. Gerekli tüm eylemler gerçekleştirildikten sonra, muteks serbest bırakılır ve diğer iş parçacıklarının paylaşılan kaynağa erişmesine izin verilir. Nesne, aynı iş parçacığı tarafından ikinci kez özyinelemeli yakalamayı destekleyebilir, iş parçacığını engellemeden sayacı artırır ve ardından birden çok serbest bırakma gerektirebilir. Bu, örneğin, Win32'deki kritik bölümdür. Ancak, bunu desteklemeyen ve özyinelemeli bir yakalama denerken iş parçacığının kilitlenmesine neden olan bazı uygulamalar vardır. Bu, Windows çekirdeğindeki FAST_MUTEX'dir.

semaforlar kaynak havuzu boşalana kadar aynı anda birden çok iş parçacığı tarafından alınabilen kullanılabilir kaynaklardır. Ardından ek iş parçacıkları, gerekli miktarda kaynak tekrar kullanılabilir olana kadar beklemelidir. Semaforlar kaynaklara eşzamanlı erişime izin verdikleri için çok verimlidir.

Gelişmeler... Üzerinde "sinyal", "sinyalsiz duruma sıfırlama" ve "bekle" işlemlerinin tanımlandığı "sinyalli veya değil" 1 bitlik bilgi depolayan bir nesne. Sinyallenmiş bir olayı beklemek, iş parçacığı yürütmesinin hemen devam etmesiyle bir işlemin olmamasıdır. Seçilmemiş bir olayda beklemek, başka bir iş parçacığı (veya işletim sistemi çekirdeğindeki kesme işleyicisinin ikinci aşaması) olayı bildirene kadar iş parçacığının askıya alınmasına neden olur. "Herhangi biri" veya "tümü" modlarında birkaç olayı beklemek mümkündür. İlk ve tek bekleyen iş parçacığı uyandıktan sonra otomatik olarak sinyalsiz bir duruma sıfırlanan bir olay oluşturmak da mümkündür (böyle bir nesne "kritik bölüm" nesnesinin uygulanması için temel olarak kullanılır). MS Windows'ta hem kullanıcı modunda hem de çekirdek modunda aktif olarak kullanılırlar. Linux çekirdeğinde kwait_queue adında benzer bir nesne var.

kritik bölümler kritik bölümleri temsil eden nesnelerin aynı işlem içinde mevcut olması dışında mutekslere benzer senkronizasyon sağlar. Olaylar, muteksler ve semaforlar tek işlemli bir uygulamada da kullanılabilir, ancak bazı işletim sistemlerindeki (Windows NT gibi) kritik bölüm uygulamaları, daha hızlı ve daha verimli, birbirini dışlayan bir eşitleme mekanizması sağlar - kritik üzerinde alma ve bırakma işlemleri. bölümü, işletim sistemi çekirdeğine yol açan herhangi bir sistem çağrısını önlemek için tek bir iş parçacığı (çekişme yok) durumu için optimize edilmiştir. Muteksler gibi, kritik bir bölümü temsil eden bir nesne, aynı anda yalnızca bir iş parçacığı tarafından kullanılabilir, bu da onları paylaşılan kaynaklara erişimi sınırlamak için son derece yararlı kılar.

koşullu değişkenler(kondvarlar). Olaylara benzerler, ancak hafızayı işgal eden nesneler değiller - yalnızca bir değişkenin adresi kullanılır, "bir değişkenin içeriği" kavramı yoktur, isteğe bağlı bir nesnenin adresi koşullu bir değişken olarak kullanılabilir . Olaylardan farklı olarak, bir koşul değişkenini sinyallenmiş bir duruma ayarlamak, şu anda değişken üzerinde bekleyen hiçbir iş parçacığı yoksa sonuç doğurmaz. Benzer bir durumda bir olay ayarlamak, olayın kendi içinde "sinyallenmiş" durumu saklamayı gerektirir, bundan sonra olayı beklemek isteyen sonraki iş parçacıkları durmadan hemen yürütmeye devam eder. Böyle bir nesneden tam olarak yararlanmak için, mutex'i serbest bırakmak ve koşullu değişkeni atomik olarak beklemek de gereklidir. UNIX benzeri işletim sistemlerinde yaygın olarak kullanılırlar. Olayların ve koşul değişkenlerinin avantajları ve dezavantajları hakkındaki tartışmalar, Windows ve UNIX'in avantajları ve dezavantajları hakkındaki tartışmaların dikkate değer bir parçasıdır.

G / Ç tamamlama bağlantı noktası(IO tamamlama bağlantı noktası, IOCP). İşletim sistemi çekirdeğinde uygulanan ve "yapıyı kuyruğun kuyruğuna koy" ve "sıranın başından sonraki yapıyı al" işlemleriyle sistem çağrıları aracılığıyla erişilebilen "kuyruk" nesnesi - son çağrı yürütmeyi duraklatır sıra boşsa iş parçacığı ve başka bir iş parçacığı "koymak" için arama yapmaz. IOCP'nin en önemli özelliği, yapıların yalnızca kullanıcı modundan açık bir sistem çağrısı ile değil, aynı zamanda dosya tanımlayıcılarından birinde tamamlanan asenkron bir I/O işlemi sonucunda OS çekirdeği içinde örtük olarak yerleştirilebilmesidir. Bu etkiyi elde etmek için, "dosya tanımlayıcıyı IOCP'ye bağla" sistem çağrısını kullanmalısınız. Bu durumda kuyruğa yerleştirilen yapı, I/O işleminin hata kodunu ve ayrıca bu işlem başarılı olursa fiilen giriş veya çıkış baytlarının sayısını içerir. Tamamlama bağlantı noktası uygulaması, bir yapı kuyruğa alındıktan sonra tek bir işlemci/çekirdek üzerinde çalışan iş parçacıklarının sayısını da sınırlar. Nesne MS Windows'a özeldir ve iş parçacığı sayısının istemci sayısından daha az olabileceği bir mimaride sunucu yazılımındaki gelen bağlantı isteklerinin ve veri yığınlarının işlenmesine izin verir (kaynak tüketimi ile ayrı bir iş parçacığı oluşturma gereksinimi yoktur). her yeni müşteri).

Konu havuzu

İplik havuzundan bahsedin

Modern olanın çoğu mobil platformlar için uygulamalar(iOS, Android, vb.) bir sunucu ile birlikte çalışır. Güncel olmayan verilere sahip bir uygulama kullanışlılığını kaybeder. Bu nedenle sunucudan cihaza gelen verilerin güncel tutulmasını sağlamak önemlidir. Bu, İnternet olmadan çalışması gereken çevrimdışı uygulamalar için geçerlidir. İnternet olmadan çalışmayan (veya faydasız olan) tamamen çevrimiçi uygulamalar (örneğin, Foursquare, Facebook) için bu makalenin kapsamı dışında kalan özellikler vardır.

Çevrimdışı uygulamalarımızdan birinin örneğini kullanarak, verileri senkronize etmek için hangi yaklaşımları kullandığımızı anlatacağım. İlk sürümlerde Geliştirdik basit algoritmalar ve gelecekte deneyimle bunları geliştirdik. Makalede benzer bir sıra sunulmaktadır - basit bariz uygulamalardan daha karmaşık olanlara.

Makalenin yalnızca bir yönde veri aktarımı ile ilgili olduğu açıklığa kavuşturulmalıdır: sunucudan cihaza. Burada sunucu veri kaynağıdır.

Tüm yaklaşımlar için genel hükümler

Örnek olarak, cihaza bir yemek dizini (“yemekler”) aktarmayı ele alacağız. Cihazın / servis / bulaşık / güncelleme url'si için bir istekte bulunduğunu varsayacağız, değişim JSON formatında http protokolü aracılığıyla gerçekleştirilir ( www.json.org). Sunucuda aşağıdaki alanlara sahip bir “yemekler” tablosu vardır: id (kayıt tanımlayıcı), ad (yemeğin adı), güncellendi (yemek güncellendiği an, saat dilimi desteğini hemen yapmak daha iyidir, “YYYY-AA -DDThh: aa: ssTZD”, örneğin, “1997 -07-16T19: 20: 30 + 01: 00 ”), is_deleted (silinen kaydın işareti).

Son alanın varlığına ilişkin açıklama. Varsayılan olarak değeri 0'dır. Varlıkların istemci ve sunucu arasında senkronize edildiği bir uygulamada, verilerin sunucudan fiziksel olarak silinmesi (hataları önlemek için) önerilmez. Bu nedenle silinen yemekler için is_deleted = 1 ayarlanır.is_deleted = 1 olan bir varlık cihaza geldiğinde cihazdan silinir.

Aşağıda ele alınacak herhangi bir yaklaşımla, sunucu bir dizi nesneyi JSON cihazlarına döndürür (boş olabilir):

[
(İD: , isim: , güncellenmiş: , silindi: },…
]

Sunucu yanıtı örneği:

[
(id: 5625, ad: "Ekmek", güncellendi: "2013-01-06 06:23:12", Silindi: 0),
(id: 23, isim: "Pişmiş irmik", güncellendi: "2013-02-01 14:44:21", silindi: 0), (

isim: "Balık çorbası",

güncellendi: "2013-08-02 07:05:19",

Bir cihazdaki verileri güncelleme ilkeleri

  1. Cihazdaki bir öğe geldiyse ve Silindi = 0 ise, güncellenir
  2. Cihazda olmayan bir öğe geldiyse ve Silindi = 0 ise eklenir.
  3. Cihazdaki bir eleman geldiyse ve Silindi = 1 ise silinir.
  4. Cihazda olmayan bir öğe geldiyse ve Silindi = 1 ise, hiçbir şey yapılmaz.

Yaklaşım 1: Her şey her zaman senkronizedir

Bu en kolay yöntemdir. Cihaz, sunucudan bir bulaşık listesi ister ve sunucu tüm listeyi gönderir. Tüm liste her geldiğinde. Sıralanmamış.

Örnek istek: null veya “()”

Avantajlar:

  • sunucudaki mantık basittir - her zaman her şeyi veririz
  • cihazdaki mantık basittir - her zaman her şeyin üzerine yazarız

Dezavantajları:

  • listeyi sık sık (her 10 dakikada bir) talep ederseniz, çok fazla İnternet trafiği olacaktır.
  • listeyi nadiren talep ederseniz (günde bir kez), verilerin alaka düzeyi ihlal edilecektir.

Uygulama alanı:

  • düşük trafik uygulamaları için
  • çok nadiren değişen verilerin iletimi (şehir listesi, kategoriler)
  • uygulama ayarlarının aktarılması
  • bir mobil uygulamanın ilk prototipi için projenin başında

Yaklaşım 2: yalnızca güncellenenleri senkronize edin

Cihaz, önceki senkronizasyondan güncellenen bir yemek listesi ister. Liste, artan düzende "güncellendi" olarak sıralanır (isteğe bağlı, ancak kullanışlı). Cihaz en son gönderilen çanak için “güncellendi” değerini saklar ve bir sonraki istekte “lastUpdated” parametresinde sunucuya gönderir. Sunucu, “lastUpdated”den (güncellendi> lastUpdated) daha yeni olan yemeklerin bir listesini gönderir. Sunucuya ilk istekte “lastUpdated” = null.

Örnek istek: (sonGüncelleme: “2013-01-01 00:00:00”)

Şemada: “last_updated”, cihazda depolanan değerdir. Genellikle bu “last_updated” değerlerinin her bir varlık (yemek, şehir, organizasyon vb.)

Bu yaklaşım, varış kurallarının tüm cihazlar için aynı olduğu basit doğrusal listeleri senkronize etmek için uygundur. Daha seçici senkronizasyon için bkz. “Yaklaşım 5: Cihazda bulunanların bilgisiyle senkronize edin”.

Bu yaklaşım genellikle çoğu ihtiyacı karşılar. Cihaza yalnızca yeni veriler gelir, en az her dakika senkronize edebilirsiniz - trafik az olacaktır. Ancak, mobil cihazların sınırlamalarıyla ilgili sorunlar var. Bunlar bellek ve işlemcidir.

Yaklaşım 3: Gruplar halinde senkronize edin

Mobil cihazların RAM'i düşük. Dizinde 3000 yemek varsa, sunucudan büyük bir json dizesini cihazdaki nesnelere ayrıştırmak bellek eksikliğine neden olabilir. Bu durumda uygulama ya çökecek ya da bu 3000 yemeği kaydetmeyecektir. Ancak cihaz böyle bir diziyi sindirebilse bile, arka planda senkronizasyon anlarında uygulamanın performansı düşük olacaktır (arayüz gecikmeleri, düzgün kaydırma değil vb.) Bu nedenle, listeyi istemek gerekir. daha küçük porsiyonlarda.

Bunu yapmak için cihaz, porsiyonun boyutunu belirleyen bir parametre daha (“miktar”) iletir. Liste, artan düzende "güncellendi" alanına göre sıralanmış olarak gönderilmelidir. Cihaz, önceki yaklaşıma benzer şekilde, son gönderilen varlığın “güncellenmiş” değerini hatırlar ve “lastUpdated” alanına iletir. Sunucu tam olarak aynı sayıda varlık gönderdiyse, cihaz senkronizasyona devam eder ve yeniden bir istekte bulunur, ancak güncellenmiş “lastUpdated” ile. Sunucu daha az varlık gönderdiyse, bu, daha fazla yeni veriye sahip olmadığı ve senkronizasyonun sona erdiği anlamına gelir.

Diyagramda: “last_updated” ve “tutar”, içinde saklanan değerlerdir. mobil uygulama... "Last_item" - sunucudan gönderilen son varlık (yemek). Bir sonraki listenin isteneceği bu değerden daha yenidir.

Örnek istek: (sonGüncelleme: “2013-01-01 00:00:00”, miktar: 100)

Avantajlar:

  • Cihaz, bir seferde işleyebileceği kadar veri alır. Porsiyon büyüklüğü pratik testler ile belirlenir. Basit varlıklar bir seferde 1000 senkronize edilebilir. Ancak, çok sayıda alana ve karmaşık depolama işleme mantığına sahip varlıkların normalde en fazla 5 parça senkronize edildiği de olur.

Dezavantajları:

  • Aynı güncellenmiş 250 yemek varsa, o zaman miktar = 100 ile, son 150 cihazlara gönderilmez. Bu durum oldukça gerçektir ve aşağıdaki yaklaşımda açıklanmıştır.

Yaklaşım 4: Doğru parti zamanlaması

Önceki yaklaşımda, tablo aynı "güncellenmiş" (örneğin, "2013-01-10 12:34:56") 250 tabak içeriyorsa ve porsiyon boyutu 100 ise, o zaman yalnızca ilk 100 kayıtlar gelecek. Kalan 150 sabit kırpılacaktır (güncellendi> lastUpdated). Bu neden olacak? İlk 100 kayıt istendiğinde, lastUpdated “2013-01-10 12:34:56” olarak ayarlanacak ve bir sonraki istek koşuluna sahip olacaktır (güncellendi> “2013-01-10 12:34:56”). Durumu yumuşatmak bile (güncellendi> = “2013-01-10 12:34:56”) yardımcı olmaz, çünkü cihaz daha sonra sonsuz sayıda ilk 100 kaydı isteyecektir.

Aynı "güncellenmiş" durum çok nadir değildir. Örneğin, bir metin dosyasından veri alırken, "güncellendi" alanı ŞİMDİ () olarak ayarlandı. Binlerce satırdan oluşan bir dosyayı içe aktarmak bir saniyeden az sürebilir. Tüm dizinin aynı "güncellenmiş" olması da olabilir.

Bunu düzeltmek için, en az bir an içinde benzersiz olacak ("güncellenmiş") bir çanak alanı kullanmanız gerekir. "id" alanı tüm tablo boyunca benzersizdir, bu nedenle senkronizasyonda ek olarak kullanmalısınız.

Dolayısıyla, bu yaklaşımın uygulanması şuna benzer. Sunucu, "updated" ve "id" olarak sıralanmış listeyi döndürür ve cihazlar "lastUpdated" ve yeni "lastId" parametresini kullanarak veri ister. Sunucuda, seçim koşulu daha karmaşıktır: ((updated> lastUpdated) VEYA (updated = lastUpdated ve id> lastId)).

Diyagramda: “last_updated”, “last_id” ve “tutar”, mobil uygulamada saklanan değerlerdir. "Last_item" - sunucudan gönderilen son varlık (yemek). Bir sonraki listenin isteneceği bu değerden daha yenidir.

Yaklaşım 5: Cihazda bulunanların bilgisiyle senkronize edin

Önceki yaklaşımlar, sunucunun, verilerin cihaza ne kadar başarılı bir şekilde kaydedildiğini gerçekten bilmediği gerçeğini dikkate almaz. Cihaz, açıklanamayan hatalar nedeniyle bazı verileri kaydedemedi. Bu nedenle, cihazdan bulaşıkların tamamının (veya tamamının) korunduğuna dair onay almak güzel olurdu.

Ek olarak, uygulamanın kullanıcısı uygulamayı, verilerin yalnızca bir kısmına ihtiyaç duyacak şekilde yapılandırabilir. Örneğin, bir kullanıcı 10 şehirden sadece 2'sinin yemeklerini senkronize etmek istiyor. Bu, yukarıda açıklanan senkronizasyonlar kullanılarak gerçekleştirilemez.

Yaklaşımın arkasındaki fikir aşağıdaki gibidir. Sunucu (ayrı bir tabloda “stored_item_list”), cihazda hangi bulaşıkların olduğu hakkında bilgi depolar. Sadece "id - güncellenmiş" çiftlerin bir listesi olabilir. Bu tablo, tüm cihazlar için "id - güncellenmiş" çanak çiftlerinin tüm listelerini içerir.

Cihaz, cihazda bulunan yemekler hakkında bilgi ("id - güncellenmiş" çiftlerin listesi) senkronizasyon talebi ile birlikte sunucuya gönderir. İstendiğinde, sunucu cihazda hangi yemeklerin olması gerektiğini ve hangilerinin şu anda olduğunu kontrol eder. Fark daha sonra cihaza gönderilir.

Sunucu, cihazda hangi yemeklerin olması gerektiğini nasıl belirler? En basit durumda, sunucu, tüm yemeklerin "id - güncellenmiş" çiftlerinin bir listesini döndürecek bir istekte bulunur (örneğin, id SEÇ, yemekler FROM güncellendi). Diyagramda bu, “WhatShouldBeOnDeviceMethod()” yöntemi ile yapılır. Bu yaklaşımın dezavantajıdır - sunucunun cihazda ne olması gerektiğini hesaplaması (bazen ağır sql sorguları yapması) gerekir.

Sunucu, cihazda hangi yemeklerin olduğunu nasıl belirler? Bu cihaz için "stored_item_list" tablosuna bir sorgu yapar ve "id - update" çiftlerinin bir listesini alır.

Sunucu, bu iki listeyi analiz ederek, cihaza neyin gönderileceğine ve neyin silineceğine karar verir. Diyagramda, bu "delta_item_list". Bu nedenle, istek "lastUpdated" ve "lastId" içermez, görevleri "id - update" çiftleri tarafından gerçekleştirilir.

Sunucu, cihazda bulunan yemekleri nasıl biliyor? Sunucuya yapılan istekte, son senkronizasyonda ("device_last_stored_item_list") cihaza gönderilen yemeklerin kimliğinin bir listesini içeren yeni bir "items" parametresi eklenir. Tabii ki, cihazda bulunan tüm yemeklerin kimliğinin bir listesini gönderebilir ve algoritmayı karmaşıklaştırmayabilirsiniz. Ama cihazda 3000 çanak varsa ve hepsi her seferinde gönderilirse trafik maliyetleri çok yüksek olacaktır. Senkronizasyonların büyük çoğunluğunda "öğeler" parametresi boş olacaktır.

Sunucu, “items” parametresinde cihazdan gelen verilerle “stored_item_list”i sürekli güncellemelidir.

Storage_item_list içindeki sunucu verilerini temizlemek için bir mekanizma uygulamalısınız. Örneğin, bir uygulamayı bir cihaza yeniden yükledikten sonra sunucu, cihazın hala güncel olduğunu varsayacaktır. Bu nedenle, uygulamayı yüklerken, cihazın bir şekilde sunucuyu bilgilendirmesi gerekir, böylece bu cihaz için depolanan_item_listesini temizler. Uygulamamızda bu durumda ek bir “clearCache” = 1 parametresi gönderiyoruz.

Çözüm

Bu yaklaşımların özelliklerinin özet tablosu:

Bir yaklaşım Trafik yoğunluğu(5 - büyük) Gelişimin emek yoğunluğu(5 - yüksek) Cihaz hafızası kullanımı(5 - yüksek) Cihazdaki verilerin doğruluğu(5 - yüksek) Belirli bir cihazı seçebilirsiniz
1 Her şey her zaman senkronize 5 1 5 5 Numara
2 Yalnızca güncellenen 1 2 5 3 Numara
3 Gruplar halinde senkronizasyon 1 3 1 3 Numara
4 Gruplarda doğru senkronizasyon 1 3 1 3 Numara
5 Cihazda zaten ne olduğu bilgisi ile senkronizasyon 2 5 2 5 Evet

"Cihazdaki verilerin doğruluğu", cihazın sunucu tarafından gönderilen tüm verileri içerme olasılığıdır. # 1 ve # 5 yaklaşımlarında, cihazın ihtiyaç duyduğu tüm verilere sahip olduğuna dair %100 kesinlik vardır. Diğer durumlarda, böyle bir garanti yoktur. Bu, diğer yaklaşımların kullanılamayacağı anlamına gelmez. Sadece, cihazdaki verilerin bir kısmı kaybolursa, onu sunucudan düzeltmek mümkün olmayacaktır (ve hatta daha fazlasını sunucu tarafında öğrenmek).

Belki de sınırsız İnternet tarifeleri ve ücretsiz wifi varlığında, bir mobil uygulama tarafından oluşturulan trafiği sınırlama sorunu daha az alakalı hale gelecektir. Ancak her türlü hileye başvurmanız gerekirken, ağ maliyetlerini azaltabilecek ve uygulama performansını artırabilecek daha akıllı yaklaşımlar bulun. Her zaman işe yaramaz. Bazen duruma bağlı olarak “daha ​​basit, daha iyi” olur. Umarım bu makaleden işinize yarayacak bir yaklaşım seçebilirsiniz.

İnternette sunucu senkronizasyonu ile ilgili şaşırtıcı derecede az açıklama vardır ve mobil cihazlar... Üstelik bu şemaya göre çalışan birçok uygulama var. İlgilenenler için birkaç link.

Geçmişte çevrimdışıyken, bugün Çevrimiçi olmak bir zorunluluktur. En azından modern iş dünyası için. Marka ürün ve hizmetlerinin sunumları, çevrimiçi sipariş ve teslimat, müşteri tabanını koruma, müşterilerle iletişim ve çok daha fazlası - tüm bunlar İnternet varlığı olmadan imkansızdır. Bir uygulamaya ihtiyacınız varsa, hem Ön Uç (web arayüzü) hem de Arka Uç (uygulamanızın arka ucu) olmalıdır. Ve uygulamanızın içeriğini geliştiricilerin katılımı olmadan düzenleyebilmek istiyorsanız, iyi bir yönetici paneline ihtiyacınız var.

Mobil uygulama alanındaki Front-end, X-Code ve Java gibi teknolojiler kullanılarak oluşturulurken, veritabanının ve tüm uygulama mantığının saklanacağı Back-end, sunucu tarafı programlama dili hakkında profesyonel bilgi gerektirir. İyi bir örnek, neredeyse tüm sunucu tarafı geliştirmeleri için kullanılan tartışmasız en popüler programlama dili olan PHP'dir. Bu tartışmasız lider.

PHP'nin birçok kullanım alanı vardır: statik ve dinamik web siteleri + özel içerik yönetim sistemleri, sosyal medya, özel CRM sistemleri, e-ticaret yazılımı ve daha fazlası. Elbette ücretsiz veya ucuz sunucu parçaları ve kontrol panelleri var. Ancak çoğu durumda gerekli kolaylık, özelleştirme ve yükseltilebilirlik düzeyini sağlamazlar.

Programcılarımız, farklı iş hedefleri, ihtiyaçlar ve gereksinimler için çok çeşitli çözümler uygulamak için teknolojilerle çalışır. Her proje için sistem gereksinimlerini ayrı ayrı analiz ediyoruz ve mobil uygulamanızın optimum performansı için çeşitli özel sunucu yazılımları kullanıyoruz.

Sıfırdan bir uygulama oluşturmak veya mükemmel bir kullanıcı deneyimi için mevcut bir uygulamayı yeniden oluşturmak için sizi en akıllı ve en uygun maliyetli çözüme götürebilecek bir ekip arıyorsanız, başka yere bakmayın. Appsmob, sizin için en iyi çözümü bulmanıza yardımcı olmaya hazır.

Mobil istemcilerin dezavantajı sunucudur.

Ek gereksinimler, uygulamanın özelliklerine bağlıdır:
sunucu ölçeklenebilirliği - ideal olarak büyük bir ziyaretçi akışının beklendiği SaaS, sosyal uygulamalar için bu koşul zorunludur. Kullanıcı sayısında kısıtlamaların olduğu veya sayının tahmin edildiği iş uygulamaları için bu özellik gerekli değildir;
etkileşim: bir dizi uygulamaya bir bildirim mekanizması sağlanmalıdır - uygulamayı (kullanıcıyı) belirli olayların oluşumu hakkında bilgilendirmek, kullanıcıya bir mesaj göndermek. Bu mülk, örneğin, bir değişim sistemi veya otomatik bir taksi memuru tarafından sahip olunmalıdır.
açık API: üçüncü taraf geliştiricilerin, sistemin işlevselliğini belgelenmiş bir protokol aracılığıyla kullanabileceği varsayılır. Sonuçta, bir istemci mobil veya harici bir sunucu uygulaması olabilir.
diğer gereklilikler ...

Emretmek
Sistemin geliştirilmesi için proje ekibinin bileşimi ideal olarak aşağıdaki gibi olabilir:
proje yöneticisi: projeyi yönetir, kontrol eder, doğrudan müşteri ile etkileşime girer;
sunucu uygulaması geliştiricisi: bir iş mantığı sunucusu, veritabanı, ağ protokolü geliştirir;
yönetici uygulama geliştiricisi: bir sunucu uygulamasını yapılandırmak ve yönetmek için bir kullanıcı arabirimi olan bir Web uygulaması geliştirir;
Android için istemci uygulama geliştiricisi;
iOS istemci uygulama geliştiricisi;
için istemci uygulama geliştiricisi ...
test cihazı: yönetici uygulamasını ve istemci uygulamalarını test eder.

Dikkatli okuyucu, örneğin HTML5'te grafik arayüzlü bir sunucu taraflı uygulama yazarsanız, paradan tasarruf edebileceğinizi fark edecektir. Bu durumda, istemci uygulamalarının geliştirilmesi gerekli değildir - kullanıcı arayüzü tarayıcı tarafından sağlanır. Bu makale böyle bir durumu ele almıyor, mobil cihazlar için "yerel" (yerel) uygulamaların geliştirilmesi ile ilgili.

Tam kadrolu bir ekipte çalıştım, ancak gerçekçi olacağım - her zaman insan kaynakları ve bütçe böyle bir ekip kurmanıza izin vermez. Ve bazen rollerin birleştirilmesi gerekir: proje yöneticisi + sunucu uygulaması geliştiricisi, istemci uygulaması geliştiricisi + testçi.

Teknolojiler, araçlar, kütüphaneler
Mobil istemciler için bir sunucu geliştirmek için genellikle aşağıdaki "ücretsiz" teknoloji yığınını kullanırım:
Apache Tomcat - Servlet kapsayıcısı;
MySQL - DBMS;
Subversion, bir sürüm kontrol sistemidir;
Maven, proje derlemelerini otomatikleştirmek için bir çerçevedir;
JUnit - sağlayacaktır;
Apache Log4j - günlük kitaplığı;
Jenkins - sürekli entegrasyon sistemi;
Hazırda Beklet - ORM (ayarlar, özelliklerde yapılandırma, xml dosyaları ve açıklamalar);
hibernate-generic-dao - Google'dan DAO uygulaması, veritabanı verileriyle çalışmak için temel yöntemleri uygular, yöntemlerde filtreleme ve sıralama uygulamasını basitleştirir;
- kimlik doğrulama ve yetkilendirme (güvenlik), hizmetler ve fasulye konteyneri (xml dosyalarında ve ek açıklamalarda yapılandırma), testler oluştururken de kullanırız.

Sistemin özelliklerine ve gereksinimlerine bağlı olarak, veri alışverişi protokolünü uygulamak için 2 seçenekten birini kullanıyorum.
Platformlar arası, hız, basitlik, verimlilik, ölçeklenebilirlik, açık API gerektiğinde, RESTful Web hizmetlerinin bir uygulaması olan Jersey'i alıyorum. Bu kitaplık, JSON ve/veya XML veri serileştirme kullanmanıza olanak tanır. REST yapılandırması ek açıklamalar aracılığıyla yapılır. Mobil cihazlarla değiş tokuş için, istemci tarafında daha basit bir uygulamaya sahip olması nedeniyle (bu nedenle “klasik” Web servislerini kullanmıyoruz) JSON formatı alınmıştır, daha az trafik oluşturulmuştur. Jersey, en uygun JSON "görünümüne" uyum sağlamanıza izin verir.
Aksi takdirde, platformlar arası, yüksek performans, basitlik, verimlilik, etkileşime ihtiyacınız varsa, o zaman alırım
Apache MINA, ağ uygulamaları oluşturmak için bir çerçevedir.
Google protobuf, yapılandırılmış bir veri kodlama ve kod çözme kitaplığıdır. Veri yapısı * .proto başlık dosyaları tarafından belirlenir, derleyici bunlardan Java sınıfları oluşturur (diğer programlama dilleri için de oluşturma olasılığı vardır: C ++, Objective-C, vb., çapraz platform sağlar. Emlak);
java.util.concurrent - standart paketi kullanıyoruz.
Bu seçenek ölçeklendirilebilir, ancak bu, iş mantığı dikkate alınarak mimari düzeyde tasarım aşamasında ortaya konmalıdır.

Gerçek bir SaaS hizmeti için teknoloji seçimi örneğini kullanarak varsayımsal bir sorunu ele alalım - insanların gerekli hizmetlerin veya işlerin performansı için sipariş vermelerini sağlayan “Hizmet açık artırması“ Auknem ”ve kuruluşlar, sırayla, önerilerini onlara bırakın. Tüm temel gereksinimleri varsayılan olarak alıyoruz. Bu sisteme kayıt olmanın ücretsiz ve ücretsiz olması nedeniyle bunlara kesinlikle ölçeklenebilirlik eklemek gerekir. Peki ya etkileşim? Müteahhitleri (icracıları) yeni siparişlerin oluşturulması hakkında bilgilendirmek ve müşterilere aynı anda gelen teklifler hakkında sadece e-posta ile değil, başvuruda bilgilendirmek harika olurdu. Buna dayanarak, Google protobuf olan Apache MINA'nın uygulanmasını alıyoruz. Bir sonraki özelliğe bakıyoruz - API'yi açın. Hizmet herkese açıktır, bu nedenle harici geliştiricilerin hizmetle entegre olmakla ilgilenebileceğini varsayalım. Bir dakika bekle! O kadar basit değil. Apache MINA'ya dayalı protokol, uygulamaya ve entegrasyona oldukça bağlıdır, nüansları bilmeden entegrasyon hiçbir şekilde şeffaf değildir. Böyle bir durumda, hangi faktörün daha önemli olduğunu tartmanız ve bir seçim yapmanız gerekecektir.

Çözüm
Mobil cihazlar veya benzeri sistemler için bir sunucu geliştirirken hangi teknolojileri, kütüphaneleri kullandığınızı bilmek isterim. Her şey değişir, hiçbir şey sonsuza kadar sürmez, her seviyede kendi avantajları ve dezavantajları olan alternatifler vardır: MySQL -

DESTEK OLMAK

Neden bir mobil platformda yedeklemeye ihtiyacınız var?

Uzmanlar, 1C'deki mobil uygulamaların bazen ne kadar güvenilmez olduğunu biliyorlar: kullanıcı tabanının basitçe çökeceği için herhangi bir zamanda hatalar meydana gelebilir. Aynı zamanda, cihazların kendilerinin güvenilmezliği ile karşı karşıyayız: kırılabilirler, kaybolabilirler, çalınabilirler ve kullanıcılar verilerini saklamak isterler. Ve 8.3.9 sürümüne kadar, bir yedeği kaydetmek için bir platform mekanizmamız yoktu.

Kullanıcılar daha önce "kopyasını kaydet" düğmesine sahip olmadığı için Boss uygulamasının geliştiricileri kendi yedeklemelerini yapmak zorunda kaldı. Nasıl yaptık?

Veritabanı verilerini XML biçiminde kaydediyoruz.

Kullanıcıya kopyaları depolamak için çeşitli seçenekler sunmanız önerilir - her şeyden önce, müşteriler için uygundur, kendileri için en iyi seçeneği seçebilirler: buluta yükleyin, postalarına gönderin, cihaza kaydedin.

Böylece, geliştiriciler ayrıca kendilerini sigortalarlar. Bir şeyler ters giderse ve Google Drive veya Yandex Drive'da kopya oluşturma mekanizması aniden bozulursa, kullanıcıya her zaman geliştiricinin şu anda bir hatayla uğraştığını söyleyebilirsiniz, ancak şimdilik verileri bir alternatifte kaydedebilir. yol. Ve kullanıcılar, verilerinden emin oldukları için memnunlar.

mutlaka bulut hizmetlerine odaklanmak gerekiyor, çünkü cihaz kaybolur veya bozulursa ve kullanıcı aynı cihaza bir kopyasını kaydederse, veriler kaybolur.

Ayrıca biz kullanıcıya yedek oluşturma ihtiyacını hatırlattığınızdan emin olun.

Yapılandırma değişirse kopyalar nasıl saklanır?

Kitlesel bir çözümden, sürekli değişen, gelişen ve rafine bir uygulamadan bahsettiğimizde, müşteri davranışını dikkate almak gerekir. Kullanıcı, uygulamanın eski bir sürümünde kaydedilmiş ve hiçbir ayrıntıya sahip olmayan bir yedeği geri yüklemek isteyebilir. Ve sonra görev ortaya çıkar: verileri okumak, ardından verileri uygulamanın eski sürümünden güncelleme mantığına göre doldurmak. Nasıl yapılır? Verilere ek olarak, daha sonra nasıl okunacağını öğrenmek için veri yapısının kendisini kaydedin.

Bu veri yapısını depolamak için, konfigürasyonun kendisinde saklanabilmesi de dahil olmak üzere, birkaç seçenek vardır. Yani, her yeni sürüm yayınlandığında, önceki sürümün meta veri yapısını konfigürasyondaki bir düzende tutun.

Unutmayın ki bir mobil uygulamada konfigürasyon böyle büyümemeli, içindeki yere değer vermeli, olabildiğince kompakt hale getirmeliyiz. Ancak uygulama gelişiyor ve bu tür birçok düzen olacak ve zamanla giderek daha fazla olacaklar.

Bu nedenle, bir mobil uygulama söz konusu olduğunda, başka bir yol tercih edilir - meta veri yapısını doğrudan veri dosyasına kaydedin... Çıktıda, ilk önce bazı yardımcı verileri sakladığımız böyle bir dosya alıyoruz - konfigürasyon versiyonu, konfigürasyon şeması, sıra sınırları ve bundan sonra kullanıcı verilerini XML formatında yazıyoruz. Ayrıca, dosyanın "Yardımcı veriler" bölümünde, bazı nedenlerden dolayı XML'e yazılamayan diğer önemli verileri de saklayabilirsiniz.

Dosyaya kaydettiğimiz veri şemasını alıyoruz ve temelinde dosyayı okumak için XDTO paketini oluşturuyoruz. Veritabanında benzer bir nesne oluşturuyoruz, dolduruyoruz, güncelleme yaparken yeniden doldurma işlemi yapıyoruz ve zaten bitmiş nesneyi veritabanına kaydediyoruz.

Aşağıdaki resimde, bu konfigürasyonların XDTO modelini güzel bir şekilde nasıl yazacağınıza dair bir ipucu görebilirsiniz. Boss uygulamasını yayınlayan şirket bunu denedi, birkaç yol buldu, ancak meta veri şemasını kaydetmek için bu seçeneğe karar verdi. Veri dosyasını açtığınızda, tüm uygulama meta verilerini listeleyen, okunabilir, olağan yapılandırılmış XML'i görebilirsiniz.

// Yapılandırma şemasını yazın ModelXDTO = FactoryXDTO.ExportModelsXDTO ("http://v8.1c.ru/8.1/data/enterprise/current-config"); XDTO Factory.WriteXML (UploadFile, XDTO Modeli); // Konfigürasyon şemasını okuma Model XDTO = Fabrika XDTO. XML oku (XML'yi oku, Fabrika XDTO. Tür ("http://v8.1c.ru/8.1/xdto", "Model")); UnloadFactory = Yeni XDTOFactory (XDTOModel);

Kullanıcıyı korumak için, yedeği geri yüklemesi gerekip gerekmediğini ona tekrar sormak zorunludur. Belki de sadece deneme yapıyordu ve uygulamadaki tüm düğmelere tıklıyordu :) Ve şimdi mevcut veriler kaybolabilir. Bu nedenle, potansiyel olarak "tehlikeli" eylemler gerçekleştirirken, bunu gerçekten isteyip istemediğini ve nasıl yapılması gerektiğini her zaman belirtiriz. Kullanıcı eylemlerinin farkında olmalıdır.

Kullanıcının tüm verileri yalnızca bir mobil cihazda depoladığı zaman, otonom bir çözümden bahsettiğimizde yedekleme oluşturmak için bir mekanizma olmalıdır: kullanıcı cihazını kaybedebilir ve ardından veriler kaybolacaktır. Ve öyle görünüyor ki, uygulama özerk çalışmıyorsa, ancak merkezi bir sunucuya bağlıysa, kullanıcının böyle bir sorunu olmamalıdır, çünkü cihaz kaybolursa sunucuya bağlanır, tüm verilerini alır. sunucudan tekrar ve her şey yoluna girecek.

Ancak, kullanıcılar yedeklemeleri her zaman beklediğimiz şekilde kullanmazlar :) Çok sık bunları verileri basitçe "geri almak" için kullanırlar. Bu gerçekten çok garip bir davranış, ancak mobil uygulama kullanıcıları veri girerken nerede hata yapabileceklerini anlayamayacak kadar tembeller ve sadece verileri geri alıp o güne ait verileri yeniden giriyorlar. Boss uygulamasıyla çalışmanın istatistiklerini analiz ettikten sonra, bunun normal bir uygulama olduğunu ve bu kullanıcı davranışının beklediğimizden daha yaygın olduğunu fark ettik.

Ve diğer cihazlarla senkronizasyon kullanıyorsanız, bunu halletmeniz gerekir. Burada birkaç çözüm var:

  • sunucuyla bağlantıyı kes, üzerindeki verilerin olduğu gibi kalacağını ve kopyanın yalnızca kullanıcının cihazına geri yükleneceğini belirterek;
  • kullanıcının, daha önce bu tür mekanizmaları öngörmüş olarak, tüm cihazlarda bir kerede bir kopyayı geri yüklemesine izin vermesi daha iyidir.

Burada bir şey daha var. Şimdiye kadar yedekleri kendimiz kaydettik, tüm süreci kontrol ettik, kullanıcının "kopyasını kaydet" düğmesine bastığında yaptığı işlemleri doğrudan kodda yakaladık. Bütün bunlar daha sonra işlenebilir. 8.3.9 platformunda, platform sayesinde yedekleri aynen kaydetmek mümkün hale geldi. Ve kullanıcı bunu bizim bilgimiz dışında yapıyor. Merkezi bir veritabanı ile senkronizasyon kullanılıyorsa, böyle bir senaryo ele alınmalıdır. Kullanıcının önceden kaydedilmiş bir kopyayı geri yüklediğini sunucumuzda bir şekilde bulmalı ve ona bir tür çözüm sunmalıyız. Verilerin senkronize olmamasını göze alamayız.

DEĞİŞ TOKUŞ

Bir mobil platformda özel bir çözümden bahsettiğimizde, genellikle, örneğin satış acenteleri için bir mobil platform kullanmak ve böylece merkezi bir veritabanı ile veri alışverişi yapmak isteyen bir müşterimiz olur. Burada her şey basit: bir veritabanı, birkaç cihaz, sunucuyu yükseltirsiniz, onunla iletişim kurarsınız. Bu nedenle, cihazlar arasındaki değişim sorununu çözmek kolaydır.

Ancak, her biri çok sayıda kullanıcıya sahip çok sayıda veri tabanının bulunduğu toplu bir uygulamadan bahsediyorsak, durum daha karmaşık hale gelir. Kullanıcılar uygulamayı marketten indirdiler ve birbirleriyle senkronize etmek istiyorlar. Örneğin, bir koca kişisel finans muhasebesi için bir uygulama indirdi ve şimdi karısının da bağlanmasını istiyor ve aynı uygulamada birlikte çalışıyorlar. Çok sayıda kullanıcı var, uygulama gelişiyor, büyüyor ve çok, çok sayıda veritabanına ihtiyaç var. Bütün bunlar nasıl organize edilir? Kullanıcılar, kendileri için ayrı bir veritabanı oluşturmak ve senkronizasyonu etkinleştirmek için geliştiricilerle kişisel olarak iletişime geçmeyecektir. Bir düğmeye basmak ve hemen çalışmasını sağlamak istiyorlar. Aynı anda.

Nasıl devam edilir? Veri paylaşım mekanizmasının kurtarmaya geldiği yer burasıdır. Tek bir ortak yapılandırmanın olduğu, ancak aynı zamanda sınırsız sayıda kullanıcı tabanının tek bir ortak veritabanında depolandığı tek bir veritabanını düzenlemenize olanak tanır.

En iyi yanı, bizim katılımımız olmadan kullanıcıları dinamik, programlı olarak ekleyebilmenizdir. Gerçekte, kullanıcılar sadece "sunucuya kaydol" düğmesine tıklarlar ve her şey kendiliğinden olur: sunucuda onun için kişisel bir veritabanı oluşturulur ve hemen üzerinde çalışmaya başlayabilir.

Nasıl yapılır? İlk ve en basit çözüm, bu mekanizma ile kendi sunucu tabanınızı yazmaktır. Şirketimiz Boss uygulamasını yapmaya ve içinde değiş tokuş yapmaya başladığında, ilk sürümde tam olarak bunu yaptık: veri paylaşım mekanizmalı bir sunucu veritabanı yazdık. Her şey çalıştı, özellikle karmaşık bir şey olmadığı için - temel ayırıcı ortak bir sahne.

Ama sonra tekerleği yeniden icat ettiğimizi fark ettik :) Aslında hazır bir çözüm var ve daha önce hiç düşünmediğimiz noktaları da hesaba katmış durumda. Bu 1C: Taze.

Hizmetin ölçeklenebilirliği burada düşünülür: çok fazla veri ve veri tabanı olduğunda ne yapmalı, tüm bunlarla nasıl büyümeli. Veri alanlarının yedek kopyalarını oluşturmanın bir anlamı vardır: yani, sadece ortak bir veritabanını yedeklemeyiz, belirli bir kullanıcının kopyalarını yaparız. Dahası, kopyaların yalnızca gerçekten ihtiyaç duyulduğunda yapılması gibi bir mekanizma var. Bir kullanıcı bir hafta boyunca veritabanına girmediyse, orada hiçbir şey değişmediği için onun kopyasını almayız. Bir diğer Fresh özelliği, hizmetin, çok sayıda veritabanınız olduğunda çok önemli olan sunucu üzerindeki yükü azaltmak için bir mekanizma uygulamasıdır.

Genel olarak, Fresh bizim için yeni ve ilginç bir şey. Yavaş yavaş anlamaya çalışıyoruz, ancak çoğunlukla çalışmasından memnunuz.

Veri transferi. Cihazlar arasında değişim için nasıl uygulanır

Platform iki mekanizma sağlar - SOAP ve http hizmetleri. Veri paylaşım mekanizması söz konusu olduğunda bu hizmetlere nasıl erişileceğine dair nüanslar vardır. Özellikle, platform kullanıcı adıyla hangi veritabanına erişileceğini belirleyemediğinden, eriştiğiniz alanın belirli numarasını belirten parametreler eklemeniz gerekir. Ek olarak, bir ve aynı kullanıcı, tek bir veritabanı içinde birkaç veritabanıyla çalışabilir (resme bakın).

Hizmetlere gelince, Boss uygulaması anında değişim uygular: bir kullanıcı veri girer ve diğeri onu alır. Mobil uygulamaların kullanıcıları, her şeyin anında gerçekleştiği gerçeğine alışkındır, bu yüzden hangi hizmetin daha iyi kullanılacağını düşündük - SABUN veya http. Bağlantı hızı önemli bir rol oynadı. Http'de bağlantı hızı çok daha yüksektir ve SOAP üzerinden bağlanırken, ağır ve yüklenmesi uzun süren hizmetin bir açıklamasını alırız. Platformun bir servis tanımını saklama yolu var ancak dinamik olarak eklediğimiz parametreler nedeniyle WS referanslarını kullanamıyoruz. Ek olarak, http servislerine erişim deneyimimizde daha rahat ve esnektir.

Dolayısıyla amacımız, değişimi gerçek zamanlı olarak uygulamaktır. Yani, kullanıcının bir yere gitmesine, bir butona tıklamasına, verilerinin ne kadar alakalı olduğunu, güncellemesi gerekip gerekmediğini düşünmemeye çalışıyoruz... Veriler her zaman kullanıcılar için alakalı olmalıdır. Anlık mesajlaşma programlarında çalışmaya çok alışkınlar - biri verileri gönderdi, diğeri hemen aldı. Her şey anında olur. Aynısı işle ilgili uygulamalar için de geçerlidir: bir satıcı satış yaptı, diğeri ise herhangi bir işlem yapmadan mevcut durumu hemen görmelidir.

Bu nedenle, Boss uygulaması, değiş tokuşlar için arka plan işlerini kullanır. Her veri veritabanına yazıldıktan sonra, değişimi başlatan bir arka plan işi başlatılır. İlk kısım, sunucuya veri göndermektir. O zaman diğer cihazların yeni veriler olduğunu bilmesi gerekir. Bunun için PUSH bildirimlerini kullanıyoruz. Bu şema zaten çalışıyor ve yeterince hızlı çalışıyor.

Ancak daha da hızlı olmasını istedik çünkü gerçek zamanlı çalışıyoruz ve genellikle çok az veriye sahibiz. Küçük XML'imiz var ama aynı zamanda ilk cihazdan sunucuya bu verilerle bir mesaj gönderiyoruz, sunucu başka bir cihaza PUSH gönderiyor ve ardından ikinci cihaz PUSH aldıktan sonra kendi tarafında bir değişim başlatıyor, sunucuya hitap eder ve verileri ister, bu verileri alır ve ardından verilerin alındığına dair bir yanıt gönderir. Bu uzun bir süre, ancak verilerin kendisi çok küçüktü.

Bu sürecin nasıl hızlandırılabileceğini düşündük.

Bunu yapmak için PUSH'un ne içerdiğini, hala nasıl kullanılabileceğini anladık. PUSH'un veri ve metin gibi alanları içerdiği ortaya çıktı. iOS ve Android belgeleri, PUSH mesajlarının boyutuyla ilgili kısıtlamalar içeriyor, ancak bu bize yeterli gelmedi ve bunu deneysel olarak çözmek istedik. Geçerli karakterlerin toplamının iOS için 981 karakter ve Android için 3832 karakter olduğunu kontrol ettik. İkinci durumda, kısıtlamayı kullanmak oldukça mümkündür, bir veya birkaç temel nesne böyle bir hacme sığdırılabilir. Ve sonra şirketin geliştiricileri şemayı biraz değiştirdi. Çok fazla veri olmadığında bir cihazdan gönderiyoruz, sunucuda alıyoruz, oraya PUSH olarak paketliyoruz ve doğrudan içindeki başka bir cihaza gönderiyoruz. Plan kısaldı ve değişim daha da hızlı gerçekleşmeye başladı :)

PUSH kullanmanın önemli bir noktası da kullanıcıları rahatsız etmemek.

Bu durumdan kurtulmak çok kolay: Sadece kullanıcıya çok fazla PUSH mesajı göndermeyin :) Şu anda uygulamada çalışıyorsa bol bol mesaj gönderebilirsiniz. Platform çalışırken kullanıcı PUSH görmez, onun için her şey otomatik olarak gerçekleşir. Ancak uygulama kapatıldığında, istemcinin çok sayıda okunmamış mesajı vardır. Bu nedenle, cihazdan uygulamanın çalıştığı, aktif olduğu ve önceki PUSH'un zaten işlendiğine dair bir yanıt alınana kadar hiçbir durumda bir sonraki PUSH gönderilmemelidir.

Değişimin bir başka nüansı da web üzerinden çalışmaktır. Eşzamansızlıktan en iyi şekilde yararlanmalıyız. Her zamanki gibi çalışamazsınız - kodu yazın - işlevi çağırın - çalışmasını bekleyin - cevabı alın - ve her şey yolunda. Web üzerinden çalışıyorsanız, örneğin kararsız İnternet, uzun işlemler gerçekleştirirken tetiklenen zaman aşımları gibi belirli kısıtlamalarla karşılaşacaksınız. Bu nedenle, mimariyi önceden düşünmek gerekir.

Bir cihazı kaydetme örneğine bakalım, bir kullanıcı kayıt olmak istediğinde bir uygulamada neler oluyor. Bir süre kayıt tutuyor, bir sürü veri girdi ama sonra satıcının da bu veri tabanı ile çalışmasını istiyor. Kullanıcı "kayıt ol" düğmesine tıklar. İlk başta her şey çok basitti: verilerini aldılar, sunucuya kaydettiler ve lütfen çalışıp kullanıcıları bağlayabilirsiniz. Ancak daha sonra, bazı kullanıcılar için cihazdaki veritabanlarının kayıt sırasında zaten büyük ölçüde büyüdüğü bir durumla karşılaştık. Ve bu plan artık işe yaramadı, çünkü tüm veritabanı sunucuya kaydedilirken, bağlantı zaman aşımı tetiklendi veya İnternet basitçe kesildi. Bu nedenle, bir eşzamanlı çağrıyı birçok kısa çağrıyla değiştirdik. Artık veriler tek seferde iletilmek yerine paylaşılıyor. Sunucunun verileri işlemesini ve kaydetmesini hiçbir şekilde beklemiyoruz. Veri gönderdik, verilerin alındığına dair bir yanıt aldık, bağlantıyı kapattık. Periyodik olarak sunucuyu yoklamanız gerekir, orada neler oluyor ve nasıl oluyor ve bu arada sunucuda alınan verileri kaydeden bir arka plan işi çalışıyor. Bu şekilde çok sayıda sunucu çağrısı alıyoruz, ancak her şeyin yolunda gideceğine dair bir garantimiz var. Ve ne zaman aşımları ne de İnternet'in kararsızlığı tüm verileri sunucuya yüklemenizi engellemez.

GÜNCELLEMELER

Uygulamanın farklı sürümlerine sahip cihazlar arasında değişim

Piyasalara çıkan toplu bir uygulamadan bahsettiğimiz için güncelleme ve veri alışverişi sürecinin bazı özelliklerini dikkate almamız gerekiyor.

Bir işletme için bir uygulama yayınladıysanız ve güncellemeye karar verdiyseniz, genellikle tüm çalışanların yeni uygulamayı birlikte kurması için bir komut verirsiniz. Bu, uygulamayı marketten indiren kullanıcılarla yapılamaz. Onlara ne yapacaklarını hiç söyleyemezsin. Örneğin, bir uygulamada çalışıyorlar ve ne şimdi ne de hiç güncellemek istemiyorlar. Otomatik güncellemeleri yoktur, bu nedenle merkezi tabana birkaç cihazın bağlı olması ve hepsinin farklı versiyonlara sahip olması oldukça yaygın bir durumdur. Bu olgunun bir başka nedeni de piyasalarda yayınlanma süresidir: iOS ve Android için farklıdır. Genellikle önemli şeyleri uygularız, örneğin kritik hataları düzeltiriz ve iOS'un yeni sürümü iki hafta boyunca kontrol etmesini beklemek istemiyoruz, en azından yalnızca Android için istiyoruz, ancak güncellemeyi hemen şimdi yayınlıyoruz.

Kullanıcılara komut verme hakkımız yok. İsterlerse güncellenirler, istemezlerse hiçbir şey yapmazlar. Resim, GooglePlay'deki sürümlere göre Boss uygulama yüklemelerinin oranını ve sunucumuzdaki istatistikleri gösterir - geçen hafta sunucuyla veri alışverişinde bulunan cihazlara yüklenen uygulama sürümlerinin gerçek oranı. İşte çalışmak için bir set. Bunlar farklı sürümler ve farklı meta verilerdir. Ve aynı anda normal bir değişim düzenlememiz gerekiyor :)

Geliştiriciler aşağıdaki görevlerle karşı karşıyadır:

  • Bütün bunların çalışması gerekiyor. Kullanıcılar, yükseltmeyi unuttukları için rahatsızlık hissetmemelidir. Bunu hiç fark etmemeliler. Güncellendi - daha iyi, iyi ve iyi.
  • Verilerin güvenliğini sağlamalıyız. Örneğin, bir kullanıcının bir dizini ve yeni bir sahne donanımı varken, diğerinin henüz yok. Ayrıca yeni bir detayı olmayan bir kullanıcı, cihazında bir şeyi değiştirirse, diğer cihazlardaki veriler kaybolmamalıdır.
  • Yeni bir sürüme yükselttiğimizde verilerin güncellendiğinden emin olmamız gerekiyor. Kullanıcı güncellemeye hazır olduğuna karar verdiğinde, eski bir sürüme sahip olduğu için sahip olmadığı tüm yeni bilgilere otomatik olarak sahip olmalıdır.

Nasıl yaptık?

1. Sunucuda 2 değişim planı kullanıyoruz. Birincisi cihazlar arası paylaşım, ikincisi ise güncellemeler içindir. Örneğin, bir kullanıcıya bir kılavuz gönderdik, ancak onun ölçü birimleri yok, yani eksik veriler. Bunu hatırlamalıyız. Ve güncellendiğinde, sahip olmadığı tüm bilgileri ona göndermeliyiz. İkinci değişim planı bunun için.

2. Nesneleri yazmak ve okumak için, yedeklemeler için kullanılan aynı mekanizmayı kullanırız, yani meta verilerin sürümünü kaydederiz. Bu durumda, sunucu ile çalışıyoruz ve istediğimiz her şeyi doğrudan konfigürasyona eklemeyi karşılayabiliyoruz, bu yüzden uygulama geliştikçe konfigürasyona yerleşimler şeklinde meta veri şemaları ekliyoruz.

Değişim sırasında ve sunucuda büyük hatalar nasıl izlenir?

İlk olarak, sunucunun kendisinin kullanılabilirliğini kontrol etmeniz gerekir. Bu sunuculara olur - düşerler. İzleme için özel bir şey icat etmedik, ancak telgrafta bir şeyler ters gittiğinde çığlık atan bir bot bulduk. Her dakika sunucunun performansını kontrol eder ve sunucu aniden kullanılamaz hale gelirse çığlık atmaya başlar, adminler görür ve sunucuyu açar.

Ayrıca günlükten hata günlüğünü de topluyoruz. Ayrıca doğaüstü hiçbir şey yok - her üç saatte bir hata günlüğü topluyoruz, postaya gönderiyoruz ve periyodik olarak gözden geçiriyoruz. Bu, yaygın sorunları ve bazı istisnai durumları görmenize yardımcı olur. Postanızı okumak, izini sürmek ve hataları hızla düzeltmek zor değil. Ancak bu, veritabanlarının büyümesiyle büyüyebilecek sorunları hızlı bir şekilde belirlemenize ve çözmenize olanak tanır.

Bir diğer önemli nokta - kullanıcıya "şikayet" etme fırsatı verdiğinizden emin olun. Onların gözündeki durumumuzu iyileştirir ve bizi kurtarır. En ufak bir hatada bize postamızda hiçbir şeyin işe yaramadığı, veritabanının yüklenmediği, her şeyin çok kötü olduğu bir sürü mesaj göndermeye başlayan "histerik" dediğimiz kullanıcılar var. Ama bazen bizi gerçekten kurtarıyorlar, çünkü bazen başkalarının mucizevi bir şekilde bulamadığı böcekleri buluyorlar, ciddi hatalar.

Kullanıcı korkamaz. Korkunç mesajlar değil, başka bir şey değil. Her şeyi güzelce açıklamaları ve şikayet etmeyi teklif etmeleri gerekiyor. Ve her şeyi çözeceğimize söz veriyoruz. O zaman kullanıcılar mutlu oluyorlar, çünkü kendilerine bakıldığını görüyorlar ve hemen kendilerine yardım edileceğine inanıyorlar :)

Bu makale INFOSTART EVENT 2016 GELİŞTİRİCİ konferansında okunan raporun sonuçlarına dayanılarak yazılmıştır. Daha fazla makale okunabilir.

2020'de herkesi 7 bölgesel buluşmaya ve ayrıca Moskova'daki INFOSTART EVENT 2020 yıldönümüne katılmaya davet ediyoruz.