OpenResty logo

OpenResty® 通过 Lua 扩展 NGINX 实现的可伸缩的 Web 平台

Search
OpenResty XRay

Advanced observability built for OpenResty and more

×

limited time offer

Request TRIAL today and receive a diagnostic REPORT
Learn more
OpenResty
最新! OpenResty 1.31.1.1 已发布。
OpenResty
最新! OpenResty 1.29.2.5 已发布。
OpenResty XRay logo
最新! 新博客文章 OpenResty XRay 26.7.15 版正式发布 已发表。
OpenResty private libraries
最新! 新博客文章 OpenResty 私有库:高性能 Lua 与 Nginx 模块 已发表。

基于 Redis 的动态路由

Yichun Zhang , 14 Sep 2011 (created 27 Jul 2011)

This sample demonstrates how to use redis to route incoming requests to different HTTP backends based on the requests' User-Agent header.

This demo uses the modules Redis2 Nginx Module, Lua Nginx Module, Lua Redis Parser Library, and Set Misc Nginx Module bundled by OpenResty:

Here's the complete code listing for our nginx.conf:

worker_processes  1;
error_log logs/error.log info;

events {
    worker_connections 1024;
}

http {
    upstream apache.org {
        server apache.org;
    }

    upstream nginx.org {
        server nginx.org;
    }

    server {
        listen 8080;

        location = /redis {
            internal;
            set_unescape_uri $key $arg_key;
            redis2_query get $key;
            redis2_pass 127.0.0.1:6379;
        }

        location / {
            set $target '';
            access_by_lua '
                local key = ngx.var.http_user_agent
                local res = ngx.location.capture(
                    "/redis", { args = { key = key } }
                )

                print("key: ", key)

                if res.status ~= 200 then
                    ngx.log(ngx.ERR, "redis server returned bad status: ",
                        res.status)
                    ngx.exit(res.status)
                end

                if not res.body then
                    ngx.log(ngx.ERR, "redis returned empty body")
                    ngx.exit(500)
                end

                local parser = require "redis.parser"
                local server, typ = parser.parse_reply(res.body)
                if typ ~= parser.BULK_REPLY or not server then
                    ngx.log(ngx.ERR, "bad redis response: ", res.body)
                    ngx.exit(500)
                end

                print("server: ", server)

                ngx.var.target = server
            ';

            proxy_pass https://$target;
        }
    }
}

And then let's start the redis server on the localhost:6379:

$ ./redis-server  # default port is 6379

and feed some keys into this using the redis-cli utility:

$ ./redis-cli
   redis> set foo apache.org
   OK
   redis> set bar nginx.org
   OK

And then let's test our nginx app!

$ curl --user-agent foo localhost:8080
   <apache.org home page goes here>

   $ curl --user-agent bar localhost:8080
   <nginx.org home page goes here>

To further tune the performance, one could enable the connection pool for the redis connections, as documented in Redis2 Nginx Module's README.