Desain untuk penyembuhan mandiri

Desain aplikasi Anda agar dapat menyembuhkan diri ketika kegagalan terjadi

Dalam sistem terdistribusi, kegagalan dapat terjadi. Perangkat keras bisa mengalami kegagalan. Jaringan dapat mengalami kegagalan sementara. Jarang akan seluruh layanan, pusat data, atau bahkan wilayah Azure mengalami gangguan, namun, bahkan yang harus direncanakan.

Oleh karena itu, rancang aplikasi yang menyembuhkan diri ketika kegagalan terjadi. Ini membutuhkan pendekatan tiga cabang:

  • Deteksi kegagalan.
  • Tanggapi kegagalan dengan elegan.
  • Mencatat dan memantau kegagalan untuk memberikan wawasan operasional.

Cara Anda menanggapi jenis kegagalan tertentu mungkin tergantung pada persyaratan ketersediaan aplikasi Anda. Misalnya, jika Anda memerlukan ketersediaan tinggi, Anda dapat menyebarkan ke beberapa zona ketersediaan di suatu wilayah. Untuk menghindari pemadaman, bahkan jika seluruh wilayah Azure yang tidak mungkin mengalami gangguan, Anda dapat secara otomatis melakukan failover ke wilayah sekunder selama pemadaman regional. Namun, itu akan dikenakan biaya yang lebih tinggi dan berpotensi menurunkan performa daripada penyebaran satu wilayah.

Selain itu, jangan hanya mempertimbangkan peristiwa besar seperti ketidaktersediaan regional, yang umumnya jarang terjadi. Anda juga harus memberikan fokus yang sama banyaknya pada penanganan kegagalan lokal yang berumur pendek, seperti kegagalan konektivitas jaringan atau koneksi database yang gagal.

Rekomendasi

Mencoba lagi operasi yang gagal. Kegagalan sementara dapat terjadi karena hilangnya konektivitas jaringan sesaat, koneksi database yang terputus, atau waktu habis ketika layanan sibuk. Bangun logika coba lagi ke dalam aplikasi Anda untuk menangani kegagalan sementara. Untuk banyak layanan Azure, SDK klien menerapkan percobaan ulang otomatis. Untuk informasi selengkapnya, lihat Penanganan kegagalan sementara dan pola Coba Lagi.

Lindungi layanan jarak jauh yang gagal (Circuit Breaker). Baik untuk mencoba kembali setelah terjadi kegagalan sementara, tetapi jika kegagalan berlanjut, Anda dapat berakhir dengan terlalu banyak pemanggil menyerang layanan yang gagal. Ini dapat menyebabkan kegagalan bertingkat saat permintaan dicadangkan. Gunakan pola Circuit Breaker untuk gagal cepat (tanpa melakukan panggilan jarak jauh) ketika operasi cenderung gagal.

Isolasi sumber daya kritis (Sekat). Kegagalan dalam satu subsistem kadang-kadang dapat menghasilkan kaskade. Ini dapat terjadi jika kegagalan menyebabkan beberapa sumber daya, seperti utas atau soket, tidak dibebaskan tepat waktu, yang menyebabkan kelelahan sumber daya. Untuk menghindari hal ini, gunakan pola Bulkhead untuk mempartisi sistem ke dalam grup terisolasi sehingga kegagalan dalam satu partisi tidak menurunkan seluruh sistem.

Lakukan perataan beban. Aplikasi mungkin mengalami lonjakan lalu lintas tiba-tiba, yang dapat membebani layanan pada ujung belakang. Untuk menghindari hal ini, gunakan pola perataan Beban Berbasis Antrean untuk membariskan item kerja agar berjalan secara asinkron. Antrian bertindak sebagai penyangga yang menghaluskan puncak beban.

Mengalihkan. Jika instans tidak dapat dihubungi, alihkan ke instans lain. Untuk hal-hal yang tidak berstatus, seperti server web, letakkan beberapa contoh di belakang load balancer atau traffic manager. Untuk hal-hal yang menyimpan status, seperti database, gunakan replika dan alihkan. Tergantung pada penyimpanan data dan cara replikasinya, aplikasi mungkin harus berurusan dengan konsistensi akhir.

Mengompensasi transaksi yang gagal. Secara umum, hindari transaksi terdistribusi, karena memerlukan koordinasi lintas layanan dan sumber daya. Sebagai gantinya, buat operasi dari transaksi individual yang lebih kecil. Jika operasi gagal di tengah jalan, gunakan Transaksi Kompensasi untuk membatalkan langkah yang sudah selesai.

