Bagaimana kami menjaga stabilitas aplikasi Lamoda

Halo semuanya!

Nama saya Vitaliy Bendik. Saya adalah pemimpin tim untuk pengembangan aplikasi Android di Lamoda. Pada tahun 2018, saya berbicara di Mosdroid Aluminium dengan sebuah laporan , transkrip yang ingin saya bagikan.

gambar

Akan tentang bagaimana kita menjaga stabilitas aplikasi seluler. Ini sangat penting bagi kami, karena pemirsa seluler kami adalah jutaan pengguna. Selain itu, dalam hal pangsa dalam pesanan pelanggan kami, aplikasi telah lama melampaui situs, versi desktop dan seluler, dan platform iOS telah menjadi pemimpin mutlak, di depan situs desktop.

Dalam laporan itu saya akan memberi tahu:

  1. apa yang kita maksud dengan stabilitas aplikasi;
  2. Tentang arsitektur aplikasi seluler kami;
  3. tentang proses, praktik, dan alat yang kami gunakan.


Jadi, apa aplikasi yang stabil untuk kita? Ini adalah aplikasi yang tidak macet, tidak hang, dan berfungsi seperti yang diperkirakan. Ketika saya mengatakan bahwa itu tidak jatuh, maksud saya itu tidak jatuh di setidaknya 95% -99% pengguna.

Arsitektur


gambar

Seperti yang mungkin sudah Anda duga, gambar ini menunjukkan arsitektur murni, yang kami coba patuhi. Sebagai lapisan Presentasi, kami menggunakan MVP dengan beberapa tambahan, yang akan saya bahas di bawah ini.

Aplikasi seluler kami disesuaikan untuk ponsel dan tablet. Oleh karena itu, tata letak sering berbeda, tetapi terdiri dari blok yang sama atau identik. Dalam hal ini, kami memiliki entitas seperti Widget. Ini memungkinkan Anda untuk menguraikan aktivitas atau fragmen menjadi blok yang lebih kecil yang dapat digunakan kembali di layar lain. Ini masuk akal, karena dari sudut pandang kode yang ada di fragmen atau dalam aktivitas, jarang diperlukan untuk membedakan antara konteks yang sedang dijalankan oleh UI. Dan fragmen kode ini dapat dibuat menjadi beberapa abstraksi dan digunakan kembali. Pendekatan ini agak mengingatkan pada perpustakaan SoundCloud - LightCycle .

gambar
gambar
gambar
Halaman produk. Contoh Elemen Widget

Adapun interaksi presenter dengan model, semuanya standar di sini: presenter berinteraksi dengan seluruh aplikasi melalui interaktor, apakah itu repositori atau manajer.

gambar

Kebetulan beberapa presenter perlu berkomunikasi satu sama lain, bertukar data. Untuk ini, kami memiliki koordinator, yang dapat dianggap sebagai interaksi bersama antara beberapa penyaji.

gambar

Tumpukan


- Kami menulis semua kode baru di Kotlin , dan kami menggunakan Moxy sebagai implementasi MVP.
- Sebagai DI kita menggunakan Dagger2 .
- Untuk bekerja dengan jaringan - Retrofit .
- Untuk bekerja dengan gambar - Glide .
- Kami menambahkan crash ke Relik Baru .
- Kami juga menggunakan Lottie .
- Saat ini, kami secara aktif menggunakan Kotlin Coroutines .

Proses pengembangan


Kami mematuhi aliran Git, yaitu, setiap fitur diimplementasikan dalam cabang fitur terpisah, yang, setelah peninjauan kode, diajukan untuk pengujian.

Setelah penguji berhasil menyelesaikan pengujian, dan kami memutuskan pada versi bahwa fitur ini akan pergi, itu menggabungkan ke master.

Ketika waktu rilis tiba (kami akan dirilis setiap 2 minggu), cabang-r, di mana pengujian asap dilakukan, dialokasikan, kasus uji dijalankan. Setelah itu, fitur bergabung ke cabang produksi dan diterbitkan di Google Play Beta.

