Обробка винятків у програмі, яку потрібно запустити 24/7


14

Я читав, що ми повинні виловлювати лише винятки, які можна обробити, що робить вилов базового класу винятків (C # в даному випадку) поганою ідеєю (крім інших причин). Зараз я є частиною проекту, в якому я поки що ще нічого не бачив, окрім базового винятку. Я згадував, що вважати це поганою практикою, але відповідь була "Цю службу потрібно працювати 24/7, тож саме так".

Оскільки у мене не було хорошої відповіді щодо того, як правильно поводитися з винятками в програмі, яка потребує запуску 24/7, я зараз тут. Мені не вдалося знайти будь-якої інформації / пропозицій, як боротися з обробкою виключень у "критичних" програмах / службах, які потрібно працювати цілодобово (і в цьому випадку я вважаю, що це може бути нормально, якщо послуга зникла на хвилину або два, так що навіть не критично). Я розумію, це залежить від конкретного характеру програми. Вимоги до програми, яка може спричинити загрозу життю, зовсім інші, порівняно зі сканером журналів для онлайн-ігор.

Два приклади:

1: Попередня послуга для клієнтів британських залізниць, яка використовується під час пошуку в мережі Інтернет залізничних станцій.

2: Програма, яка автоматично управляє залізничними комутаторами для вищезазначених залізниць на основі інформації в реальному часі, що надається різними датчиками в коліях, поїздах тощо.

Перша програма, ймовірно, не спричинила б серйозних проблем, якби вона знизилася на хвилину-дві, оскільки остання може спричинити людські жертви. Пропозиції, як поводитися з кожним? Вкажіть, де я можу знайти більше інформації та думок з цього питання?


2
Розмотування стека під час обробки винятків у додатку в реальному часі (sic!) Може зірвати поїзд.
Мисливець на оленів

4
@DeerHunter Погане кодування без винятку може мати той же результат.
BЈович

9
Гаразд, так ви catch Exception. Це не означає, що ваша програма працює , це означає, що збої дозволяють пошкодити стан програми, поки вона продовжує виконуватись, набагато небезпечніше місце. Збита програма може бути згубною, але програма, яка знаходиться в недійсному стані, але все ще виконує дії, може бути активно згубною.
Фоші

1
Якщо програмі потрібно запустити цілодобово, десь нескінченний цикл, і цей нескінченний цикл краще обернути навколо якоїсь конструкції, яка фіксує всі незроблені винятки. Якщо це не так, незроблений виняток буде пов'язаний з уже існуючим обробником загальної інформації, який знаходиться поза основним, і kaboom! заява 24/7 припиняється.
Девід Хаммен

Відповіді:


7

Певні мовні функції, як-от

  • Збір сміття
  • Системи виключень
  • Ледача оцінка

загалом не є корисними в системі реального часу. Напевно, слід вибрати мову без цих функцій і намагатися довести певні властивості, наприклад, максимальне використання пам'яті або максимальний час відгуку.


Коли програмі потрібно запускатись постійно, але короткі та не глобальні збої є прийнятними, тоді ми можемо використовувати стратегію, схожу на Ерланг. Erlang - це паралельна функціональна мова програмування. Зазвичай програма, написана на Erlang, буде складатися з декількох робочих процесів, які можуть спілкуватися один з одним (модель актора). Якщо один робочий потік стикається з винятком, його повторно запускають. Хоча це означає короткий час простою, інші учасники можуть тривати як завжди.

Підсумовуючи це: У надійній програмі різні частини ізольовані одна від одної і можуть бути перезапущені або масштабовані незалежно.

Тому в основному нам потрібен фрагмент коду, еквівалентний цьому:

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

плюс спосіб припинення циклу. Тоді така петля запускає кожну робочу нитку.


Проблема з ігноруванням помилок через загальну інформацію полягає в тому, що інваріанти вашої програми можуть бути порушені причиною помилки, і що наступні операції можуть бути марними. Хорошим рішенням цього є обмін даними між незалежними працівниками. Перезапуск робітника відновить усіх необхідних інваріантів. Це означає, що вони повинні спілкуватися по-різному, наприклад, через надсилання повідомлень. Стан актора може не входити до інваріантів інших акторів.

Ще одна проблема із вилученням занадто великої кількості винятків полягає в тому, що не всі винятки можна виправити за допомогою перезавантаження, навіть якщо вживати таких запобіжних заходів. В іншому випадку важкі проблеми, такі як втрата пам'яті, можуть бути вирішені шляхом перезавантаження. Але перезапуск не допоможе вам відновити підключення до Інтернету, коли фізичний кабель був витягнутий.


1
Так, але ситуація на зразок "фізичного кабелю витягнута" - це саме тоді, коли ви просто хочете заповнити журнал винятків, поки хтось не введе кабель назад, і тоді справи почнуть працювати знову, з подальшим ручним перезапуском програми.
Марк Херд

2

Щоб відповісти на ваше запитання, треба зрозуміти, що таке винятки та як вони працюють.

Виключення, як правило, викидаються, коли виникають такі помилки, коли потрібна допомога користувача. У таких випадках не має значення, скільки часу потрібно, щоб розмотати стек і обробити виняток.

Без обробників улову програма зупиняє виконання. Залежно від налаштувань та вимог, це може бути прийнятним.

У конкретних випадках:

  1. якщо запит неможливо виконати (наприклад, неправильна назва міста), повідомте про помилку користувача та попросіть його виправити.
  2. якщо ви не отримуєте інформацію від критичного датчика, не має великого сенсу продовжувати, не вимагаючи від оператора виправити проблему.

Це означає, що в обох випадках може бути доцільним використовувати винятки, з більшою обережністю в програмі RT вказувати лише на серйозні проблеми, коли неможливо продовжити виконання.


1

Я поки що ще нічого не бачив, окрім базового виключення.

Здається, тут є проблема, оскільки винятки не розглядаються належним чином. Ловлячи винятки у відповідній точці та вживаючи відповідних дій (залежно від типу винятку), буде тримати послугу набагато надійніше.

Якщо сервіс повинен тривати, мабуть, важливо, щоб він працював за призначенням. З огляду на ваш приклад, якщо програма, яка контролює залізничні переїзди, викидає виняток, це може вказувати на наявність проблеми в спілкуванні з датчиками безпеки. Якщо ви переймаєте базовий виняток і продовжуєте службу, можливо, вона запускається, але може не функціонувати так, як передбачалося, призводить до катастрофи.

Крім того, якщо ви потрапили на виняток, кинутий, коли є датчик зв'язку з датчиком, і справляєтесь з ним належним чином (тобто зупиняйте поїзди в районі, що постраждав), ваша служба працює, і ви нікого не вбили.

Тож, як я розумію питання, я б припустив, що в першу чергу вам буде краще додати більш конкретні обробки винятків, а не видаляти обробники базових винятків.


0

Що стосується пункту 2: не використовуйте C #. Це не мова в реальному часі , і ви будете отримувати боляче , якщо ви намагаєтеся використовувати його в якості такого.

Для пункту 1: ви можете піти помилковим шляхом: нехай він вийде з ладу, потім перезапустіть


Моє використання та досвід C # не стосується точки 2 (перемикання треку в режимі реального часу). Мені цікаво, чому C # настільки непридатний для такого завдання?
Майкл О'Нілл

1
Переважно: сміттєзбірник робить поведінку програми, що стосується часу, непередбачуваною. Крім того, час виконання занадто складний, і в цих контекстах вам потрібні прості речі, вони більш передбачувані
miniBill

0

Заявник: це лише думки, у мене немає досвіду.

Я б здогадався, що програма, що відповідає вимогам другого прикладу, повинна бути надзвичайно модульною . Отже, модулі можуть бути перезапущені без дестабілізації системи.

Наприклад, об'єкт, який не може стверджувати про внутрішній стан, повинен бути здатний бути знищений і відтворений, повідомляючи в процесі всіх своїх споживачів і постачальників. Більш конкретно, якщо програма керує комутаторами залізниці і не спрацьовує в циклі прийняття рішень, вона все одно може запустити аварійний модуль, який зупиняє всі задіяні поїзди, і чекає, коли основний модуль рішення повторно ініціалізується.

Більш реально, можна було б запровадити надмірність - дублювання апаратного та програмного забезпечення. Один екземпляр підключений до керованої системи, а другий - вільний. Якщо виявлена ​​помилка, системи перемикаються.

Прикладом можуть слугувати два процеси на одній машині, які відстежують один одного, і якщо одного вбивають, інший повторно породжує його та від'єднує батьківський PID від себе.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.