Layanan referensi aplikasi seluler

Ruslan Aromatov, kepala pengembang, ICD



Selamat siang, Khabrovites! Saya bekerja sebagai pengembang backend di Moscow Credit Bank, dan kali ini saya ingin berbicara tentang bagaimana kami mengatur pengiriman konten runtime ke aplikasi seluler MKB Online kami. Artikel ini dapat bermanfaat bagi mereka yang terlibat dalam desain dan pengembangan server depan untuk aplikasi mobile, yang penting untuk secara konstan memberikan berbagai pembaruan, baik dokumen bank, titik geolokasi, ikon yang diperbarui, dll. Tanpa memperbarui aplikasi itu sendiri di toko. Mereka yang mengembangkan aplikasi mobile, tidak ada salahnya juga. Artikel tidak berisi contoh kode, hanya beberapa diskusi tentang topik tersebut.

Latar Belakang


Saya pikir setiap pengembang aplikasi seluler mengalami masalah dalam memperbarui sebagian konten aplikasi mereka. Misalnya, ubah klausa perjanjian pengguna, ikon atau koordinat toko pelanggan yang tiba-tiba pindah. Tampaknya itu bisa lebih mudah? Kami membangun kembali aplikasi dan meletakkannya di toko. Pelanggan diperbarui, semua orang senang.

Tetapi skema sederhana ini tidak berfungsi karena satu alasan sederhana - tidak semua klien diperbarui. Dan dilihat dari statistik, ada banyak klien seperti itu.

Dalam kasus aplikasi perbankan, kegagalan untuk menyampaikan informasi yang relevan dapat menimbulkan biaya dan ketidakpuasan pelanggan. Misalnya, pada hari pertama bulan berikutnya, tarif kartu diubah, aturan program bonus baru dimasukkan, atau jenis penerima pembayaran baru ditambahkan. Dan jika klien meluncurkan aplikasi tepat 0 jam 01 menit, maka ia harus melihat konten yang diperbarui.

"Dasar!" - kamu bilang. - "Unduh data ini dari server dan Anda akan senang."

Dan kamu akan benar. Kami melakukannya. Itu saja, kami tidak setuju .

Namun, tidak semuanya begitu sederhana. Kami memiliki aplikasi untuk iOS dan Android. Setiap platform memiliki beberapa versi berbeda yang memiliki fungsi dan api yang berbeda.
Akibatnya, mungkin kita perlu memperbarui file untuk aplikasi android dengan versi api lebih tinggi dari 27, tetapi tidak menyentuh iOS dan versi sebelumnya.

Ternyata lebih menarik ketika, misalnya, kita perlu memperbarui ikon penerima pembayaran atau menambahkan item baru dengan ikon baru. Kami menggambar setiap instance ikon dalam tujuh resolusi berbeda untuk setiap jenis layar spesifik: untuk android kami memiliki 4 resolusi (hdpi, xhdpi, xxhdpi, xxxhdpi) dan 3 untuk iOS (1x, 2x, 3x). Yang mana yang harus saya kirim ke aplikasi tertentu?

"Kalau begitu kirimkan parameter file yang dibutuhkan oleh aplikasi tertentu."

Benar! Tidak ada yang tahu tentang file mana yang dibutuhkan aplikasi, kecuali untuk aplikasi tersebut.
Namun, ini belum semuanya. Dalam aplikasi, ada beberapa file yang saling berhubungan. Misalnya, daftar penerima pembayaran (satu file json) dikaitkan dengan rincian penerima pembayaran (file json lain). Dan jika kami menerima file pertama dan karena alasan tertentu tidak dapat menerima yang kedua, maka pelanggan tidak akan dapat membayar untuk layanan ini. Dan ini tidak terlalu bagus, terus terang.

Kasus kedua: kami memperbarui seluruh rangkaian ikon penerima pembayaran (dan ada lebih dari seratus ikon) ketika memasuki halaman pembayaran. Bergantung pada kecepatan Internet, dapat dibutuhkan dari 10 detik hingga beberapa menit. Apa yang seharusnya menjadi perilaku halaman yang benar? Misalnya, Anda cukup menampilkan versi ikon sebelumnya, dan mengunduh yang baru di latar belakang, lalu menyimpannya dan hanya menampilkan yang baru saat berikutnya klien mengunjungi halaman. Entah bagaimana tidak, kan?

Pilihan lain adalah mengganti secara dinamis ikon yang sudah diunduh dengan yang baru. Tidak terlalu cantik, bukan? Dan jika beberapa ikon tidak mengunduh sama sekali? Kemudian kita akan melihat serangkaian ikon baru yang indah dengan sepotong desain lama di tengah.

