Penanganan pengecualian dalam program yang perlu dijalankan 24/7

14

Saya telah membaca bahwa kita seharusnya hanya menangkap pengecualian yang dapat ditangani, yang menjadikan menangkap kelas pengecualian dasar (C # dalam kasus ini) merupakan ide yang buruk (di atas alasan lain). Saat ini saya bagian dari proyek di mana saya sejauh ini belum melihat apa pun kecuali pengecualian dasar yang tertangkap. Saya menyebutkan bahwa itu dianggap praktik buruk untuk melakukannya, tetapi jawabannya adalah "Layanan ini perlu dijalankan 24/7, jadi memang begitu adanya.".

Karena saya tidak memiliki respons yang baik untuk bagaimana menangani dengan benar pengecualian dalam suatu program yang perlu dijalankan 24/7, saya sekarang di sini. Saya belum berhasil menemukan informasi / saran tentang cara menangani penanganan pengecualian dalam program / layanan "kritis" yang perlu dijalankan sepanjang waktu (dan dalam hal ini saya percaya mungkin ok jika layanan turun sebentar) atau dua, jadi bahkan tidak kritis). Saya mengerti itu tergantung pada sifat program. Persyaratan untuk sebuah program yang dapat menyebabkan masalah yang mengancam jiwa sangat berbeda dibandingkan dengan pemindai log untuk game online.

Dua contoh:

1: Layanan tipe-depan untuk pelanggan kereta api Brittish, digunakan ketika mereka mencari stasiun kereta api online.

2: Suatu program yang secara otomatis mengontrol sakelar kereta api untuk perkeretaapian di atas berdasarkan informasi waktu nyata yang disediakan dari berbagai sensor di rel, kereta api dll

Program pertama mungkin tidak akan menyebabkan masalah besar jika turun selama satu atau dua menit, sementara yang terakhir dapat menyebabkan korban manusia. Saran tentang cara menangani masing-masing? Menunjuk ke mana saya dapat menemukan lebih banyak informasi dan pemikiran tentang masalah ini?

pengguna1323245
sumber
2
Stack unwinding selama penanganan pengecualian dalam aplikasi waktu nyata (sic!) Dapat merusak kereta.
Pemburu Rusa
4
@DeerHunter Pengodean yang buruk tanpa pengecualian, dapat memiliki hasil yang sama.
BЈовић
9
Oke, jadi kamu catch Exception. Itu tidak berarti program Anda berfungsi , itu berarti bahwa kegagalan membiarkan keadaan aplikasi rusak sementara terus dijalankan, tempat yang jauh lebih berbahaya. Program yang mogok mungkin menjadi bencana, tetapi program yang dalam kondisi tidak valid tetapi masih melakukan tindakan dapat menjadi bencana yang aktif .
Phoshi
1
Jika aplikasi perlu dijalankan 24/7 ada loop tak terbatas di suatu tempat dan loop tak terbatas ini sebaiknya dibungkus dengan beberapa konstruksi yang menangkap semua pengecualian yang tidak tertangani. Jika bukan itu masalahnya, pengecualian yang tidak ditangani akan meresap ke handler semua yang sudah ada yang berada di luar main, dan kaboom! aplikasi 24/7 berhenti.
David Hammen

Jawaban:

7

Fitur bahasa tertentu suka

  • Pengumpulan Sampah
  • Sistem Pengecualian
  • Evaluasi Malas

umumnya tidak berguna dalam sistem waktu nyata. Seseorang mungkin harus memilih bahasa tanpa fitur-fitur ini, dan mencoba untuk membuktikan sifat-sifat tertentu seperti penggunaan memori maksimum, atau waktu respons maksimum.


Ketika suatu program perlu berjalan terus-menerus, tetapi kegagalan yang pendek dan non-global dapat diterima, maka kita dapat menggunakan strategi seperti Erlang. Erlang adalah bahasa pemrograman fungsional bersamaan. Biasanya, sebuah program yang ditulis dalam bahasa Erlang akan terdiri dari beberapa proses pekerja yang dapat berkomunikasi satu sama lain (model aktor). Jika satu pekerja thread menemukan pengecualian, itu dimulai kembali. Meskipun ini menyiratkan downtime singkat, aktor-aktor lain dapat melanjutkan seperti biasa.

Untuk meringkas ini: Dalam program yang kuat, berbagai bagian diisolasi satu sama lain dan dapat dimulai kembali atau diskalakan secara independen.

Jadi pada dasarnya kita membutuhkan kode yang setara dengan ini:

while (true) {
  try {
    DoWork();
  }
  catch (Exception e) {
    log(e);
  }
}

plus cara untuk mengakhiri loop. Perulangan semacam itu akan mendorong setiap utas pekerja.


Masalah dengan mengabaikan kesalahan melalui catch-all adalah bahwa invarian program Anda mungkin telah dilanggar oleh penyebab kesalahan, dan bahwa operasi selanjutnya bisa sia-sia. Solusi yang baik untuk ini adalah tidak membagikan data antara pekerja independen. Restart pekerja akan membangun kembali semua invarian yang diperlukan. Ini berarti mereka harus berkomunikasi secara berbeda, misalnya melalui pengiriman pesan. Negara aktor mungkin bukan bagian dari invarian aktor lain.

