Como Gerenciar Pacotes de Terceiros do OpenResty com LuaRocks e OPM?

API7.ai

September 17, 2022

OpenResty (NGINX + Lua)

No post anterior, obtivemos uma visão geral de alguns projetos oficiais do OpenResty. No entanto, se usarmos o OpenResty para o ambiente de produção, essas bibliotecas que vêm com o pacote do OpenResty são insuficientes. Por exemplo, não há uma biblioteca lua-resty para enviar solicitações HTTP, e não há como interagir com o Kafka.

Então, o que devemos fazer?

Como o OpenResty não é um fork do NGINX, nem um repackaging do NGINX com algumas bibliotecas padrão, mas sim apenas usando o NGINX como a biblioteca de rede subjacente.

Ao usar o NGINX, você não está pensando em como iniciar solicitações HTTP personalizadas e como interagir com o Kafka. E no mundo do OpenResty, graças ao cosocket, os desenvolvedores podem rapidamente escrever lua-resty-http e lua-resty-kafka para lidar com essas necessidades, assim como você pode fazer com linguagens de desenvolvimento como Python, PHP, etc.

Outro conselho para você: você não deve usar nenhuma biblioteca do mundo Lua para resolver os problemas acima, mas sim usar a biblioteca lua-resty-* do cosocket. Bibliotecas do mundo Lua provavelmente introduzirão bloqueios, transformando um serviço de alta performance em algo várias ordens de magnitude mais lento. Este é um erro comum para iniciantes no OpenResty e não é facilmente perceptível.

Então, como encontramos essas bibliotecas lua-resty-* não bloqueantes? A seguir, vou apresentar algumas maneiras.

OPM

OPM (OpenResty Package Manager) é o gerenciador de pacotes que vem com o OpenResty e pode ser usado após a instalação do OpenResty. Podemos tentar encontrar a biblioteca que envia solicitações http usando o comando opm search http.

A consulta pode ser lenta na primeira vez, geralmente levando alguns segundos. opm.openresty.org fará uma consulta no banco de dados PostgreSQL e armazenará os resultados em cache por um tempo.

openresty/lua-resty-upload                            Streaming reader and parser for HTTP file uploading based on ngx_lua cosocket

Quando você vê esse resultado, pode se perguntar: o que esse pacote lua-resty-upload tem a ver com o envio de http?

Acontece que, ao pesquisar, o OPM pesquisou tanto o nome do pacote quanto o perfil do pacote usando a palavra-chave fornecida. É por isso que a pesquisa acima leva alguns segundos. Ele faz uma pesquisa de texto completo da string dentro do PostgreSQL.

Mas, de qualquer forma, esse retorno não é amigável. Vamos modificar a palavra-chave e pesquisar novamente.

$ opm search lua-resty-http

ledgetech/lua-resty-http                          Lua HTTP client cosocket driver for OpenResty/ngx_lua
pintsized/lua-resty-http                          Lua HTTP client cosocket driver for OpenResty/ngx_lua
agentzh/lua-resty-http                            Lua HTTP client cosocket driver for OpenResty/ngx_lua

No mundo do OpenResty, se você implementar um pacote usando cosocket, deve usar o prefixo lua-resty, que é uma regra não escrita.

Voltando aos resultados da pesquisa, o OPM usa o endereço do repositório GitHub do contribuidor como o nome do pacote, ou seja, ID do GitHub / nome do repositório. Ele retorna três bibliotecas de terceiros lua-resty-http. Qual devemos escolher?

Antes de escolher o pacote, vamos olhar para a contagem de estrelas e a última atualização: apenas uma dúzia de estrelas; a última atualização foi em 2016. Este é um projeto abandonado. Olhando mais profundamente, pintsized/lua-resty-http e ledgetech/lua-resty-http apontam para o mesmo repositório. Portanto, não importa qual você escolha, é o mesmo.

Além disso, o site do OPM é relativamente simples e não fornece o número de downloads do pacote ou as dependências desse pacote. Você precisaria gastar mais tempo para descobrir quais bibliotecas lua-resty são as certas para usar, quando isso deveria ser trabalho do mantenedor.

LuaRocks