Ikon operasi

"Lalu unduh seluruh set ikon dalam satu arsip saat startup aplikasi."

Ide bagus. Tidak benar-benar. Namun ada nuansa.

Sering terjadi bahwa seorang desainer hanya menggambar ulang beberapa ratusan ikon, dan Anda hanya perlu menggantinya. Beratnya 200 byte, dan seluruh arsip kami memiliki 200 kilobyte. Apakah klien harus memompa kembali apa yang sudah dimilikinya?

Dan kami belum menghitung biaya pekerjaan tersebut di server. Katakanlah 10.000 klien per jam datang kepada kami (ini adalah nilai rata-rata, itu terjadi lebih). Mulai aplikasi memulai pembaruan latar belakang direktori(ya, sekarang Anda tahu apa sebutan kami). Jika satu klien perlu memperbarui 1 kilobyte, maka dalam satu jam server akan memberikan lebih dari 10 megabita. Sen, benar? Dan jika set pembaruan berbobot 1 megabyte? dalam hal ini, kita harus memberikan sudah 10 gigabyte. Pada titik tertentu, kami sampai pada kesimpulan bahwa lalu lintas harus dipertimbangkan.

Maka Anda perlu belajar memahami file mana yang telah berubah dan mana yang tidak, dan hanya mengunduh yang diperlukan.

Baik. Tetapi bagaimana memahami file mana yang telah berubah dan mana yang tidak? Kami menganggap hash untuk ini. Dengan demikian, cache file tertentu muncul dalam aplikasi, yang berisi sekumpulan file referensi. File-file ini digunakan sebagai sumber daya sesuai kebutuhan. Dan di sisi server, kami akhirnya lahir ...

Layanan Direktori


Secara umum, ini adalah layanan web biasa yang mengirim file melalui http dengan mempertimbangkan semua persyaratan aplikasi. Ini terdiri dari sejumlah kontainer buruh pelabuhan, di mana aplikasi java bekerja dengan server web dermaga di papan. Backend adalah database Tarantool pada mesin vinil (tidak ada pilihan yang menyakitkan - hanya memiliki seluruh ikatan untuk database ini; Anda dapat membacanya di artikel saya sebelumnya layanan cache Smart berdasarkan ZeroMQ dan Tarantool ) dengan replikasi master-slave. Untuk mengelola file ada antarmuka web layanan, juga sepenuhnya ditulis sendiri.



Detail implementasi teknis dalam topik artikel ini tidak terlalu signifikan. Ini bisa berupa php + apache + mysql, C # + IIS + MSSQL, atau bundel lainnya, termasuk tanpa database sama sekali.

Diagram di bawah ini menunjukkan bagaimana layanan yang kami sebut Woodside bekerja. Klien seluler melalui penyeimbang pergi ke contoh layanan web, dan mereka, pada gilirannya, mendapatkan file yang diperlukan dari database.

Skema kerja

Tetapi dalam artikel ini saya hanya akan berbicara tentang struktur sistem referensi, dan bagaimana kita menggunakannya dalam aplikasi.

File yang diperlukan dalam aplikasi, kami bagi menjadi 3 jenis.

  1. File yang harus selalu ada dalam aplikasi, dan independen dari jenis sistem operasi. Sebagai contoh, ini adalah file pdf dengan perjanjian layanan perbankan.
  2. -, , ( ) . , .
  3. , , . - , , . , .

Program Afiliasi

2 jenis file pertama dalam bentuk arsip segera dimasukkan ke dalam rakitan aplikasi - rilis baru secara default termasuk set direktori terbaru. Mereka jatuh ke dalam sistem pembaruan otomatis, yang berjalan di latar belakang ketika aplikasi dimulai, dan berfungsi sebagai berikut.

1. Layanan direktori secara otomatis menerima bagian dari data dari berbagai tempat: basis data, layanan terkait, bola jaringan - ini adalah beberapa informasi perbankan umum yang penting yang diperbarui oleh departemen lain. Bagian lainnya adalah direktori yang dibuat dalam tim kami melalui antarmuka web dan berisi file yang hanya ditujukan untuk aplikasi seluler.

2. Menurut jadwal (atau dengan tombol), layanan menjalankan semua file dari semua direktori, dan atas dasar mereka membentuk satu set file indeks (di dalam json) baik untuk file jenis pertama (2 versi untuk iOS dan android), dan untuk file sumber daya dari yang kedua ketik (7 versi untuk setiap jenis layar).
Itu terlihat seperti ini:

