OpenResty — это не «Nginx с плагинами», а способ писать серверную логику на Lua прямо в конфиге

public

Автор: Владимир Протасов · Habr


Владимир Протасов — разработчик с опытом highload-систем, выступал на HighLoad++ 2016 с докладом об OpenResty. Доклад из тех, что не устаревают: OpenResty существует с 2009 года, но основная масса разработчиков по-прежнему думает о нём как о «Nginx с Lua» и недооценивает, что именно это означает.

OpenResty встраивает LuaJIT прямо в worker-процессы Nginx и даёт хуки на каждую фазу обработки запроса: до получения заголовков, после, перед отправкой ответа, при ошибке. Это не «скрипт, вызываемый Nginx» — это Lua, исполняемый с той же производительностью, что и сам Nginx, без форков, без HTTP-запросов к отдельному backend, без копирования тела запроса туда-обратно. Авторизация, rate limiting, трансформация ответов, маршрутизация на основе тела запроса — всё это можно делать без выхода из nginx-контекста.

Протасов разбирает конкретные паттерны: как подключить Redis через cosocket API (без блокировки event loop), как кешировать сессии, как писать обработчики для нестандартных протоколов. Это не «hello world на Lua в nginx», а production-архитектура.

Кому смотреть: backend-разработчикам, которые используют Nginx как reverse proxy и хотят перенести часть логики (auth, rate limiting, A/B-роутинг) ближе к трафику, не добавляя отдельный сервис.

Из этого можно взять в работу: если у тебя есть endpoint, который только проверяет token и проксирует запрос дальше — попробуй вынести проверку на уровень OpenResty. Latency упадёт, а отдельный auth-сервис в цепочке исчезнет.

OpenResty — это дистрибутив Nginx, который включает LuaJIT, набор Lua-библиотек (lua-resty-*) и механизм встраивания Lua в фазы обработки запроса. Фазы: init, rewrite, access, content, header_filter, body_filter, log. Каждая — хук, в котором можно выполнить произвольный Lua-код.

Ключевое отличие от nginx.conf с if-директивами: Lua в OpenResty — полноценный язык с библиотеками, паттернами, таблицами и доступом к API Nginx. Можно делать HTTP-субзапросы внутри воркера, читать тело запроса, менять заголовки ответа, писать в разделяемую память между воркерами.

Cosocket API — механизм неблокирующего ввода-вывода в Lua. Когда Lua-код делает запрос в Redis или PostgreSQL, Nginx event loop не блокируется — он обрабатывает другие соединения. Это позволяет писать синхронный по виду код (без callback hell), который работает асинхронно. lua-resty-redis, lua-resty-mysql, lua-resty-http — всё это реализации поверх cosocket.

Shared memory: ngx.shared.DICT позволяет хранить данные между Lua-воркерами без Redis. Для rate limiting, счётчиков сессий, небольших кешей — достаточно, и без сетевых задержек.

Протасов показывает архитектуру реального проекта: OpenResty как API-gateway, который делает auth через Redis, кеширует ответы, трансформирует XML в JSON и логирует в Kafka — всё без отдельных сервисов в цепочке. Не академический пример — такая конфигурация работает под highload.