OpenResty FAQ | Как OpenResty используется на практике
API7.ai
February 10, 2023
- Некоторые вопросы и ответы о OpenResty, API Gateway и Lua
- Часто задаваемые вопросы по OpenResty | Привилегии процессов, фазы выполнения и многое другое
- Часто задаваемые вопросы по OpenResty | Сетевая структура для тестирования, функции, связанные с SSL, DSL, инструмент ab
- Часто задаваемые вопросы по 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, чтобы получить абсолютный путь.
Наконец, вы можете продолжать оставлять свои вопросы в разделе комментариев, и я продолжу отвечать на них. Я надеюсь, что через общение и вопросы и ответы я смогу помочь вам превратить то, что вы изучаете, в то, что вы получаете. Вы также можете поделиться этой статьей, чтобы мы могли общаться и улучшаться вместе.