Fail Fast

15 July 2009 scalability messaging
$data = file_get_contents($location);

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

Хорошо, предположим, что у вас есть 3 web frontend’а, каждый из которых может обслуживать 60 параллельных запросов (итого 180 конкурентных запросов). На минутку предположим, что вышеприведенный код — это единственный код, который выполняется при обработке запроса. Если location указывает на локальный ресурс (на локальной файловой системе), то вряд ли что-то может пойти не так. Latency чтения с локальной файловой системы достаточно низкий для того, чтобы не беспокоится о возможных проблемах (если файлы достаточно маленькие).

А что если location указывает на удаленный ресурс? Например, на какой-нибудь ресурс доступный по протоколу HTTP. Предположим, что ресурс недоступен. Как поведет себя ваше приложение?

В лучшем случае, вы моментально получите управление назад, сможете определить ошибочную ситуацию и каким-либо образом восстановить поток исполнения. Но так бывает далеко не всегда. В случае если недоступна физический машина (а не приложение на этой машине), или если на сервере некорректно настроен firewall, то вы не получите управление назад. Клиент отсылает TCP SYN запрос и… тишина. Некому вам сказать, что ресурс недоступен, и все что вам остается — это ждать.

Возможно у вас возник вопрос: “А как это меня касается? Я же не могу оживить удаленный ресурс”. Два момента.

Во-первых, пользователи не любят ждать. Особенно они не любят когда после ожидания им говорят: “извините, мы не смогли обработать ваш запрос”. Зачем было ждать ЭТО? Во-вторых, путем довольно нехитрых расчетов можно вычислить, что если скорость поступления запросов равна 30 запросам в секунду, а запрос обрабатывается дольше 6 секунд, то при 180 обработчиках у вас переполнится очередь входящий запросов и вы перестанете отвечать на эти самые запросы. А пользователи, как известно, не любят ждать. Числа, может быть и ничего не говорящие, но смысл в том, что они конечны, а следственно конечен и тот timeout превышение которого для вас может закончится отказом в обслуживании для всех новых запросов.

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

Поэтому реализуя системы которые имеют синхронные зависимости от 3rd party ресурсов необходимо соблюдать ряд правил:

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