1、转发单台设备的请求量在十几万QPS,如果不保持长连接,性能会非常差
2、转发的后端地址并不是固定的,需要根据请求信息上报给不同的域名
使用balancer_by_lua_file的方式,用balancer.set_current_peer动态设置后端地址
location = /upload {
# 长链接配置
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass "$scheme://$addr";
}
如上述代码,就是nginx的的一个配置,addr可以在rewrite过程中从请求信息中读取即可。
但实际测试过程中发现,该方式不可行,长连接并没有保持成功。
多方咨询,终于了解到,为了与后端保持长连接,需要加入upstream模块并配置keepalive。
upstream log_forward_backend {
server 127.0.0.1:80;
keepalive 100;
}
但问题又来了,upstream模块中server配置的地址不能用变量,只能为ip,那不同域名的地址如何写到server配置中?想到了以下办法:
1、upstream中的server先放一个默认的,在安装脚本中根据实际地址去替换。
-- 不适用,后端地址固定的。而转发的场景后端地址太多,并且新增地址还需要还需要添加配置后重新reload,不灵活
2、放弃使用upstream,直接用lua库的resty.http去发起请求,用一个client也是可以保持长连接的。
-- resty.http性能会较差,且部分信息无法记录在访问日志中,不便于定位
3、采用balancer的方式,根据请求信息动态设置后端地址
-- 可行。
经过上一步的方案讨论后,最终采用balancer_by_lua_file的方式,就只剩下以下问题需要解决:
最终实现的关键代码如下:
1、location模块,proxy_pass到对应的upstream中:
location = /upload {
# 长链接配置
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass "$scheme://forward_backend$path";
}
2、实现log_forward_backend的upstream,用了balancer之后,这里server实际就失效了,可以先写一个假的server:
upstream forward_backend {
server 127.0.0.1:80;
balancer_by_lua_file lua/balancer.lua;
keepalive 100;
}
3、实现balancer.lua,主要是有以下两个配置:
balancer.set_more_tries(1)
balancer.set_current_peer(cur_ip, port)
到此,nginx到后端厂商的长连接问题终于解决。
1、采用balancer之后,必须要自己实现DNS解析
2、DNS解析后,可能会有多个IP地址,如果只使用一个IP地址,可靠性会较差
步骤一:直接用nginx中http模块中的resolver配置(采用balancer后不可行)
http {
# DNS域名解析
resolver 119.29.29.29 223.5.5.5 114.114.114.114 valid=300s;
resolver_timeout 3s;
}
该方式对proxy_pass中的域名可正常解析,但由于需要保持长连接,用balancer就无法采用该配置。
步骤二:rewrite阶段进行DNS解析查询,并缓存DNS结果到共享内存中。