在Lua中使用OpenResty向Redis查询的API示例

我将使用扩展了Lua功能的OpenResty来扩展Nginx,并编写一个简单的API示例。它将通过与后端的Redis进行通信,并以JSON格式返回响应。据我了解,Lua使用了lua-resty-redis作为Redis客户端。由于Lua具有嵌入式编程的能力,因此我们可以在OpenResty中使用它作为反向代理来平衡后端应用程序之间的轻微API差异。

项目

这次我们仍然使用Docker Compose来进行服务编排。您需要创建一个项目目录并创建docker-compose.yml和nginx.conf文件。

$ cd ~/openresty_apps
$ tree
.
├── docker-compose.yml
└── nginx
    └── nginx.conf

使用OpenResty镜像的推荐选项是tenstartups/openresty。此镜像中有一个名为/entrypoint的启动脚本被设置为ENTRYPOINT。由于想要在编辑nginx.conf后发送HUP信号来重新加载配置,因此需要在docker-compose.yml中进行覆盖设置。

openresty:
  restart: always
  image: tenstartups/openresty
  ports:
    - "80:80"
  volumes:
    - ./nginx:/etc/nginx
  links:
    - redis
  entrypoint: ["nginx", "-c", "/etc/nginx/nginx.conf"]
redis:
  restart: always
  image: redis
rediscli:
  image: redis
  links:
    - redis

使用 `env` 指令在 `nginx.conf` 文件中读取环境变量,并使用 `links` 指定的 Redis 服务的 IP 地址和端口进行配置。将 UUID 指定为查询字符串。这是一个简单的示例,它从 OpenResty 查询 Redis 来获取相应的令牌,并返回 JSON。

daemon off;
worker_processes  1;

env REDIS_PORT_6379_TCP_ADDR;
env REDIS_PORT_6379_TCP_PORT;

events {
    worker_connections  256;
}

http {
    server {
        listen 80;
        access_log /proc/self/fd/1;
        error_log /proc/self/fd/2;

        location /api/v1/tokens {
            default_type text/html;
            content_by_lua '
                local cjson = require "cjson"
                local redis = require "resty.redis"
                local red = redis:new()
                local args = ngx.req.get_uri_args()

                local ok, err = red:connect(os.getenv("REDIS_PORT_6379_TCP_ADDR"), tonumber(os.getenv("REDIS_PORT_6379_TCP_PORT")))

                if not ok then
                    ngx.say("failed to connect: ", err)
                    return
                end

                local res, err = red:get("users:" .. args.uuid)

                if not res then
                    ngx.say("failed to get token: ", err)
                    return
                end

                ngx.header.content_type = "application/json; charset=utf-8"
                ngx.say(cjson.encode({token = res}))
                red:close()
            ';
        }
    }
}

使用Docker Compose启动openresty服务。

$ docker-compose up openresty
docker-compose up openresty
Recreating openrestyapps_redis_1...
Recreating openrestyapps_openresty_1...
Attaching to openrestyapps_openresty_1

与此同时Redis服务将启动,但RedisCLI服务将不会启动。

$ docker-compose ps
      Name             Command             State              Ports
-------------------------------------------------------------------------
openrestyapps_op   nginx -c /etc/ng   Up                 0.0.0.0:80->80/t
enresty_1          inx/nginx.conf                        cp
openrestyapps_re   /entrypoint.sh     Up                 6379/tcp
dis_1              redis-server

使用redis-cli创建记录。

使用rediscli服务在Redis中创建用于测试的记录。

$ docker-compose run --rm rediscli bash -c 'redis-cli -h $REDIS_PORT_6379_TCP_ADDR set users:123 8Nyo7D9a'
OK
Removing openrestyapps_rediscli_run_1...

确定从get开始创建记录。

$ docker-compose run --rm rediscli bash -c 'redis-cli -h $REDIS_PORT_6379_TCP_ADDR get users:123'
"8Nyo7D9a"
Removing openrestyapps_rediscli_run_1...

用curl进行测试。

向OpenResty服务发送HUP信号,并重新加载nginx.conf文件。

$ docker-compose kill -s HUP openresty
Killing openrestyapps_openresty_1...

我已经从Docker主机使用curl命令以JSON格式成功获取到了令牌。

$ curl  "http://localhost/api/v1/tokens?uuid=123"
{"token":"8Nyo7D9a"}
广告
将在 10 秒后关闭
bannerAds