LuaRocks é outro gerenciador de pacotes para o mundo do OpenResty, nascido antes do OPM. Diferente do OPM, que contém apenas pacotes relacionados ao OpenResty, o LuaRocks também tem bibliotecas do mundo Lua. Por exemplo, o LuaSQL-MySQL no LuaRocks é um pacote que se conecta ao MySQL no mundo Lua e não pode ser usado no OpenResty.

Ainda usando a biblioteca HTTP como exemplo, vamos tentar usar o LuaRocks para encontrar.

$ luarocks search http

Como você pode ver, ele também retorna uma série de pacotes.

Podemos mudar a palavra-chave novamente.

$ luarocks search lua-resty-http

Desta vez, apenas um pacote foi retornado. Podemos ir ao site do LuaRocks e ver os detalhes deste pacote. Aqui está uma captura de tela da página do site.

Detalhes do Pacote LuaRocks

A captura de tela acima contém o autor, Licença, URL do GitHub, número de downloads, resumo de recursos, histórico de versões, dependências, etc. Diferente do OPM, o LuaRocks não usa as informações do GitHub diretamente, mas exige que os desenvolvedores se registrem no LuaRocks separadamente.

O projeto de API gateway de código aberto, Apache APISIX, usa o LuaRocks para gerenciamento de pacotes. Vamos examinar brevemente como a configuração de gerenciamento de pacotes do APISIX é escrita.

A versão mais recente do APISIX é a 2.15, e você pode encontrar o arquivo apisix-2.15.0-0.rockspec no projeto Apache APISIX.

package = "apisix"
version = "2.15.0-0"
supported_platforms = {"linux", "macosx"}

source = {
    url = "git://github.com/apache/apisix",
    branch = "2.15.0",
}

description = {
    summary = "Apache APISIX is a cloud-native microservices API gateway, delivering the ultimate performance, security, open source and scalable platform for all your APIs and microservices.",
    homepage = "https://github.com/apache/apisix",
    license = "Apache License 2.0",
}

dependencies = {
    "lua-resty-ctxdump = 0.1-0",
    "lua-resty-dns-client = 6.0.2",
    "lua-resty-template = 2.0",
    "lua-resty-etcd = 1.8.2",
    "api7-lua-resty-http = 0.2.0",
    "lua-resty-balancer = 0.04",
    "lua-resty-ngxvar = 0.5.2",
    "lua-resty-jit-uuid = 0.0.7",
    "lua-resty-healthcheck-api7 = 2.2.0",
    "api7-lua-resty-jwt = 0.2.4",
    "lua-resty-hmac-ffi = 0.05",
    "lua-resty-cookie = 0.1.0",
    "lua-resty-session = 3.10",
    "opentracing-openresty = 0.1",
    "lua-resty-radixtree = 2.8.2",
    "lua-protobuf = 0.3.4",
    "lua-resty-openidc = 1.7.5",
    "luafilesystem = 1.7.0-2",
    "api7-lua-tinyyaml = 0.4.2",
    "nginx-lua-prometheus = 0.20220527",
    "jsonschema = 0.9.8",
    "lua-resty-ipmatcher = 0.6.1",
    "lua-resty-kafka = 0.20-0",
    "lua-resty-logger-socket = 2.0.1-0",
    "skywalking-nginx-lua = 0.6.0",
    "base64 = 1.5-2",
    "binaryheap = 0.4",
    "api7-dkjson = 0.1.1",
    "resty-redis-cluster = 1.02-4",
    "lua-resty-expr = 1.3.1",
    "graphql = 0.0.2",
    "argparse = 0.7.1-1",
    "luasocket = 3.0rc1-2",
    "luasec = 0.9-1",
    "lua-resty-consul = 0.3-2",
    "penlight = 1.9.2-1",
    "ext-plugin-proto = 0.5.0",
    "casbin = 1.41.1",
    "api7-snowflake = 2.0-1",
    "inspect == 3.1.1",
    "lualdap = 1.2.6-1",
    "lua-resty-rocketmq = 0.3.0-0",
    "opentelemetry-lua = 0.1-3",
    "net-url = 0.9-1",
    "xml2lua = 1.5-2",
    "nanoid = 0.1-1",
    "lua-resty-mediador = 0.1.2-1"
}

