在项目中应用到了 Tornado 框架,开始时只是单进程裸跑 Tornado 实例,但是在高并发的情况下,单进程无法满足上千的连接请求。Nginx 是我们熟知的反向代理服务器,它可以支持上万的平行连接,在与 PHP、Python 集成后可以应用在大规模的集群上,Nginx 同时也可以用作负载平衡器,以减小单点服务器的压力。
Supervisor 是一个进程管理工具,我们可以使用它管理多个 Tornado 实例,非常方便。
总的思路是:Nginx 通过唯一监听端口接收大量请求,然后将请求分发到不同的 Tornado 实例上,Supervisor 将多个 Tornado 实例进程统一管理。
Tornado
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。Tornado 由于内置了支持 epoll/kqueue 等高效网络库,而具备了处理高并发的能力。
程序入口:
1 | # -*- coding: utf-8 -*- |
执行以下命令运行:
1 | python27 app.py --port=8081 |
注意: 因为我的机器上安装了不同版本的 Python 解释器,python27
是我为 Python 2.7.13 创建的软连接。
以下一行代码必须有:
1 | tornado.options.parse_command_line() |
因为我们运行程序脚本时,需要指定不同的端口,这是在执行 Tornado 的解析命令行。
Supervisor 管理 Tornado 进程
Supervisor 的安装可以在官方文章中找到,可使用 yum pip easy_insatll
等方法。最简单的就是:
1 | pip27 install supervisor |
注意: 因为我的机器上安装了不同版本的 pip 包,pip27
是我为 Python 2.7.13 使用的。
创建文件夹:
1 | mkdir /etc/supervisor |
创建配置文件:
1 | echo_supervisord_conf > /etc/supervisor/supervisord.conf |
修改 /etc/supervisor/supervisord.conf
文件内容,在文件结尾 [include]
节点处
1 | ; [include] |
保存并退出
在 /etc/supervisor/
下创建 conf.d
文件夹,及 ProjectName.conf
(以项目名称命名的,例如:tornados.conf)
执行:
1 | vi tornados.conf |
添加以下内容:
1 | [group:tornados] |
保存并退出
执行以下命令启动 Supervisor :
1 | supervisord -c /etc/supervisor/supervisord.conf |
坑1:出现错误 Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord.For help, use /usr/bin/supervisord –h
解决办法:是因为有一个使用 supervisor 配置的应用程序正在运行。执行
ps -ef | grep supervisor
查看进程,杀掉 supervisor 的所有进程,重新运行 参考这里坑2:出现错误 Unlinking stale socket /tmp/supervisor.sock
解决办法:执行
unlink /tmp/supervisor.sock
参考这里
如果执行成功,ps -ef | grep python
结果如下:
1 | root 21314 1 0 15:22 ? 00:00:00 /usr/bin/python27 /usr/local/python2.7/bin/supervisord -c /etc/supervisor/supervisord.conf |
Nginx 作反向代理
安装好 Nginx 后,编辑 nginx.conf 文件:
1 | http { |
可参考 运行和部署
以上,就完成了Nginx+Tornado+Supervisor 的项目部署,分别启动 nginx、supervisord ,就可以达到不错的负载均衡效果(我的项目中没有访问静态资源的情景,所以主要还是作负载均衡用)