gambar

Adapun CI / CD, karena kami menggunakan tumpukan Atlassian, Bamboo bertindak sebagai server pembangun.

Saat pengembang membuat permintaan tarik, tugas pembangunan dimulai dari Bamboo. Dia menarik kode dari repositori, menjalankan skrip pada fastlane, yang mengumpulkan aplikasi, menjalankan tes dan melaporkannya ke Slack.

Jika penguji memulai perakitan untuk menguji fitur, maka apk juga dimuat di HockeyApp.

Untuk mempublikasikan rilis di Google Play Beta, manajer pengiriman meluncurkan tugas terkait di Bamboo, yang menjalankan aliran yang sama, tetapi juga mengunggah versi ke Google Play Beta.

gambar

Praktek Terapan


Pra-rilis build

Awalnya, kami memiliki dua jenis perakitan, seperti banyak:

Debug build di mana ProGuard dan SSL Pinning dinonaktifkan.
Rilis rilis yang menyertakan ProGuard dan Pinning SSL.
Prosesnya terlihat seperti ini: pengembang selesai mengerjakan fitur dan memberikannya untuk pengujian. Penguji mengumpulkan rakitan Debug, menguji kasus uji di atasnya dan memeriksa kebenaran analitik yang dikirim oleh aplikasi. Jika semuanya baik-baik saja, maka dia mengirimkan tugas ke Siap untuk rilis, dan dia menunggu saat ketika kita mulai mengumpulkan rilis.

Ketika tiba saatnya untuk rilis aplikasi, pengembang menggabungkan semua tugas menjadi master, memilih cabang rc dan memberinya QA untuk pengujian asap. QA mengumpulkan perakitan rilis, mulai menjalankan tes. Tetapi ada kalanya ada yang tidak beres. Masalah biasanya terjadi karena ProGuard. Tentu saja, mereka cepat diperbaiki, tetapi ini dapat menunda rilis atau menunda untuk beberapa waktu.

Untuk alasan ini, kami membuat bangunan pra-rilis di mana ProGuard dihidupkan dan Pinning SSL dimatikan. Ini memungkinkan para penguji untuk memverifikasi kebenaran dari analitik yang dikirimkan (inilah alasan mengapa para penguji pada awalnya tidak membangun pembuatan rilis).
Sekarang, QA sedang membangun bangunan pra-rilis. Ini memberi mereka kesempatan untuk menguji analitik dan untuk menghadapi masalah yang disebabkan oleh ProGuard sedini mungkin.

Spesifikasi terlebih dahulu

Ini adalah pendekatan di mana spesifikasinya utama. Ketika kami mengembangkan fitur baru dan memerlukan backend, spesifikasi dibuat terlebih dahulu, dan kemudian berdasarkan itu, pengembangan fitur dimulai baik dari backend dan dari klien. Semua perubahan melewati spesifikasi, dan hanya kemudian perubahan dilakukan pada backend dan klien. Spesifikasi ini juga menghasilkan dokumentasi Swagger tentang metode API.

gambar

Awalnya, kami memiliki API yang kliennya bukan hanya aplikasi seluler. Metode API tidak konsisten satu sama lain, yang seringkali membuat perubahan sulit.

Juga sering menjumpai kasus lucu. Misalnya, ketika metode mengembalikan daftar merek, dalam kasus ketika ada beberapa, itu mengembalikan array, dan jika hanya ada satu merek, itu mengembalikan objek.

gambar

Atau, ketika tidak ada merek, null dikembalikan, atau secara umum 4 karakter null
(bukan JSON). Dalam hal ini, aplikasinya sulit.

gambar

Oleh karena itu, dari waktu ke waktu, kami sampai pada kesimpulan bahwa aplikasi seluler memerlukan API mereka sendiri, yang akan mempertimbangkan spesifikasinya dan mengaitkan aplikasi seluler dengan sekelompok sistem Lamoda internal yang harus berinteraksi dengan Anda.

