Nginx是一个高效的Web服务器及代理服务器,Tornado是一个基于epoll的异步Web开发框架,通常使用Nginx做为Web服务器时,都会以FastCGI模式,而我们从开发、调试、运维的角度考虑,使用了反向代理的模式,同时Nginx可以做一些特殊业务和负载均衡的处理。
其实反向代理模式很简单,Nginx监听在80端口,做为Web服务端口,而Tornado的Web服务进程监听在808*的内部端口(可以启动多个进程),使用supervisor对Nginx、Tornado服务进程进行统一的管理。
首先看supervisor的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # supervisor自己的配置及日志切割等 [supervisord] logfile = /opt/logs/supervisord .log logfile_maxbytes = 200MB logfile_backups=10 loglevel = warn pidfile = /opt/logs/supervisord .pid nodaemon = false minfds = 1024 minprocs = 200 umask = 022 identifier = supervisor directory = %(here)s nocleanup = true strip_ansi = false [unix_http_server] file = /opt/logs/supervisord .sock [supervisorctl] serverurl = unix: ///opt/logs/supervisord .sock [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface # 服务进程的启动及多端口 [program:MyWeb] command = /opt/bin/python %(here)s /server .py --port=808%(process_num)01d process_name = 808%(process_num)01d numprocs = 4 numprocs_start = 1 autostart = true autorestart = true redirect_stderr = true stdout_logfile = /opt/logs/stdout .log stderr_logfile = /opt/logs/stdout .log # Nginx的管理配置 [program:Nginx] command = /opt/sbin/nginx -c %(here)s /nginx .conf process_name = Nginx numprocs = 1 autostart = true autorestart = true redirect_stderr = true stdout_logfile = /opt/logs/nginx_stdout .log stderr_logfile = /opt/logs/nginx_stdout .log |
启动脚本(可以放到start.sh中):
1 | /opt/bin/supervisord /opt/conf/supervisor .conf |
重启脚本(可以放到restart.sh中)
1 2 3 4 5 6 7 8 | #逐个启动MyWeb每个端口进程,不中断服务 for i in "8081 8082 8083 8084" : do
/opt/bin/supervisorctl /opt/conf/supervisor .conf restart MyWeb:$i; done #重新加载nginx的配置 /opt/sbin/nginx /opt/conf/nginx .conf -s reload; |
Nginx的部分配置(启动4个服务进程,监听在80端口,并反向代理负载到Tornado的808*端口上):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | worker_processes 4; daemon off; #nginx不能以daemon模式启动 user nobody; http {
upstream myweb {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
server 127.0.0.1:8083;
server 127.0.0.1:8084;
}
server {
listen 80;
server_name localhost;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_read_timeout 300s;
proxy_pass http: //myweb ;
}
} } |
现在Nginx已经反向代理到Tornado的服务进程监听的端口了,那么MyWeb的服务进程如何构建、并如何优雅的重启呢,略过其他代码,介绍一下主进程采用信号停止服务,并重新启动的方法。主进程的启动参数会指定此进程监听的端口,这样supervisor检测到服务进程结束后,会自动启动对应的服务进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import signal import tornado.ioloop import tornado.httpserver http_server = None def sig_handler(sig, frame):
"""信号处理函数
"""
tornado.ioloop.IOLoop.instance().add_callback(shutdown) def shutdown():
"""进程关闭处理
"""
# 停止接受Client连接
global http_server
http_server.stop()
io_loop = tornado.ioloop.IOLoop.instance()
deadline = time.time() + 10 #设置最长强制结束时间
def stop_loop():
now = time.time()
if now < deadline:
io_loop.add_timeout(now + 1 , stop_loop)
else :
io_loop.stop()
stop_loop() if __name__ = = ‘__main__‘ :
# 等待supervisor发送进程结束信号
signal.signal(signal.SIGTERM, sig_handler)
signal.signal(signal.SIGINT, sig_handler)
app = Application()
http_server = tornado.httpserver.HTTPServer(app, xheaders = True )
http_server.listen(tornado.options.options.port)
tornado.ioloop.IOLoop.instance().start() |
生产环境优雅的重启基于Nginx、Tornado的Web服务进程
原文地址:https://www.cnblogs.com/sunsky303/p/9579926.html