在做毕设的时候需要动态改变通过nginx代理的服务器数量。背景大概是我有一个generator不断产生负载打在nginx上,还有一个monitor根据generator生成负载的qps来动态决定需要多少台服务器刚好能够承担这个qps的请求,因此需要动态修改nginx中的upstream。以前在配置nginx的时候,upstream都是写死在nginx.conf文件中的,现在要动态改变upstream,这需要在nginx运行过程中用脚本修改,那么就用Lua来实现吧。
nginx+lua安装
之前安装过了nginx,但是没有安装lua模块,下面按照官网的步骤开始集成Lua。
需要下载:
- LuaJIT:Lua编译器(a Just-In-Time Compiler for Lua),2.0或2.1版本均可
- ngx_devel_kit (NDK) module
- lua-nginx-module
安装好LuaJIT,解压NDK module和lua-nginx-module,继续。
|
|
测试一下是否成功:
在nginx.conf中加入
访问127.0.0.1/hello,出现”hello, lua”即为成功。
动态改变upstream
这里使用了lua中的”lua_shared_dict”创建一个共享内存空间,通过该命令定义的共享内存对象对于nginx中所有worker进程都是可见的,通过./nginx -s reload是不会改变共享内存对象的内容的,只有nginx重启才重新清空内容。
下面就是nginx.conf中的配置了。
|
|
日志打在了nginx/log/error.log中
定义了切换upstream的接口,下面命令可以将upstream切换为energyaware_servers_2(一组服务器),而无需./nginx -s reload
切换完成之后,可以用下面脚本生成请求,然后看看这些请求都打到了哪台服务器上
我这里energyaware_servers_2中有两台服务器,负载均衡策略就是最简单的轮询,所以请求应该是平均地被这两台服务器消费了。
当然也可以把upstream设置成单台服务器,直接写成ip:port的形式即可。比如:
参考:
https://github.com/openresty/lua-nginx-module#installation
http://blog.csdn.net/force_eagle/article/details/51966333
http://blog.csdn.net/toontong/article/details/49633829
利用redis持久化upstream
有的时候我们希望把upstream持久化,否则nginx因为各种各样的原因需要重启的时候lua_shared_dict被清空,从而失去了我们原来的upstream;而且,当不止有一台nginx的时候,由于lua_shared_dict为单个nginx所有不被共享,造成不同nginx对应着不同的upstream,失去了nginx集群的意义。总之,我们需要持久化upstream。
实现与上面方法类似,将upstream以
参考:
https://sosedoff.com/2012/06/11/dynamic-nginx-upstreams-with-lua-and-redis.html
http://blog.csdn.net/imlsz/article/details/47720235
其他方法
其实我最初的想法是想能不能动态地增加/删除upstream里面的server,这样做需要懂nginx内核了。。。好在发现了一个开源的模块ngx_http_dyups_module,淘宝大神写的。不过我还没有尝试,先记录下万一以后用到。
nginx官方实现了这个功能,但是在nginx plus版本中(收费)
“NGINX Plus offers an API that falls closely to the REST architecture and is unified under a single API endpoint. Use the NGINX Plus API to update upstream configurations and key‑value stores on the fly with zero downtime. “
–摘自官网