gambar

Pada saat yang sama, kami memutuskan untuk mencoba pendekatan spesifikasi pertama (spesifikasi Swagger). Ketika seorang pengembang mulai bekerja pada beberapa fitur yang membutuhkan backend, ia membuat permintaan tarik dengan kontrak fitur. Kemudian semua pihak yang tertarik dari iOS, Android, dan tim backend ditambahkan ke permintaan penarikan ini. Ketika semua orang puas dengan kontrak metode API baru, permintaan tarik dituangkan ke cabang backend dan pengembang backend mulai mengembangkan fitur. Pelanggan juga mulai mengembangkan fitur, karena kontraknya sekarang telah diperbaiki dan Anda dapat mengandalkannya dan, jika perlu, membuat moki.

Matikan-fitur

Perusahaan memiliki pengembangan A / B Tool sendiri, yang memungkinkan Anda untuk mengimplementasikan eksperimen dan fitur-toggle. Fitur-matikan kami menutup fungsionalitas tidak kritis untuk pengguna, yang, jika perlu, dapat dinonaktifkan. Misalnya, jika ada kesalahan di dalamnya, atau jika kita perlu mengurangi beban di backend (sebagai opsi, pada "Black Friday").

Fitur-matikan juga memungkinkan kami untuk menguji perpustakaan untuk dapat melihat apakah perpustakaan lain akan memecahkan masalah kita lebih baik dan berperilaku lebih stabil. Jika tidak, maka kita selalu dapat kembali ke perpustakaan sebelumnya.

Pemantauan pengguna nyata

Pemantauan Pengguna Nyata memungkinkan Anda untuk mengukur kinerja aplikasi dari perspektif pengguna. Sebagai contoh, seorang pelanggan mengklik sebuah item dalam katalog. Berapa lama dia harus menunggu sebelum dia melihat hasil dari tindakannya, yaitu, dia melihat kartu produk dengan foto?
gambar
Ini tidak dapat dilakukan secara otomatis, karena titik awal dan titik akhir pengukuran ini harus ditetapkan secara manual. Hanya pengembang yang mengerti ketika dapat diasumsikan bahwa pengguna siap untuk berinteraksi dengan layar baru. Dalam proses interaksi ini, kita mungkin tertarik pada hal-hal seperti:

1. konsumsi memori;
2. konsumsi CPU;
3. apa yang terjadi pada arus utama;
4. apa yang dimuat dari jaringan;
5. apa yang terjadi di utas lainnya.

Ini memberi kita peluang untuk memperbaiki masalah jika muncul, karena menjadi jelas bahwa itu benar-benar menghabiskan sebagian besar waktu dan kita dapat mengoptimalkannya sehingga aplikasi lebih responsif kepada pengguna.

Pengembalian utang teknis


Sebelum meluncurkan versi baru, kami memperbaiki kerusakan yang terjadi di versi sebelumnya. Ini bukan tentang crash kritis, karena ini pasti akan memerlukan perbaikan terbaru, tetapi tentang crash yang tidak terjadi terlalu sering tidak mempengaruhi kinerja bisnis, tetapi tidak menyenangkan bagi pengguna.

Setelah rilis versi, kami meluncurkannya berdasarkan persentase, memantau indikator kritis dan menanggapi insiden jika terjadi. Untuk pengguliran bertahap, kami menggunakan Google Play Console. Pengguliran dilakukan sebagai berikut: diluncurkan sebesar 5%, kami memantau indikator; jika semuanya beres, maka bergulir. Jika sesuatu terjadi, buat perbaikan terbaru dan roll out sudah. Selanjutnya, kami melakukan rolling 10%, 20% dan 50%.