{
  "version": "43",
  "date": "04 Apr 2020 12:31:59",
  "os": "android",
  "screen": "any",
  "hashType": "md5",
  "ts": 1585992719,
  "files": [
    {
      "id": "WBRbDUlWhhhj",
      "name": "action-in-rhythm-of-life.json",
      "dir": "actions",
      "ts": 1544607853,
      "hash": "68c589c4fa8a44ded4d897c3d8b24e5c"
    },
    {
      "id": "o3K4mmPOOnxu",
      "name": "banks.json",
      "dir": "banks",
      "ts": 1583524710,
      "hash": "c136d7be420b31f65627f4200c646e0b"
    }
  ]
}

Indeks berisi informasi tentang semua file dari jenis yang diberikan, atas dasar di mana mekanisme untuk memperbarui direktori pada aplikasi dibangun.

3. Aplikasi saat startup, hal pertama yang mereka unduh adalah file indeks di direktori / baru di dalam cache file mereka. Dan di direktori / saat ini mereka memiliki indeks untuk set file saat ini bersama dengan file itu sendiri.

4. Berdasarkan file indeks baru dan lama (dengan partisipasi semua file saat ini dari mana hash dipertimbangkan), daftar file dibuat yang perlu diperbarui atau dihapus, dan kebutuhan untuk memperbarui secara umum dibuat.

5. Setelah itu, ke direktori / baruaplikasi mengunduh file yang diperlukan dari server melalui tautan langsung (id file dalam indeks bertanggung jawab untuk ini). Dalam hal ini, keberadaan dan hash file yang sudah ada di direktori / baru diperhitungkan , karena ini bisa menjadi resume.

6. Segera setelah seluruh set file diterima di direktori / baru , mereka diperiksa terhadap file indeks (kadang-kadang terjadi bahwa file tidak sepenuhnya diunduh).

7. Jika pemeriksaan berhasil, seluruh pohon file dipindahkan dengan penggantian di direktori / saat ini . File indeks baru menjadi terkini.

8. Jika verifikasi tidak berhasil, transfer file tidak akan terjadi, dan aplikasi akan terus menggunakan set direktori saat ini. Saat berikutnya aplikasi dimulai, mekanisme pembaruan akan mencoba memperbaikinya. Jika kami mengalami kerusakan global saat memindahkan file, maka kami terpaksa memutar kembali ke versi pertama direktori yang disertakan dengan perakitan. Sejauh ini belum ada preseden.

Tetapi mengapa begitu sulit?

Pada kenyataannya, tidak terlalu sulit. Tetapi kenyataannya adalah bahwa kita terus-menerus harus bereksperimen dan menemukan kompromi antara jumlah file yang terus diperbarui dan waktu buka, antara menghemat lalu lintas dan kecepatan. Peran penting dalam memilih jenis file dimainkan ketika sebenarnya dibutuhkan dalam aplikasi. Misalkan, jika ikon harus segera ditampilkan di halaman utama setelah login, maka aplikasi dapat memuat file seperti itu di runtime segera, dan tidak memasukkannya ke dalam mekanisme pembaruan yang panjang. Sekarang ukuran total arsip dengan hanya file utama adalah 12 megabyte, tidak termasuk sumber daya yang tergantung layar. Dan karena pembaruan pada dasarnya adalah operasi atom, kita harus menunggu sampai selesai. Ini bisa memakan waktu hingga beberapa menit dalam kasus di mana koneksi buruk dan ada banyak file baru.

Poin penting adalah menghemat lalu lintas. Ada saat-saat ketika kami benar-benar memanfaatkan saluran 100 megabit setelah pembaruan yang tebal. Saya harus memperluas ke 300. Sejauh ini, cukup. Rata-rata, metrik menunjukkan bahwa biasanya klien mengunduh dari 25 hingga 50 gigabita per jam di siang hari (ini karena kami memiliki file yang cukup besar yang diperbarui setiap hari). Masih ada ruang untuk pengembangan lebih lanjut dalam hal ekonomi, tetapi bisnis juga waspada - sepanjang waktu mereka menambahkan berbagai keindahan baru.

Sebagai kesimpulan, saya dapat menambahkan bahwa server depan sendiri juga menggunakan layanan ini, yang saat startup mengunduh data yang diperlukan untuk memproses permintaan klien.

Dan bagaimana Anda mengirimkan pembaruan konten ke aplikasi?

All Articles