OpenResty FAQ | Как OpenResty используется на практике

API7.ai

February 10, 2023

OpenResty (NGINX + Lua)

  1. Некоторые вопросы и ответы о OpenResty, API Gateway и Lua
  2. Часто задаваемые вопросы по OpenResty | Привилегии процессов, фазы выполнения и многое другое
  3. Часто задаваемые вопросы по OpenResty | Сетевая структура для тестирования, функции, связанные с SSL, DSL, инструмент ab
  4. Часто задаваемые вопросы по OpenResty | Динамическая загрузка, NYI и кэширование Shared Dict

На данный момент мы завершили последний раздел курса по OpenResty и микросервисным API-шлюзам. Поздравляю вас с тем, что вы не отстаете, активно учитесь и практикуетесь, а также с энтузиазмом оставляете свои мысли.

Я выбрал несколько типичных и интересных вопросов, чтобы поделиться с вами. Давайте рассмотрим эти 5 вопросов сегодня.

Вопрос 1: Как OpenResty используется на практике

Описание: Курс почти завершен, и я в основном понимаю материал, но моя собственная практика пока что слабая (в настоящее время не используется в моей работе). Однако это очень полезная серия статей. Спасибо автору за продолжение публикаций, и я позже внедрю это в своей работе.

Я хотел бы поговорить о внедрении OpenResty на работе, это тема, заслуживающая обсуждения.

OpenResty основан на NGINX и добавляет модуль lua-nginx-module и множество библиотек lua-resty, поэтому OpenResty является хорошей альтернативой для NGINX, что является самым простым способом начать использовать OpenResty. Конечно, в процессе замены существуют риски, поэтому нужно учитывать следующие три момента.

Во-первых, убедитесь, что версия NGINX в продакшене совпадает с основной версией OpenResty, например, OpenResty 1.15.8.1 использует NGINX 1.15.8. Если текущая версия NGINX в продакшене выше, чем последняя версия OpenResty, нужно быть осторожным при переходе на OpenResty. В конце концов, OpenResty обновляется медленно и отстает от основной версии NGINX на шесть месяцев или год. Если версия NGINX в продакшене совпадает или ниже, чем у OpenResty, то у вас есть предпосылки для обновления.

Во-вторых, тестирование. Тестирование — это один из самых важных аспектов. Использование OpenResty для замены NGINX несет мало рисков, но они все же существуют. Например, есть ли пользовательские C-модули, которые нужно компилировать, версия openssl, от которой зависит OpenResty, и повлияют ли патчи, которые OpenResty накладывает на NGINX, на бизнес. Вам нужно будет воспроизвести часть бизнес-трафика, чтобы проверить это.

В-третьих, переключение трафика. После прохождения базовой проверки вам все равно нужно будет проверить канареечный релиз реального трафика в продакшене. Чтобы быстро откатиться, мы можем развернуть несколько новых серверов с OpenResty вместо того, чтобы сразу заменять оригинальный сервис NGINX. Если проблем не возникнет, мы можем либо выполнить горячее обновление бинарного файла, либо постепенно удалить и заменить NGINX из LB для обновления.

Помимо замены NGINX, OpenResty имеет еще две точки входа: WAF и API-шлюзы. Оба этих сценария требуют высокой производительности и динамичности, и для них существуют соответствующие открытые проекты, которые можно использовать "из коробки", о чем я рассказывал ранее.

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

Обычно хорошей идеей является начать с замены NGINX, а затем постепенно расширять использование OpenResty.

Вопрос 2: Инкапсуляция базы данных для OpenResty

Описание: Согласно предыдущей статье, мы должны использовать оператор конкатенации строк .. как можно меньше, особенно в горячем пути кода. Но при работе с доступом к базе данных мне нужно динамически строить SQL-запросы, вставляя переменные в запросы, что должно быть распространенным сценарием использования. Но для этого требования я чувствую, что конкатенация строк — это самый простой способ, и я не могу придумать другого простого и высокопроизводительного способа.

