Nginx состоит из модулей и именно они выполняют всю реальную работу. Стандартные модули позволяют решить большинство задач, но наступает момент, когда необходимо  осуществить какие-то нетипичные действия и тогда мы либо берем сторонний модуль, либо пишем свой собственный.  При этом, даже если модуль давно написан и имеет хорошие отзывы, нет никакой гарантии, что его работа не вызовет проблем, причем, возможно, исключительно в нашей конфигурации или сборке. А Nginx, как известно, рождён для производительности, и, добавляя модули, мы не хотим этой производительности потерять. Поэтому каждая новая сборка должна завершаться отладкой и профилированием.  В недавней статье мы сняли верхний слой грунта, но чтобы локализовать возможную проблему нам придётся копать намного глубже. В самом Nginx есть режим отладки, и он действительно помогает выявлять проблемы, но в качестве профилировщика не годится, так как сам вносит приличную задержку. Поэтому нам потребуется сторонний инструмент и тут, как нельзя лучше, подойдёт dtrace. Вообще, настоящие экскаваторщики готовят dtrace вот так. Но этот подход, из-за тьмы перекрестных зависимостей, требует либо включения множества файлов заголовков, либо ручного определения структур и типов. Мы, простые чернорабочие, поступаем проще. Для начала попросим Nginx работать с одним рабочим процессом и создадим простейшую конфигурацию: Посмотрим какой путь проходит наш запрос, создав сценарий на языке D (который не стоит путать с языком D). Для этого воспользуемся опцией flowindent, чтобы построить дерево вызовов. Исполнив сценарий, мы получим симпатичное дерево иллюстрирующее путь нашего запроса. Так как данная конфигурация не подразумевает никаких перенаправлений, мы рассчитываем, что запрос прошел именно тот простейший путь, который определен фазами Nginx. Убедимся в этом: Фаз обработки запроса 11, а здесь отобразилось 10 этапов. В этом нет никакой ошибки, так как мы закончили трассировку на этапе завершения запроса, а логирование произойдет только после закрытия соединения, то есть ещё исполнятся ngx_http_finalize_connection, ngx_http_free_request и только потом начнется этап записи в лог. Соотнесем наши результаты со списком фаз: 1 NGX_HTTP_POST_READ_PHASE ngx_http_core_generic_phase 2 NGX_HTTP_SERVER_REWRITE_PHASE  ngx_http_core_rewrite_phase 3 NGX_HTTP_FIND_CONFIG_PHASE ngx_http_core_find_config_phase 4 NGX_HTTP_REWRITE_PHASE ngx_http_core_rewrite_phase 5 NGX_HTTP_POST_REWRITE_PHASE ngx_http_core_post_rewrite_phase 6 NGX_HTTP_PREACCESS_PHASE  ngx_http_core_generic_phase 7 NGX_HTTP_ACCESS_PHASE ngx_http_core_access_phase 8 NGX_HTTP_POST_ACCESS_PHASE ngx_http_core_post_access_phase 9 NGX_HTTP_PRECONTENT_PHASE ngx_http_core_generic_phase 10 NGX_HTTP_CONTENT_PHASE ngx_http_core_content_phase 11 NGX_HTTP_LOG_PHASE ngx_http_core_generic_phase Так как обычно модуль работает в какой-то одной фазе, то её пробу нам и нужно делать. Для примера возьмем NGX_HTTP_POST_ACCESS_PHASE и посмотрим сколько времени занимает её обработка: Этот же подход можно применять ещё более точечно, например, копаясь в фильтрах тела запроса. Попробуем сделать практический анализ эффективности двух различных модулей, решающих одну и ту же задачу, для этого в качестве index.html используем страничку rfc2822, и соберем Nginx c поддержкой родного http_sub_module и стороннего ngx_http_substitutions_filter_module. Соответственно, для теста мы имеем две конфигурации: И два сценария dtrace: Не будем доверять штучному тесту и выполним миллион запросов, собрав значения в агрегирующую функцию: С одной стороны, преимущество в 2.6 раза, с другой - разница в 400 микросекунд не так уж и критична. Но по крайней мере без использования regex, использование стороннего модуля не даёт преимуществ. Бытует мнение, что с веток 1.9+ sub_filter существенно ускорился. Ради интереса я откатился до более ранних версий 1.8.1: 1.6.3: но на этих простых задачах ускорения не заметил. Подводя итоги. На самом деле, хотя OpenResty и не упоминается в статье, всё вышесказанное было написано с целью ответа на комментарий к предыдущей публикации. Я не ответил на него прямо, так как это потребовало бы подтверждений, которых у меня сейчас нет, но не ответить совсем не мог, поэтому хотя бы показал тот путь, который привел меня к отказу, если не от OpenResty вообще, то, по крайней мере, к использованию его с крайней осторожностью и после тщательного тестирования, как, впрочем, и любой другой сборки или модуля.