Titik pemeriksaan transaksi jangka panjang. Titik pemeriksaan dapat memberikan ketahanan jika operasi yang telah berjalan lama gagal. Ketika operasi dimulai ulang (misalnya, diambil oleh VM lain), itu dapat dilanjutkan dari titik pemeriksaan terakhir. Pertimbangkan untuk menerapkan mekanisme yang merekam informasi status tentang tugas secara berkala, dan simpan status ini dalam penyimpanan tahan lama yang dapat diakses oleh instans apa pun dari proses yang menjalankan tugas. Dengan cara ini, jika proses dimatikan, pekerjaan yang sedang dilakukan dapat dilanjutkan dari titik pemeriksaan terakhir dengan menggunakan instans lain. Ada pustaka yang menyediakan fungsionalitas ini, seperti NServiceBus dan MassTransit. Status tersebut bertahan secara transparan, di mana interval diselaraskan dengan pemrosesan pesan dari antrean di Azure Bus Layanan.

Rendahkan dengan elegan. Terkadang Anda tidak dapat mengatasi masalah, tetapi Anda dapat memberikan fungsionalitas yang dikurangi yang masih berguna. Pertimbangkan sebuah aplikasi yang menampilkan katalog buku. Jika aplikasi tidak dapat mengambil gambar mini untuk sampul, aplikasi mungkin menampilkan gambar tempat penampung. Seluruh subsistem mungkin nonkritis untuk aplikasi tersebut. Misalnya, pada situs e-niaga, menunjukkan rekomendasi produk mungkin kurang penting daripada memproses pesanan.

Pembatasan klien. Terkadang sejumlah kecil pengguna menghasilkan beban yang berlebihan, yang dapat mengurangi ketersediaan aplikasi Anda untuk pengguna lain. Dalam situasi ini, batasi klien untuk jangka waktu tertentu. Lihat pola Pembatasan.

Blokir pelaku jahat. Hanya karena Anda membatasi klien, itu tidak berarti klien bertindak jahat. Itu hanya berarti klien telah melebihi kuota layanan mereka. Tetapi jika klien secara konsisten melebihi kuota mereka atau berperilaku buruk, Anda dapat memblokir mereka. Tentukan proses out-of-band bagi pengguna untuk meminta penghentian pemblokiran.

Gunakan pemilihan pemimpin. Ketika Anda perlu mengoordinasikan tugas, gunakan Pemilihan Pemimpin untuk memilih koordinator. Dengan cara itu, koordinator bukanlah satu titik kegagalan. Jika koordinator gagal, yang baru akan dipilih. Daripada menerapkan algoritma pemilihan pemimpin dari awal, pertimbangkan solusi off-the-shelf seperti Zookeeper.

Uji dengan injeksi kesalahan. Sering kali, jalur kesuksesan diuji dengan baik, tetapi tidak dengan jalur kegagalan. Sebuah sistem dapat berjalan dalam produksi untuk waktu yang lama sebelum jalur kegagalan diterapkan. Gunakan injeksi kesalahan untuk menguji ketahanan sistem terhadap kegagalan, baik dengan memicu kegagalan aktual atau dengan simulasi.

Terima rekayasa kekacauan. Rekayasa chaos memperluas gagasan injeksi kesalahan dengan menyuntikkan kegagalan atau kondisi abnormal secara acak ke dalam instans produksi.

Pertimbangkan untuk menggunakan zona ketersediaan. Banyak wilayah Azure menyediakan zona ketersediaan, yang merupakan kumpulan pusat data terisolasi dalam wilayah tersebut. Beberapa layanan Azure dapat disebarkan secara zonal, yang memastikan mereka ditempatkan di zona tertentu dan dapat membantu mengurangi latensi dalam berkomunikasi antar komponen dalam beban kerja yang sama. Atau, beberapa layanan dapat disebarkan dengan redundansi zona, yang berarti bahwa Azure secara otomatis mereplikasi sumber daya di seluruh zona untuk ketersediaan tinggi. Pertimbangkan pendekatan mana yang memberikan serangkaian tradeoff terbaik untuk solusi Anda. Untuk mempelajari selengkapnya tentang cara merancang solusi Anda untuk menggunakan zona dan wilayah ketersediaan, lihat Rekomendasi untuk menggunakan zona dan wilayah ketersediaan.

Untuk pendekatan terstruktur agar membuat aplikasi Anda menyembuhkan sendiri, lihat Merancang aplikasi yang andal untuk Azure.