Tempat kritis apa yang kami pantau ?

  1. Permintaan jaringan, termasuk dari perpustakaan pihak ketiga: kesalahan, waktu respons, memuat.
  2. Musim gugur.
  3. Menangani pengecualian, yang disebut "pengecualian yang diproses". Ini adalah pengecualian yang bisa terjadi jika kita tidak membungkusnya dengan try-catch. Ini memungkinkan aplikasi untuk tidak jatuh jika pengecualian terjadi pada fungsionalitas yang tidak kritis bagi pengguna. Misalnya, jatuh miskin karena analitik. Namun, penting bagi produk untuk memahami bahwa fitur meningkatkan atau memperburuk konversi. Menggunakan pengecualian yang Ditangani memungkinkan kami untuk tetap merespons dan memperbaiki masalah ini.

Alat-alatnya


  • Alat A / B
  • RPM BaruRelik
  • Wawasan Baru.

Alat A / B adalah mekanisme untuk melakukan eksperimen dan mekanisme untuk variabel bergulir, fitur-toggle yang sama. Ini adalah pengembangan internal, sehingga terintegrasi dengan baik ke dalam banyak sistem: dalam aplikasi seluler, di situs, di bagian belakang. Ini memungkinkan Anda untuk menyampaikan konfigurasi Fitur-beralih tidak dalam permintaan terpisah di belakangnya, tetapi di header tanggapan terhadap permintaan yang dilakukan aplikasi.

Ini memberi kita kesempatan:

  • Luncurkan eksperimen di kantor ketika kami ingin menguji beberapa fitur di dalam kantor kami.
  • Luncurkan percobaan, serta matikan Fitur untuk pengguna tertentu.

Sistem ini tidak tergantung pada faktor eksternal. Jika kami menggunakan alat pihak ketiga, maka di beberapa titik itu bisa diblokir (halo, Roskomnadzor) atau ada yang salah di dalamnya. Bagi kami, ini akan menjadi sangat penting, karena dalam hal ini kami tidak akan dapat dengan cepat beralih fitur-toggle. Dan karena ini adalah pengembangan kami sendiri, kami tidak punya masalah seperti itu.

NewRelic adalah alat yang memungkinkan Anda memantau banyak indikator berbeda secara real time. Dari beragam fitur Relik Baru, kami menggunakan, misalnya, instrumentasi kode otomatis. Hal inilah yang memungkinkan kami untuk memonitor permintaan jaringan tidak hanya ke backend kami, tetapi juga semua yang lain (termasuk dari perpustakaan pihak ketiga). NewRelic mendukung sekumpulan klien standar untuk bekerja dengan jaringan. Anda juga dapat mengumpulkan informasi:

1. tentang konsumsi memori;
2. tentang konsumsi CPU;
3. tentang operasi yang terkait dengan JSON;
4. tentang operasi yang terkait dengan SQlite.

Selain itu, kami menggunakan NewRelic untuk mengumpulkan laporan kerusakan, untuk mengumpulkan pengecualian yang ditangani dan untuk interaksi pengguna - ini persis dengan Pemantauan Pengguna Nyata yang sama. Kami sudah menerapkannya melalui mekanisme interaksi pengguna NewRelic.

Tetapi bagaimana dengan stabilitas?


Kami memiliki indikator seperti tingkat kerusakan. Sebelumnya, kami meluncurkan perbaikan terbaru ketika indikatornya berada di kisaran 0,3% hingga 0,5%. Sangat penting jika nilainya menjadi lebih dari 0,5%. Sekarang kami meluncurkan perbaikan terbaru ketika tingkat kerusakan berada di kisaran 0,1% hingga 0,3%. Nilai kritis lebih dari 0,3%. Dan, jika sebelumnya tingkat kerusakan rata-rata aplikasi kami adalah 0,1%, sekarang adalah 0,05%.

gambar

Sebagai kesimpulan, saya ingin membuat daftar praktik paling penting yang membantu kami menjaga stabilitas aplikasi. Kami menguji aplikasi sedekat mungkin dengan versi produksi, menutup fungsionalitas kritis dari toggle-toggle, serta memantau dan menanggapi indikator yang penting bagi kami.

Source: https://habr.com/ru/post/id461897/


All Articles