JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

OpenResty实现动态路由 openresty 动态配置

wys521 2024-10-06 13:13:20 精选教程 27 ℃ 0 评论

什么是路由

这里所说的「路由」不是用在网络中的概念,而是在 web 开发中,访问路径以及具体的内容映射。比如,访问 /a 映射到某个具体的服务,这个就称为一个路由。动态路由,顾名思义就是动态地添加这种映射关系。

对于 OpenResty (Nginx) 来说,得益于它强劲的性能,常常用来当作反向代理网关,用过nginx的朋友对点肯定清楚。是通过它强大的 location 配置将不同的 /$request_uri 转发到不同的后端服务中,这样的转发关系也就是我们这里要说到的「路由」如下面nginx.conf配置:

...
localtion = /app1 {
    ...
    proxy_pass http://www.app1.com;     #app1服务
}

location = /app2 {
    ....
    proxy_pass http://www.app2.com;     #app2服务
}

动态路由

原始配置问题:上面的配置都是把路由写在nginx.conf中,如果路由发生变化,就需要修改nginx.conf,要断开手动 reload 使配置生效。这样的操作在今天以容器作为服务的载体下就显得异常的繁琐了,容器的生命周期通常来说是短暂的,一旦容器发生变动就需要去手动修改配置,这样对于生产环境和运维人员是不能接受的。

解决方法:通过 Lua + Redis 实现动态路由

应用场景:该方案是将原来定义 upstream 中的 server_ip 存放在 redis 中,通过 lua 去读取后直接 proxy_pass,这样做其实是损失了 Nginx 中 upstream 中的负载均衡算法,心跳机制,所有应用场景存在一定的局限性,就是 proxy_pass 的 server_ip 是一个 LB 的地址,这个 LB 上实现了原来由 Nginx upstream 中实现的负载均衡和心跳机制。有个好消息就是这样的方案就非常适合现在的 Kubernetes 架构了,Kubernetes 中的 Service 对象产生的 cluster_ip 正是一个 LB 的 IP。

具体的实现方法如下:

使用 OpenResty已经帮我们集成好的模块ngx_redis2 来实现读取 redis 的接口,安全考虑要在 location 中配置 internal 保护这个接口只运行内部调用。

具体nginx.conf配置信息:

worker_processes  1;
error_log logs/error.log info;
events {
    worker_connections 1024;
}
http {
    lua_package_path "/usr/local/openresty/nginx/jwt-lua/lib/?.lua;;";
    server {
        listen 80;
        default_type text/plain;
      
        location = /redis {
                set_unescape_uri $key $arg_key;
                redis2_query get $key;
                redis2_pass 172.17.0.3:6379;
        }

        location /app1 {
                set $target '';
                default_type "text/html";
                #lua语言部分
                access_by_lua_block {
                      local rds_key = "app1"
                      local res = ngx.location.capture('/redis', { args = {key = rds_key}})
                      local parser = require 'redis.parser'
                      local res, typ = parser.parse_reply(res.body)
                      ngx.var.target = res
                }
                proxy_pass "http://$target";
        }

        location /app2 {
                set $target '';
                default_type "text/html";
                #lua语言部分
                access_by_lua_block {
                      local rds_key = "app2"
                      local res = ngx.location.capture('/redis', { args = {key = rds_key}})
                      local parser = require 'redis.parser'
                      local res, typ = parser.parse_reply(res.body)
                      ngx.var.target = res
                }
                proxy_pass "http://$target";
        }
		}
}

这样配置当后端服务变化的时候,我们只需要进入redis中把相应的key内容更换一下即可实现动态路由。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表