Сначала вы можете проанализировать это с помощью SystemTap или других инструментов, которые мы представили в предыдущих статьях, чтобы понять, является ли конкатенация SQL-запросов узким местом системы. Если это не так, то оптимизировать не нужно. В конце концов, преждевременная оптимизация — корень всех зол.

Если узким местом действительно является конкатенация SQL-запросов, то мы можем использовать prepare-запросы базы данных для оптимизации или массив для конкатенации. Но поддержка prepare в lua-resty-mysql находится в статусе TODO, поэтому мы можем использовать только конкатенацию массивов. Это также распространенная проблема с некоторыми библиотеками lua-resty, которые реализуют большую часть функциональности и работают нормально, но не обновляются вовремя. Помимо prepare-запросов базы данных, lua-resty-redis не поддерживает cluster.

Конкатенация строк и библиотеки lua-resty — это те проблемы, которые OpenResty хочет полностью решить с помощью DSL — используя технологию компиляторов для автоматической генерации массивов для конкатенации строк, скрывая эти детали от пользователей верхнего уровня; используя DSL wirelang для автоматической генерации различных библиотек сетевой коммуникации lua-resty, устраняя необходимость ручного написания.

Звучит замечательно, не так ли? Но мы должны столкнуться с проблемой: автоматически сгенерированный код недружелюбен к разработчикам. Если вы хотите изучить или изменить сгенерированный код, вам придется изучить технологию компиляторов и DSL, который может быть не открыт, что делает барьер для участия в сообществе все выше и выше.

Вопрос 3: Веб-фреймворк для OpenResty

Описание: Я хочу создать веб-проект с использованием OpenResty, но это болезненно, главным образом потому, что я не могу найти зрелый фреймворк, и мне нужно создавать множество велосипедов. Например, проблема с операциями с базой данных. Я не нашел библиотеку, которая могла бы динамически строить SQL-запросы и выполнять последовательные операции. Поэтому я хотел бы спросить автора, можете ли вы порекомендовать хороший веб-фреймворк?

В репозитории awesome-resty мы видим, что есть специальная категория для веб-фреймворков, там есть 20 открытых проектов, но большинство из них застопорились. Среди них Lapis, lor и vanilla — это три проекта, которые вы можете попробовать, чтобы понять, какой из них больше подходит.

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

Вопрос 4: Как изменить content-length в заголовке ответа после изменения тела ответа?

Описание: Если мне нужно изменить содержимое тела ответа, я могу вносить изменения только в фазе фильтрации тела, но это приведет к несоответствию длины тела и длины content-length. Как мне с этим справиться?

В этом случае нам нужно установить заголовок content-length в nil в фазе фильтрации заголовков перед фазой фильтрации тела и не возвращать его, а вместо этого передавать вывод потоком.

Вот пример кода:

server { listen 8080; location /test { proxy_pass http://api7.ai; header_filter_by_lua_block { ngx.header.content_length = nil } body_filter_by_lua_block { ngx.arg[1] = ngx.arg[1] .. "abc" } } }

Как видно из этого кода, в фазе фильтрации тела ngx.arg[1] представляет тело ответа. Если мы добавим строку abc после него, заголовок content-length будет неточным, поэтому мы можем отключить его в фазе фильтрации заголовков.

Также этот пример показывает, как различные фазы OpenResty работают вместе, что, я надеюсь, вы заметите и обдумаете.

Вопрос 5: Пути к пакетам Lua в OpenResty

Описание: Кажется, что lua_package_path настроен как путь поиска для зависимостей Lua. Для content_by_lua_file я экспериментировал и обнаружил, что он ищет только в префиксе на основе относительного пути к файлу, указанного в директиве, а не в lua_package_path. Не знаю, правильно ли я понимаю.

lua_package_path используется для загрузки модулей Lua, например, когда мы вызываем require 'cjson', мы будем искать модуль cjson в каталоге, указанном в lua_package_path. В то время как content_by_lua_file следует за путем к файлу на диске.

location /test { content_by_lua_file /path/test.lua; }

Если это не абсолютный путь, а относительный.

content_by_lua_file path/test.lua;

Тогда будет выполнена конкатенация с использованием каталога -p, указанного при запуске OpenResty, чтобы получить абсолютный путь.

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