Ваша первая программа на OpenResty: Hello World
API7.ai
September 9, 2022
Когда мы начинаем изучать новый язык разработки, учебные материалы обычно предоставляют простой пример hello world. Поэтому давайте сначала пропустим установку и посмотрим, как написать этот пример в OpenResty:
$ resty -e "ngx.say('hello world')" hello world
Это, вероятно, самый простой код hello world, который вы когда-либо видели, похожий на Python:
$ python -c 'print("hello world")' hello world
За этим стоит проявление философии OpenResty. Код должен быть достаточно лаконичным, чтобы избавить вас от мысли "от входа до отказа". Этот пост будет посвящен примеру hello world.
Как мы говорили в посте В чем разница между OpenResty и NGINX, OpenResty основан на NGINX. Поэтому у вас может возникнуть вопрос: почему здесь не видно следов NGINX? Не беспокойтесь, давайте добавим строку кода, чтобы увидеть, что работает за кулисами resty:
$ resty -e "ngx.say('hello world'); ngx.sleep(10)" &
Мы добавили метод ngx.sleep, чтобы программа не завершалась после вывода строки hello world. Таким образом, у нас есть возможность узнать:
$ ps -ef | grep nginx root 15944 6380 0 13:59 pts/6 00:00:00 grep --color=auto nginx
Наконец, появляется процесс NGINX! Похоже, что команда resty по сути запускает службу NGINX, так что же такое resty?
Возможно, у вас на машине не установлен OpenResty, поэтому давайте вернемся к шагам установки, которые мы пропустили в начале, и установим OpenResty, прежде чем продолжить.
Установка
Как и другое программное обеспечение с открытым исходным кодом, мы можем установить OpenResty различными способами, например, используя менеджер пакетов операционной системы, компиляцию из исходного кода или образ Docker. Однако я рекомендую сначала использовать менеджер пакетов, такой как yum, apt-get и brew, для установки OpenResty. В этом посте я буду использовать macOS в качестве примера:
$ brew tap openresty/brewbrew install openresty
Использование других операционных систем аналогично. Сначала добавьте URL репозитория OpenResty в менеджер пакетов, а затем используйте менеджер пакетов для установки OpenResty. Более подробные шаги можно найти в официальной документации.
Однако за этой кажущейся простой установкой скрываются две проблемы:
- Почему я не рекомендую использовать установку из исходного кода?
- Почему нельзя установить напрямую из официального репозитория операционной системы, а нужно сначала настроить другой репозиторий?
Пожалуйста, сначала подумайте над этими двумя вопросами.
Здесь я хотел бы добавить еще одну вещь. В этом курсе я буду задавать много вопросов "почему" за внешним видом. Я надеюсь, что вы будете думать, изучая новые вещи. Неважно, правильный ли результат или нет. К сожалению, независимое мышление также редкость в технической области. Из-за различий в технической области и глубине знаний каждого человека, учителя неизбежно будут иметь личные мнения и ошибки в знаниях в любом курсе. Мы можем постепенно сформировать свою собственную техническую систему, задавая несколько вопросов "почему" в процессе обучения и понимая их.
Многие инженеры любят собирать из исходных кодов, и я тоже много лет назад. Однако, когда я использую проект с открытым исходным кодом, я всегда надеюсь, что могу вручную configure и make из исходного кода и изменить некоторые параметры компиляции. Я чувствую, что это лучший способ подойти к среде этой машины и максимизировать ее производительность.
Но в реальности это не так. Каждый раз, когда я компилирую исходный код, я сталкиваюсь с странными проблемами среды, и я могу установить его только после долгих мучений. Теперь я понимаю, что наша первоначальная цель — использовать проекты с открытым исходным кодом для решения бизнес-задач. Мы не должны тратить время и силы на борьбу с окружением, не говоря уже о менеджерах пакетов и контейнерных технологиях. Именно они помогают нам решить эти проблемы.
Вернемся к теме. Использование исходного кода OpenResty для установки не только сложно, вам нужно решить внешние зависимости, такие как PCRE, OpenSSL и т.д., но также нужно вручную патчить соответствующую версию OpenSSL. В противном случае будет отсутствовать функциональность при работе с SSL-сессиями. Например, Lua API, такие как ngx.sleep, которые вызывают yield, не могут быть использованы. Если вы хотите узнать больше об этой части, вы можете обратиться к официальной документации для получения более подробной информации.
OpenResty самостоятельно поддерживает эти патчи в скрипте пакета OpenSSL. Когда OpenResty обновляет версию OpenSSL, он должен перегенерировать соответствующий патч и провести полное регрессионное тестирование.
Source0: https://www.openssl.org/source/openssl-%{version}.tar.gz Patch0: https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0d-sess_set_get_cb_yield.patch Patch1: https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0j-parallel_build_fix.patch
В то же время мы можем взглянуть на скрипт пакета OpenResty в CentOS, чтобы увидеть, есть ли другие скрытые моменты:
BuildRequires: perl-File-Temp BuildRequires: gcc, make, perl, systemtap-sdt-devel BuildRequires: openresty-zlib-devel >= 1.2.11-3 BuildRequires: openresty-openssl-devel >= 1.1.0h-1 BuildRequires: openresty-pcre-devel >= 8.42-1 Requires: openresty-zlib >= 1.2.11-3 Requires: openresty-openssl >= 1.1.0h-1 Requires: openresty-pcre >= 8.42-1
Как видно здесь, OpenResty поддерживает свою версию OpenSSL и свои версии zlib и PCRE. Однако последние два изменили параметры компиляции и не сохранили свои патчи.
Таким образом, учитывая эти факторы, я не рекомендую компилировать OpenResty из исходного кода, если вы уже не знаете деталей.
Теперь вам должно быть понятно, почему не рекомендуется установка из исходного кода. Когда мы ответили на первый вопрос, мы также ответили на второй вопрос: почему нельзя установить напрямую из официальных репозиториев пакетов операционной системы, а нужно сначала настроить другой репозиторий?
Это связано с тем, что официальные репозитории не хотят принимать пакеты OpenSSL, PCRE и zlib, поддерживаемые третьими сторонами, чтобы не вызывать путаницы у других пользователей, которые не знают, какой выбрать. С другой стороны, OpenResty нуждается в определенных версиях библиотек OpenSSL и PCRE для нормальной работы, а версии по умолчанию в системе относительно старые.
CLI OpenResty
После установки OpenResty, CLI OpenResty resty уже установлен по умолчанию. Это скрипт на Perl, и, как мы упоминали ранее, инструменты экосистемы OpenResty написаны на Perl, что определяется техническими предпочтениями автора OpenResty.
$ which resty /usr/local/bin/resty $ head -n 1 /usr/local/bin/resty #!/usr/bin/env perl
CLI resty очень мощный, и мы можем использовать resty -h или прочитать официальную документацию для получения полного списка функциональности. Далее я представлю две интересные функции.
$ resty --shdict='dogs 1m' -e 'local dict = ngx.shared.dogs dict:set("Tom", 56) print(dict:get("Tom"))' 56
Пример выше показывает конфигурацию Nginx с кодом Lua, который выполняет настройку и запрос словаря в общей памяти. dogs 1m — это конфигурация Nginx, которая объявляет пространство общей памяти с именем dogs и размером 1m. Общая память используется как словарь в коде Lua.
Также параметры --http-include и --main-include используются для настройки файла конфигурации NGINX, поэтому мы можем переписать пример выше следующим образом:
$ resty --http-conf 'lua_shared_dict dogs 1m;' -e 'local dict = ngx.shared.dogs dict:set("Tom", 56) print(dict:get("Tom"))'
Стандартные инструменты отладки в мире OpenResty, такие как gdb, valgrind, sysetmtap и Mozilla rr, также могут быть использованы с resty для облегчения обычной разработки и тестирования. Они соответствуют различным командам resty, поэтому внутренняя реализация проста, просто дополнительный слой вызовов командной строки. Давайте возьмем valgrind в качестве примера.
$ resty --valgrind -e "ngx.say('hello world'); " ERROR: failed to run command "valgrind /usr/local/openresty/nginx/sbin/nginx -p /tmp/resty_rJeOWaYGIY/ -c conf/nginx.conf": No such file or directory
Они применимы не только к миру OpenResty, но и являются общими инструментами для серверной стороны, поэтому давайте изучать их шаг за шагом.
Более формальный "hello world"
Первый OpenResty-программу, которую мы написали в начале, использовали команду resty без процесса master и без прослушивания определенных портов. Теперь давайте реализуем еще одну программу hello world.
Нам нужно как минимум три шага, чтобы завершить ее.
- Создать рабочий каталог.
- Изменить файл конфигурации
NGINX, чтобы встроить кодLuaв него. - Запустить службу
OpenResty.
Давайте начнем с создания рабочего каталога.
$ mkdir openresty-sample $ cd openresty-sample $ mkdir logs/ conf/
Ниже приведен минималистичный nginx.conf с директивой OpenResty content_by_lua в корневом каталоге, которая встраивает метод ngx.say.
events { worker_connections 1024; } http { server { listen 8080; location / { content_by_lua ' ngx.say("hello, world") '; } } }
Пожалуйста, убедитесь, что openresty добавлен в переменную окружения PATH; затем запустите службу OpenResty:
$ openresty -p `pwd` -c conf/nginx.conf
Если ошибок не произошло, служба OpenResty успешно запущена. Мы можем получить доступ к ней с помощью команды cURL, чтобы увидеть возвращаемые результаты.
$ curl -i 127.0.0.1:8080 HTTP/1.1 200 OK Server: openresty/1.13.6.2 Content-Type: text/plain Transfer-Encoding: chunked Connection: keep-alive hello, world
Поздравляем! Формальный Hello World в OpenResty завершен!
Итог
Давайте подведем итог тому, что мы узнали сегодня. Сначала мы начали с установки OpenResty и CLI с простой строкой кода "hello, world", и, наконец, мы запустили процесс OpenResty и запустили реальную серверную программу.
Среди них resty — это инструмент командной строки, который мы будем часто использовать в будущем. Поэтому демонстрационный код в курсе запускается с его помощью, а не путем запуска службы OpenResty в фоновом режиме.
Что более важно, за OpenResty скрыто множество культурных и технических деталей, и это похоже на айсберг, плавающий в море. Через этот курс я надеюсь показать вам более полный OpenResty, а не только его открытые API.