Masalah lain dengan menangkap terlalu banyak pengecualian adalah bahwa tidak semua pengecualian dapat diperbaiki dengan memulai kembali, bahkan ketika mengambil tindakan pencegahan tersebut. Jika tidak, masalah yang sulit seperti kehabisan memori dapat ditangani dengan memulai kembali. Tetapi restart tidak akan membantu Anda untuk mendapatkan kembali konektivitas internet ketika kabel fisik ditarik.

amon
sumber
1
Ya, tetapi situasi seperti "kabel fisik ditarik keluar" adalah persis ketika Anda hanya ingin mengisi log pengecualian sampai seseorang memasukkan kembali kabel itu, maka semuanya mulai berfungsi lagi, tanpa perlu memulai kembali aplikasi secara manual.
Mark Hurd
2

Untuk menjawab pertanyaan Anda, orang harus memahami apa pengecualian itu, dan bagaimana mereka bekerja.

Pengecualian biasanya dilemparkan ketika kesalahan tersebut terjadi, di mana bantuan pengguna diperlukan. Dalam kasus seperti itu, tidak masalah berapa lama waktu yang dibutuhkan untuk melepas tumpukan dan menangani pengecualian.

Tanpa catch handler, program menghentikan eksekusi. Tergantung pada pengaturan dan persyaratan Anda, itu mungkin dapat diterima.

Dalam kasus spesifik Anda:

  1. jika kueri tidak dapat dieksekusi (misalnya, nama kota salah), maka beri tahu pengguna kesalahan, dan minta untuk memperbaikinya.
  2. jika Anda tidak mendapatkan informasi dari sensor kritis, tidak ada gunanya melanjutkan tanpa meminta operator untuk memperbaiki masalah.

Itu berarti bahwa dalam kedua kasus mungkin masuk akal untuk menggunakan pengecualian, dengan lebih hati-hati dalam program RT untuk menunjukkan hanya masalah serius di mana tidak mungkin untuk melanjutkan eksekusi.

BЈовић
sumber
1

Saya sejauh ini belum melihat apa pun kecuali pengecualian dasar ditangkap.

Sepertinya ada masalah di sini, sebanyak pengecualian tidak ditangani dengan tepat. Menangkap pengecualian pada titik yang tepat dan mengambil tindakan yang sesuai (tergantung pada jenis pengecualian) akan membuat layanan berjalan dengan cara yang jauh lebih andal.

Jika layanan harus dilanjutkan, mungkin penting bahwa ia berfungsi sebagaimana mestinya. Diberikan contoh Anda, jika sebuah program yang mengontrol sakelar kereta api mengeluarkan pengecualian, itu mungkin menunjukkan bahwa ada masalah berkomunikasi dengan sensor terkait keselamatan. Jika Anda menangkap pengecualian pangkalan dan melanjutkan layanan mungkin berjalan, tetapi mungkin tidak berfungsi sebagaimana dimaksud mengarah ke bencana.

Atau, jika Anda menangkap pengecualian yang dilemparkan ketika ada kegagalan komunikasi dengan sensor dan menanganinya dengan tepat (yaitu menghentikan kereta di daerah yang terkena) layanan Anda berjalan dan Anda belum membunuh siapa pun.

Jadi, seperti yang saya pahami pertanyaannya, saya akan menyarankan bahwa pada contoh pertama Anda akan lebih mencari untuk menambahkan penanganan pengecualian yang lebih spesifik daripada menghapus penangan tipe-basis-pengecualian.

Mat
sumber
0

Sehubungan dengan poin 2: jangan gunakan C #. Ini bukan bahasa waktu nyata dan Anda akan terluka jika Anda mencoba menggunakannya.

Untuk poin 1: Anda bisa menggunakan cara erlang: biarkan crash, lalu restart

miniBill
sumber
Penggunaan dan keahlian C # saya tidak ada di sekitar poin 2 (peralihan trek waktu nyata). Saya ingin tahu mengapa C # sangat tidak cocok untuk tugas seperti itu?
Michael O'Neill
1
Sebagian besar: pengumpul sampah membuat perilaku program, sehubungan dengan waktu, tidak dapat diprediksi. Juga, runtime terlalu kompleks, dan dalam konteks itu Anda memerlukan hal-hal sederhana, mereka lebih dapat diprediksi
miniBill
0

Declaimer: ini hanya pemikiran, saya tidak punya pengalaman.

Saya akan menebak bahwa suatu program, memenuhi persyaratan contoh kedua harus sangat modular . Akibatnya, modul akan dapat di-restart, tanpa mengganggu stabilitas sistem.

Misalnya, sebuah objek, yang gagal menegaskan keadaan internal, harus dapat dihancurkan dan diciptakan kembali, memberitahukan dalam proses semua konsumen dan pemasoknya. Lebih konkretnya, jika program mengendalikan sakelar kereta api dan gagal menegaskan dalam putaran keputusan, ia masih bisa menjalankan modul darurat, yang menghentikan semua kereta yang terlibat, dan menunggu modul keputusan utama untuk diinisialisasi ulang.

Lebih realistis, orang akan memperkenalkan redundansi - duplikasi perangkat keras dan perangkat lunak. Satu instance ditransfer ke sistem yang dikendalikan, dan yang lainnya berjalan bebas. Jika kesalahan terdeteksi, sistem akan beralih.

Contohnya adalah dua proses pada mesin yang sama, yang memonitor satu sama lain dan jika satu terbunuh, yang lain memunculkan kembali dan melepaskan PID induknya dari dirinya sendiri.

Vorac
sumber