Статьи

Простое тестирование может предотвратить большинство критических сбоев

Обработка ошибок — одна из самых сложных и игнорируемых частей разработки программного обеспечения, и если система распространяется, то это становится еще сложнее.

Хорошая статья написана на тему « Простое тестирование может предотвратить большинство критических ошибок» .

Обработка ошибок

Каждый разработчик должен прочитать эту статью. Я постараюсь обобщить ключевые выводы из этой статьи, но предложу прочитать статью, чтобы узнать о ней больше.

Распределенная система простоя является распространенным явлением, и некоторые из недавних примеров

Youtube был закрыт в октябре 2018 года около 1 часа

Амазонка не работала в премьерный день июля 2018 года

Сервисы Google, такие как Map, Gmail, Youtube, не работали в 2018 году

Facebook также был в стороне от многих проблем утечки данных, с которыми они сталкиваются.

В этой статье рассказывается о катастрофическом сбое в распределенных системах, таких как Cassandra, Hbase, HDFS, Redis, Map Reduce.

Согласно статье, большинство ошибок связано с двумя причинами.

— сбой происходит из-за сложной последовательности событий

— Катастрофическая ошибка из-за неправильного обращения

— Я включу 3-й по «игнорированию проектного давления», который я написал в посте « дизайнерское давление на инженера»

Пример из отключения HBase

1 — Балансировщик нагрузки Передача области R из подчиненного устройства в подчиненное

2 — Раб B, открытый регион R

3 — Мастер удаляет текущий регион Zookeeper R после того, как он принадлежит Slave B

4 — Раб B умирает

5 — Регион R назначен подчиненному C и подчиненному C, откройте регион

6 — Master пытается удалить Slave B znode на Zookeeper и потому, что Slave b не работает и весь кластер выходит из строя из-за неправильного кода обработки ошибок.

В приведенном выше примере последовательность событий имеет значение для воспроизведения вопроса.

Сбой HDFS, когда блок не реплицируется.

Обработка ошибок

В этом примере также последовательность событий, и когда запускается новый узел данных, это выявляет ошибку системы.

У бумаги есть еще много примеров.

Основная причина ошибки

92% катастрофической ошибки происходит из-за неправильной обработки ошибок.

Это означает, что ошибка была вычтена, но код обработки ошибок не был хорош, похоже ли это на большой проект, над которым вы работали!

1 — ошибки игнорируются
Это является причиной 25% сбоев, я думаю, что число будет много во многих живых системах.

1
2
3
4
eg of such error
catch(RebootException e) {
log.info("Reboot occurred....")
}

Да, этот безвредный вид записи оператора игнорирует исключение и является очень распространенным анти-шаблоном обработки ошибок.

2 — исключение превышения
Это также очень распространено, например, общий блок захвата и разрушение всей системы.

1
2
3
catch(Throwable e) {
cluster.abort()
}

3 — TODO / FIXME в комментариях
Да, настоящая распределенная система в производстве также имеет много TODO / FIXME в критической части кода.

Некоторый другой пример обработки ошибок

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<i>} catch (IOException e) {</i>
 
<i> // will never happen </i>
 
<i> }</i>
 
<i>} catch (NoTransitionException e) {</i>
 
<i> /* Why this can happen? Ask God not me. */ </i>
 
<i> }</i>
 
<i>try { tableLock.release(); } </i>
 
<i>catch (IOException e) { </i>
 
<i> LOG("Can't release lock”, e); </i>
 
<i>} </i>

4 — Приоритет развития функции
Я думаю, что все разработчики программного обеспечения согласятся с этим. Это также называется Tech Debt, и я не могу представить себе лучшего примера, чем банкротство Knight Capital, которое было связано с конфигурацией и экспериментальным кодом.

Вывод

Все ошибки сложно воспроизвести, но лучший модульный тест определенно их поймает, это также показывает, что модульный / интеграционный тест, выполненный во многих системах, не является сценарием тестирования, таким как отключение и возвращение сервиса и его влияние на систему.

Исходя из приведенного выше примера, будет выглядеть, как будто все ошибки произошли из-за исключительной ситуации с проверкой Java, но она не отличается в другой системе, такой как C / C ++, которая не проверяла, но все не проверено, и ответственность за ее проверку в различных местах лежит на разработчику.

На языке примечаний без системы типов, такой как Python, очень легко писать код, который будет ломаться во время выполнения, и если вам действительно не повезет, то в коде обработки ошибок будет какая-то ошибка типа, и он будет протестирован в производстве.

Кроме того, почти все продукты будут иметь некоторую интеграцию с инструментами статического кода (findbugs), но эти инструменты не придают большего значения такому анти-шаблону обработки ошибок.

Ссылка на проблемы, упомянутые в статье

HDFS

Уменьшение карты

HBase

Redis

Cassandra

Пожалуйста, расскажите о большем количестве анти-паттернов, которые вы видели в производственной системе.

До тех пор Счастливое юнит-тестирование.

Посмотрите оригинальную статью здесь: Простое тестирование может предотвратить большинство критических ошибок

Мнения, высказанные участниками Java Code Geeks, являются их собственными.