build = {
    type = "make",
    build_variables = {
        CFLAGS="$(CFLAGS)",
        LIBFLAG="$(LIBFLAG)",
        LUA_LIBDIR="$(LUA_LIBDIR)",
        LUA_BINDIR="$(LUA_BINDIR)",
        LUA_INCDIR="$(LUA_INCDIR)",
        LUA="$(LUA)",
        OPENSSL_INCDIR="$(OPENSSL_INCDIR)",
        OPENSSL_LIBDIR="$(OPENSSL_LIBDIR)",
    },
    install_variables = {
        ENV_INST_PREFIX="$(PREFIX)",
        ENV_INST_BINDIR="$(BINDIR)",
        ENV_INST_LIBDIR="$(LIBDIR)",
        ENV_INST_LUADIR="$(LUADIR)",
        ENV_INST_CONFDIR="$(CONFDIR)",
    },
}

Como você pode ver no arquivo, as dependências são misturadas com bibliotecas lua-resty-* e bibliotecas do mundo Lua puro, que só podem ser parcialmente instaladas usando o OPM. Após escrever a configuração, use o comando de upload do LuaRocks para enviar essa configuração, e o usuário pode usar o LuaRocks para baixar e instalar o APISIX.

O LuaRocks suporta isso. Você pode especificar o caminho e o nome do código-fonte C no arquivo .rockspec, e o LuaRocks irá compilá-lo localmente para você. O OPM ainda não suporta esse recurso.

awesome-resty

O projeto awesome-resty mantém quase todos os pacotes disponíveis para o OpenResty, organizados em categorias. Este é o melhor lugar para ir quando você não tem certeza se há um pacote de terceiros adequado.

Vamos usar a biblioteca HTTP como exemplo. No awesome-resty, ela naturalmente pertence à categoria networking.

lua-resty-http by @pintsized — Lua HTTP client cosocket driver for OpenResty / ngx_lua
lua-resty-http by @liseen — Lua http client driver for the ngx_lua based on the cosocket API
lua-resty-http by @DorianGray — Lua HTTP client driver for ngx_lua based on the cosocket API
lua-resty-http-simple — Simple Lua HTTP client driver for ngx_lua
lua-resty-httpipe — Lua HTTP client cosocket driver for OpenResty / ngx_lua
lua-resty-httpclient — Nonblocking Lua HTTP Client library for aLiLua & ngx_lua
lua-httpcli-resty — Lua HTTP client module for OpenResty
lua-resty-requests — Yet Another HTTP Library for OpenResty

Vemos que há oito bibliotecas de terceiros para lua-resty-http. Comparando com os resultados anteriores, encontramos apenas 2 usando o OPM e apenas 1 no LuaRocks. No entanto, se for difícil escolher, use a primeira, que é a mesma do LuaRocks.

Para engenheiros dispostos a experimentar, recomendo a última biblioteca: lua-resty-requests, uma biblioteca de acesso HTTP mais amigável, com o mesmo estilo de interface do famoso Requests do Python. Se você é um amante de Python como eu, vai adorar o lua-resty-requests, que é mantido por tokers, um membro ativo da comunidade OpenResty, para que você possa usá-lo com confiança.

Resumo

Para um projeto de código aberto prosperar, ele precisa não apenas de tecnologia robusta, boa documentação e testes completos, mas também de um ecossistema que reúna mais desenvolvedores e empresas. Como diz o Apache Way: comunidade sobre código.

Não há material de aprendizagem sistemático para o OpenResty, nenhum guia de código oficial, e muitos pontos de otimização foram escritos no projeto de código aberto. Ainda assim, a maioria dos desenvolvedores sabe o que estão falando, mas não sabem o porquê. Esse é o propósito deste Ebook. Após aprendê-lo, espero que você possa escrever um código OpenResty mais eficiente e participar de forma mais eficaz em projetos de código aberto relacionados ao OpenResty, por exemplo, Apache APISIX.

O que você acha do ecossistema do OpenResty? Sinta-se à vontade para deixar um comentário e vamos conversar sobre isso. Além disso, sinta-se à vontade para compartilhar este artigo.