Flamboyan


Pemutus Arus atau Coba Lagi? (Bagian 1)

Posting ini adalah yang pertama dari seri dua bagian tentang Circuit Breakers and Retries, di mana kami akan memperkenalkan dan membandingkan dua konsep keandalan layanan yang sering digunakan ini. Untuk Bagian 1, kami akan fokus pada kasus penggunaan untuk menerapkan pemutus sirkuit termasuk berbagai opsi terkait dengan konfigurasi sirkuit. Pada Grab, kami menggunakan kedua mekanisme ini secara luas di seluruh banyak sistem perangkat lunak kami untuk memastikan bahwa kami dapat mengatasi kegagalan dan melanjutkan untuk menyediakan pelanggan kami dengan layanan yang mereka harapkan dari kami. Dalam artikel pertama dari seri dua bagian ini, kami akan mulai memperkenalkan dan membandingkan dua mekanisme keandalan layanan yang sering digunakan: Pemutus Sirkuit dan Retries. Dalam seri ini kami akan mencermati kedua pendekatan dan kasus penggunaannya, untuk membantu Anda membuat keputusan berdasarkan informasi tentang jika dan kapan menerapkan masing-masing metode. Tetapi mari kita mulai dengan melihat alasan umum untuk kegagalan. Namun daripada memikirkan semua cara panggilan ke layanan hulu bisa gagal, seringkali lebih mudah untuk mempertimbangkan apa permintaan yang berhasil. Itu harus tepat waktu, dalam format yang diharapkan, dan berisi data yang diharapkan. Dalam merencanakan kegagalan, kita harus berusaha untuk dapat menangani masing-masing kesalahan ini, sama seperti kita harus mencoba untuk mencegah layanan kami memancarkannya. Jadi mari kita mulai melihat berbagai teknik untuk mengatasi kesalahan ini.Pemutus sirkuit perangkat lunak adalah mekanisme yang berada di antara 2 buah kode dan memantau kesehatan segala sesuatu yang mengalir melaluinya. Namun, alih-alih menghentikan listrik ketika ada kesalahan, itu menghalangi permintaan. Pemutus sirkuit perangkat lunak bekerja dengan cara yang sama. Pemutus sirkuit menerima respons, dan jika tidak ada kesalahan, mengembalikannya ke pemanggil asli. "Utama" kami memanggil pemutus sirkuit, yang pada gilirannya membuat permintaan ke layanan hulu. Layanan hulu kemudian memproses permintaan dan mengirimkan respons. Ini memperhatikan bahwa semua permintaan gagal, jadi alih-alih membuat permintaan lebih lanjut, ia membuka sirkuit, yang mencegah permintaan lagi. Dan pada titik ini, Anda mungkin bertanya-tanya apa yang telah kami dapatkan dari ini karena permintaan kami masih gagal. Pemutus sirkuit telah memantau permintaan ini dan melacak berapa banyak yang berlalu dan berapa banyak yang gagal. Namun, mari kita asumsikan bahwa semua permintaan selama 3 detik terakhir telah gagal. Anda benar, untuk permintaan khusus ini, kami tidak memperoleh apa-apa. Jalur permintaannya sama. Kedua, dengan membuat lebih banyak permintaan, kami tidak mengizinkan layanan hulu untuk pulih dari kewalahan dan pada kenyataannya, kemungkinan besar membebani lebih banyak. Pertama, membuat permintaan sepertinya tidak ada gunanya, karena kami tidak akan mendapatkan respons yang valid dan / atau tepat waktu. Pertimbangkan diskusi kami sebelumnya tentang bagaimana layanan dapat rusak: Layanan dapat rusak ketika mereka dipenuhi dengan permintaan. Setelah layanan kelebihan beban, membuat permintaan lebih lanjut dapat mengakibatkan dua masalah.Tentu saja, menghitung jarak dengan cara ini akan tidak akurat, tetapi menggunakan nilai yang tidak akurat yang memungkinkan kami untuk terus memproses permintaan pengguna jauh lebih baik daripada gagal permintaan sepenuhnya. Jika semuanya berjalan sebagaimana mestinya, kami akan memanggil "layanan kalkulator jarak", menyediakannya dengan lokasi awal dan akhir, dan itu akan mengembalikan jarak. Karenanya fallback yang masuk akal dalam situasi ini adalah memperkirakan jarak dengan menggunakan beberapa trigonometri. Namun, layanan itu sedang down saat ini. Ada CPU, memori dan sumber daya jaringan, semua digunakan untuk membuat permintaan dan menunggu tanggapan. Pertimbangkan biaya pembuatan dan menunggu permintaan yang akhirnya gagal. Lalu ada respons yang tertunda untuk pengguna Anda. Semua biaya ini dihindari ketika sirkuit terbuka, karena permintaan tidak dibuat tetapi langsung gagal. Meskipun mengembalikan kesalahan kepada pengguna kami tidak ideal, mengembalikan kesalahan yang paling cepat adalah pilihan terburuk terbaik. Tidak seperti contoh listrik yang kami gunakan di atas, dengan pemutus sirkuit perangkat lunak, Anda tidak perlu menemukan kotak sekering dalam gelap dan tutup sirkuit secara manual. Pemutus sirkuit perangkat lunak dapat menutup sirkuit dengan sendirinya. Setelah pemutus sirkuit membuka sirkuit, ia akan menunggu periode yang dapat dikonfigurasi, disebut Sleep Window, setelah itu akan menguji sirkuit dengan membiarkan beberapa permintaan masuk. Jika permintaan masih mengembalikan kesalahan, maka itu akan mengulangi proses tidur / coba sampai pemulihan. Jika layanan telah pulih, ia akan menutup sirkuit dan melanjutkan operasi normal.
Benteng adalah proses perangkat lunak yang memantau jumlah permintaan bersamaan dan mampu mencegah lebih dari jumlah maksimum permintaan bersamaan yang dibuat. Di Grab, kami menggunakan pemutus sirkuit Hystrix-Go, dan implementasi ini mencakup benteng. Ini adalah bentuk pembatasan tingkat yang sangat murah. Ini karena semua kegagalan terkait dengan infrastruktur dan dalam kasus ini ketika panggilan ke satu titik akhir gagal, semua pasti akan gagal. Jadi bagaimana kita memutuskan untuk pergi bersama? Dalam dunia ideal, satu sirkuit per tujuan hulu sudah cukup. Pendekatan ini akan menghasilkan sirkuit dibuka dalam waktu secepat mungkin, sehingga mengurangi tingkat kesalahan kami. Sebagai contoh, jika kita secara tidak sengaja melacak kesalahan pengguna pada salah satu panggilan pemutus sirkuit kita, kita dapat dengan cepat menemukan diri kita dicegah dari membuat panggilan apa pun ke hulu kami. Namun, pendekatan ini mengasumsikan bahwa layanan hulu kami tidak dapat gagal sedemikian rupa sehingga satu titik akhir rusak dan yang lain tetap bekerja. Ini juga mengasumsikan bahwa pemrosesan respons hulu kami tidak pernah melakukan kesalahan dalam memproses kesalahan yang dikembalikan dari layanan hulu. Oleh karena itu, meskipun memiliki satu sirkuit per titik akhir menghasilkan sirkuit yang sedikit lebih lambat untuk dibuka, itu adalah pendekatan yang saya rekomendasikan. Lebih baik untuk membuat sebanyak mungkin permintaan yang berhasil daripada membuka sirkuit dengan tidak tepat. Kita telah berbicara tentang layanan hulu seolah-olah mereka adalah tujuan tunggal, dan ketika berurusan dengan basis data atau cache, mereka mungkin saja. Tetapi ketika berhadapan dengan API / layanan, ini jarang terjadi.Jadi, jika satu mesin kekurangan sumber daya, ini tidak berarti bahwa semua mesin lain yang mendukung layanan tersebut akan memiliki masalah yang sama. Jika mesin yang menjalankan layanan hulu kami memiliki masalah sumber daya, ini adalah masalah yang dilokalkan ke mesin tertentu. Tapi mengapa ini penting? Pikirkan kembali diskusi kita sebelumnya tentang bagaimana suatu layanan dapat gagal. Jika kita mengatur Ambang Batas Persen kita menjadi lebih dari 50%, maka sirkuit tidak akan terbuka, dan kita akan melihat 50% dari permintaan kita gagal. Atau, jika kita menetapkan Kesalahan Persen Ambang Batas menjadi kurang dari 50%, sirkuit akan terbuka dan semua pintasan permintaan ke pemrosesan mundur atau gagal. Namun, untuk mencapai ini, layanan kami harus mengetahui jumlah dan identitas hulu tuan rumah. Pada contoh sebelumnya, hanya menyadari keberadaan penyeimbang beban. Untuk dapat melakukan penyeimbangan beban sisi klien, layanan kami harus melacak keberadaan dan kesehatan semua host di layanan hulu kami dan menyeimbangkan permintaan di seluruh tuan rumah. Di Grab, banyak layanan berbasis gRPC kami dikonfigurasikan dengan cara ini. Dalam contoh ini, sepertinya tidak banyak, tetapi karena kami mengadopsi layanan hulu tambahan dan jumlah host hulu ini bertambah, biayanya berlipat ganda. Dengan konfigurasi baru kami, kami telah mengalami beberapa kompleksitas tambahan, yang berkaitan dengan penyeimbangan beban sisi klien, dan kami juga telah beralih dari 1 sirkuit ke 6. Sirkuit tambahan 5 ini juga menimbulkan sejumlah biaya sumber daya.Jika penyeimbang beban dalam contoh per layanan kami dikonfigurasikan untuk memantau kesehatan layanan yang berjalan pada setiap host, maka ia dapat mendeteksi dan menghapus host tersebut dari penyeimbang beban dan berpotensi menggantinya dengan host baru. Selain itu, kami juga harus mempertimbangkan respons apa yang mungkin dimiliki per penyeimbang beban layanan kami ketika tuan rumah yang buruk gagal. Jadi kami telah melihat mekanisme umum pertama yang digunakan dalam merancang keandalan, yaitu Pemutus Sirkuit. Saya harap Anda menikmati posting ini dan bermanfaat. Komentar, koreksi, dan bahkan ketidaksepakatan yang dianggap selalu diterima. Dalam posting berikutnya, kami akan melihat mekanisme keandalan layanan lainnya yang menjadi sorotan, yaitu Retries. Kita akan melihat cara kerjanya, cara mengkonfigurasinya, dan menangani beberapa implementasi dengan backoff dan jitter. Kami juga akan membahas kapan kami harus menggunakan pemutus sirkuit versus coba lagi, atau bahkan kombinasi keduanya. (source)