У меня есть процесс, работающий на компьютере с Linux как часть системы высокой доступности. Процесс имеет основной поток, который получает запросы от других компьютеров в сети и отвечает на них. Существует также поток пульса, который периодически отправляет многоадресные пакеты пульса, чтобы другие процессы в сети знали, что этот процесс все еще жив и доступен. они решат, что этот процесс умер, и возьмут на себя его обязанности, чтобы система в целом могла продолжать работать.
Все это работает довольно хорошо, но на днях вся система вышла из строя, и когда я исследовал, почему я обнаружил следующее:
- Из-за (что, по-видимому) ошибки в ядре Linux коробки, произошло «упс» ядра, вызванное системным вызовом, который сделал основной поток этого процесса.
- Из-за ошибки ядра системный вызов так и не вернулся, в результате чего основной поток процесса навсегда завис.
- Поток сердцебиения, OTOH, продолжал работать правильно, а это означало, что другие узлы в сети так и не поняли, что этот узел вышел из строя, и ни один из них не вмешался, чтобы взять на себя его обязанности... и поэтому запрошенные задачи не были выполнены. и работа системы фактически остановилась.
Мой вопрос: есть ли элегантное решение, которое может справиться с таким сбоем? (Очевидно, что нужно исправить ядро Linux, чтобы оно не «упс», но, учитывая сложность ядра Linux, было бы неплохо, если бы мое программное обеспечение могло более изящно обрабатывать будущие другие ошибки ядра).
Одним из решений, которое мне не нравится, было бы помещать генератор сердцебиения в основной поток, а не запускать его как отдельный поток, или как-то иначе привязывать его к основному потоку, чтобы, если основной поток зависнет на неопределенное время, сердцебиения не будут отправлены. Причина, по которой мне не нравится это решение, заключается в том, что основной поток не является потоком реального времени, и, таким образом, это приведет к возможности случайных ложных срабатываний, когда операция с медленным завершением ошибочно принимается за сбой узла. Я хотел бы избежать ложных срабатываний, если я могу.
В идеале должен быть какой-то способ гарантировать, что неудачный системный вызов либо вернет код ошибки, либо, если это невозможно, приведет к сбою моего процесса; любой из них остановит генерацию пакетов пульса и позволит продолжить аварийное переключение. Есть ли способ сделать это, или ненадежное ядро также обрекает мой пользовательский процесс на ненадежность?