---
title: "OpenResty FAQ | Как OpenResty используется на практике - API7.ai"
description: "В этой статье описывается, как OpenResty используется на практике, включая инкапсуляцию базы данных OpenResty, веб-фреймворк OpenResty и другие вопросы."
url: "https://api7.ai/ru/learning-center/openresty/faq-5"
---

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

API7.ai

February 10, 2023

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

> 1. [Некоторые вопросы и ответы о OpenResty, API Gateway и Lua](https://api7.ai/learning-center/openresty)
> 2. [Часто задаваемые вопросы по OpenResty | Привилегии процессов, фазы выполнения и многое другое](https://api7.ai/learning-center/openresty/faq-2)
> 3. [Часто задаваемые вопросы по OpenResty | Сетевая структура для тестирования, функции, связанные с SSL, DSL, инструмент ab](https://api7.ai/learning-center/openresty/faq-3)
> 4. [Часто задаваемые вопросы по OpenResty | Динамическая загрузка, NYI и кэширование Shared Dict](https://api7.ai/learning-center/openresty/faq-4)

На данный момент мы завершили последний раздел курса по 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`](https://github.com/openresty/lua-resty-mysql) находится в статусе `TODO`, поэтому мы можем использовать только конкатенацию массивов. Это также распространенная проблема с некоторыми библиотеками `lua-resty`, которые реализуют большую часть функциональности и работают нормально, но не обновляются вовремя. Помимо `prepare`-запросов базы данных, [`lua-resty-redis`](https://github.com/openresty/lua-resty-redis) не поддерживает `cluster`.

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

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

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

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

В репозитории [`awesome-resty`](https://github.com/bungle/awesome-resty) мы видим, что есть специальная категория для веб-фреймворков, там есть 20 открытых проектов, но большинство из них застопорились. Среди них [`Lapis`](http://leafo.net/lapis), [`lor`](http://lor.sumory.com/) и [`vanilla`](https://github.com/idevz/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, чтобы получить абсолютный путь.

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

Share article link

Share

Related Posts

[![Часть 3: Как создать API-шлюз для микросервисов с использованием OpenResty](https://static.api7.ai/uploads/2023/02/07/3XJXY9Jy_45.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

## [Часть 3: Как создать API-шлюз для микросервисов с использованием OpenResty](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

[![Часть 2: Как создать API-шлюз для микросервисов с использованием OpenResty](https://static.api7.ai/uploads/2023/02/07/FDLX3VMh_44.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservice-api-gateway-part-2)

## [Часть 2: Как создать API-шлюз для микросервисов с использованием OpenResty](https://api7.ai/learning-center/openresty/how-to-build-a-microservice-api-gateway-part-2)

Table of Contents

- [Вопрос 1: Как OpenResty используется на практике](#%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81-1-%D0%BA%D0%B0%D0%BA-openresty-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D1%82%D1%81%D1%8F-%D0%BD%D0%B0-%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B5)
- [Вопрос 2: Инкапсуляция базы данных для OpenResty](#%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81-2-%D0%B8%D0%BD%D0%BA%D0%B0%D0%BF%D1%81%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%B1%D0%B0%D0%B7%D1%8B-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85-%D0%B4%D0%BB%D1%8F-openresty)
- [Вопрос 3: Веб-фреймворк для OpenResty](#%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81-3-%D0%B2%D0%B5%D0%B1-%D1%84%D1%80%D0%B5%D0%B9%D0%BC%D0%B2%D0%BE%D1%80%D0%BA-%D0%B4%D0%BB%D1%8F-openresty)
- [Вопрос 4: Как изменить `content-length` в заголовке ответа после изменения тела ответа?](#%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81-4-%D0%BA%D0%B0%D0%BA-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-content-length-%D0%B2-%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BA%D0%B5-%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D0%B0-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D1%82%D0%B5%D0%BB%D0%B0-%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D0%B0)
- [Вопрос 5: Пути к пакетам Lua в OpenResty](#%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81-5-%D0%BF%D1%83%D1%82%D0%B8-%D0%BA-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%B0%D0%BC-lua-%D0%B2-openresty)
