生产环境优雅的重启基于Nginx、Tornado的Web服务进程
时间:2022-07-23
本文章向大家介绍生产环境优雅的重启基于Nginx、Tornado的Web服务进程,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Nginx是一个高效的Web服务器及代理服务器,Tornado是一个基于epoll的异步Web开发框架,通常使用Nginx做为Web服务器时,都会以FastCGI模式,而我们从开发、调试、运维的角度考虑,使用了反向代理的模式,同时Nginx可以做一些特殊业务和负载均衡的处理。
其实反向代理模式很简单,Nginx监听在80端口,做为Web服务端口,而Tornado的Web服务进程监听在808*的内部端口(可以启动多个进程),使用supervisor对Nginx、Tornado服务进程进行统一的管理。
首先看supervisor的配置:
# 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中):
/opt/bin/supervisord /opt/conf/supervisor.conf
重启脚本(可以放到restart.sh中)
#逐个启动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*端口上):
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检测到服务进程结束后,会自动启动对应的服务进程。
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()
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android中RecyclerView实现Item添加和删除的代码示例
- 小程序图片上传,存储,获取,显示(含源码)
- Android网络请求框架Retrofit详解
- Android控件RadioButton实现多选一功能
- 解决Android使用Handler造成内存泄露问题
- Android中imageView图片放大缩小及旋转功能示例代码
- Android 中 ThreadLocal使用示例
- Flutter基础widgets教程-Transform篇
- 借助云开发实现小程序模版消息推送(含源码)
- Android 监听软键盘状态的实例详解
- Android 中 ActivityLifecycleCallbacks的实例详解
- Android 优化Handler防止内存泄露
- Android Spinner 组件的应用实例
- Android编程实现扭曲图像的绘制功能示例
- 直播带货APP开发,圆形旋转动画