1、为何需要优雅重启

在实际开发过程中,我们会不断迭代升级产品,每次迭代后,都需要在线上服务器更新代码。一般小公司的迭代升级,是没有做到像金丝雀发布或者使用到kubernetes这些东西的。那如何保证更新的时候,之前接收到的请求能够正常处理完成呢,这个时候就需要实现优雅重启了。

那如何实现优雅重启呢,其实,我们部署python web服务所用到的uwsgi和gunicorn已经实现了优雅重启了,下面就讲讲如何实现优雅重启

2、uwsgi 如何实现优雅重启

以下实验是基于以下版本进行的。

python3.6.8

flask==2.0.3
uwsgi==2.0.21

2.1 编写 web 服务

main.py

import time

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
time.sleep(10)
return "hello eeee" if __name__ == "__main__":
app.run()

2.2 编写 uwsgi.ini 配置文件

[uwsgi]
#uwsgi启动时,所使用的地址和端口(这个是http协议的)
http=0.0.0.0:8000
#指向网站目录
chdir=./
#python 启动程序文件
wsgi-file=main.py
#python 程序内用以启动的application 变量名
callable=app
#处理器数
processes=4
#线程数
threads=2 #####实现优雅重启添加下面两行配置即刻#####
lazy-apps = true
#监听 test.txt 文件 当 test.txt 发生改变时优雅重启uwsgi。这个名字可以随便起
touch-chain-reload = /Users/xx/work/test/py_test/sample_test/flask_graceful_restart/test.txt

2.3 启动uwsgi 服务

uwsgi --ini uwsgi.ini

2.4 测试优雅重启

1、请求 http://127.0.0.1:8000/

2、更新 main.py 中返回的内容,改为: return "hello xxxxx"

2、在/Users/xx/work/test/py_test/sample_test/flask_graceful_restart 目录下,执行 touch test.txt。有这个文件时,更改这个文件的内容也可以优雅重启 uwsgi 服务

3、得到第一步的返回结果,返回结果为:"hello eeee"

5、再次请求 http://127.0.0.1:8000/ ,返回结果为:"hello xxxxx"

通过上述测试,可以发现实现了优雅重启。

优雅重启的日志过程:

整个时间还挺久的,差不多4分钟。

开始:12:14:45。

结束:12:18:57。

1、先查看 uwsgi 进程信息

501  7758  4633   0 12:13PM ttys005    0:00.04 uwsgi --ini uwsgi.ini
501 7759 7758 0 12:13PM ttys005 0:00.27 uwsgi --ini uwsgi.ini
501 7760 7758 0 12:13PM ttys005 0:00.27 uwsgi --ini uwsgi.ini
501 7761 7758 0 12:13PM ttys005 0:00.27 uwsgi --ini uwsgi.ini
501 7762 7758 0 12:13PM ttys005 0:00.26 uwsgi --ini uwsgi.ini
501 7763 7758 0 12:13PM ttys005 0:00.00 uwsgi --ini uwsgi.ini
501 7789 6013 0 12:13PM ttys006 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox uwsgi

2、生成 test.txt 时的现象:当 出现 chain reloading complete 时,代表了优雅完成。

Mon Apr 10 12:14:45 2023 - *** /Users/mashili/work/test/py_test/sample_test/flask_graceful_restart/test.txt has been touched... chain reload !!! ***
Mon Apr 10 12:14:45 2023 - chain next victim is worker 1
Gracefully killing worker 1 (pid: 7759)...
Mon Apr 10 12:15:46 2023 - worker 1 (pid: 7759) is taking too much time to die...NO MERCY !!!
worker 1 killed successfully (pid: 7759)
Respawned uWSGI worker 1 (new pid: 7847)
Mon Apr 10 12:15:47 2023 - chain is still waiting for worker 1...
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7fc33e00da00 pid: 7847 (default app)
Mon Apr 10 12:15:48 2023 - chain next victim is worker 2
Gracefully killing worker 2 (pid: 7760)...
Mon Apr 10 12:16:49 2023 - worker 2 (pid: 7760) is taking too much time to die...NO MERCY !!!
worker 2 killed successfully (pid: 7760)
Respawned uWSGI worker 2 (new pid: 7885)
Mon Apr 10 12:16:50 2023 - chain is still waiting for worker 2...
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7fc33e00da00 pid: 7885 (default app)
Mon Apr 10 12:16:51 2023 - chain next victim is worker 3
Gracefully killing worker 3 (pid: 7761)...
Mon Apr 10 12:17:52 2023 - worker 3 (pid: 7761) is taking too much time to die...NO MERCY !!!
worker 3 killed successfully (pid: 7761)
Respawned uWSGI worker 3 (new pid: 7905)
Mon Apr 10 12:17:53 2023 - chain is still waiting for worker 3...
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7fc33e00da00 pid: 7905 (default app)
Mon Apr 10 12:17:54 2023 - chain next victim is worker 4
Gracefully killing worker 4 (pid: 7762)...
Mon Apr 10 12:18:55 2023 - worker 4 (pid: 7762) is taking too much time to die...NO MERCY !!!
worker 4 killed successfully (pid: 7762)
Respawned uWSGI worker 4 (new pid: 7910)
Mon Apr 10 12:18:56 2023 - chain is still waiting for worker 4...
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7fc33e00da00 pid: 7910 (default app)
Mon Apr 10 12:18:57 2023 - chain reloading complete

3、优雅重启过程中,查看进程信息。ps -ef|grep uwsgi

发现即存在新的进程,也存在老的进程。测试的时候,发现,优雅重启过程中,并不一定会将重启过程中的请求转发到新的进程中去。

  501  7758  4633   0 12:13PM ttys005    0:00.08 uwsgi --ini uwsgi.ini
501 7761 7758 0 12:13PM ttys005 0:00.27 uwsgi --ini uwsgi.ini
501 7762 7758 0 12:13PM ttys005 0:00.26 uwsgi --ini uwsgi.ini
501 7763 7758 0 12:13PM ttys005 0:00.00 uwsgi --ini uwsgi.ini
501 7847 7758 0 12:15PM ttys005 0:00.26 uwsgi --ini uwsgi.ini
501 7885 7758 0 12:16PM ttys005 0:00.26 uwsgi --ini uwsgi.ini
501 7889 6013 0 12:17PM ttys006 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox uwsgi

2.5 线上如何更新

1、首先将代码更新到服务器。

2、ps -ef|grep uwsgi 查看现在的进程号。

2、查看 test.txt是否存在,存在就更新文件内容,不存在就生成 test.txt。

3、观察uwsgi的日志或者进程,待所有的worker进程都重启生成后,即完成了优雅重启。

3、gunicorn 如何实现优雅重启

3.1 编写 web 服务

main.py

import time

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
# time.sleep(3)
return "hello fdaf fdafd " if __name__ == "__main__":
app.run()

3.2 编写 conf.py 配置gunicorn 文件

conf.py

# 是否开启debug模式
debug = True
# 访问地址
bind = "0.0.0.0:8888"
# 工作进程数
workers = 2
# 工作线程数
threads = 2
# 超时时间
timeout = 600
# 输出日志级别
loglevel = 'info'
# 存放日志路径
pidfile = "log/gunicorn.pid"
# 存放日志路径
accesslog = "log/access.log"
# 存放日志路径
errorlog = "log/debug.log" ######注意,下面这个不能加,加了就不能达到优雅重启的效果,切记切记!!
# gunicorn + apscheduler场景下,解决多worker运行定时任务重复执行的问题
# preload_app = True

3.3 启动 gunicorn 服务

gunicorn -c conf.py main:app

3.4 测试优雅重启

1、pstree -ap|grep gunicorn 找到主进程

pstree -ap|grep gunicorn

2、执行 kill -HUP masterpid

kill -HUP 1540847

3、再次 执行 pstree -ap|grep gunicorn,发现worker 进程id不一样后,即更新完成。或者查看日志

[2023-04-10 15:36:51 +0800] [11623] [INFO] Handling signal: hup
[2023-04-10 15:36:51 +0800] [11623] [INFO] Hang up: Master
[2023-04-10 15:36:51 +0800] [11681] [INFO] Booting worker with pid: 11681
[2023-04-10 15:36:51 +0800] [11682] [INFO] Booting worker with pid: 11682
[2023-04-10 15:36:51 +0800] [11644] [INFO] Worker exiting (pid: 11644)
[2023-04-10 15:36:51 +0800] [11645] [INFO] Worker exiting (pid: 11645)

3.5 线上如何更新

1、通过 pstree -ap|grep gunicorn 找到主进程ID

2、执行 kill -HUP masterpid 命令

3、等待gunicorn优雅重启完成

01、uwsgi、gunicorn如何实现优雅重启的更多相关文章

  1. Apache 优雅重启 Xampp开机自启 - 【环境变量】用DOS命令在任意目录下启动服务

    D:\xampp\apache\bin\httpd.exe" -k runservice Apache 优雅重启 :httpd -k graceful Xampp开机自启动  参考文献:ht ...

  2. Spring Boot 1.X和2.X优雅重启实战

    纯洁的微笑 今天 项目在重新发布的过程中,如果有的请求时间比较长,还没执行完成,此时重启的话就会导致请求中断,影响业务功能,优雅重启可以保证在停止的时候,不接收外部的新的请求,等待未完成的请求执行完成 ...

  3. [译]Golang中的优雅重启

    原文 Graceful Restart in Golang 作者 grisha 声明:本文目的仅仅作为个人mark,所以在翻译的过程中参杂了自己的思想甚至改变了部分内容,其中有下划线的文字为译者添加. ...

  4. apache2 重启、停止、优雅重启、优雅停止

    停止或者重新启动Apache有两种发送信号的方法 第一种方法: 直接使用linux的kill命令向运行中的进程发送信号.你也许你会注意到你的系统里运行着很多httpd进程.但你不应该直接对它们中的任何 ...

  5. Golang开发支持平滑升级(优雅重启)的HTTP服务

    Golang开发支持平滑升级(优雅重启)的HTTP服务 - tabalt的博客 http://tabalt.net/blog/graceful-http-server-for-golang/ http ...

  6. Golang的优雅重启

    更新(2015年4月):Florian von Bock已将本文中描述的内容转换为一个名为endless的优秀Go包 . 如果您有Golang HTTP服务,可能需要重新启动它以升级二进制文件或更改某 ...

  7. uWSGI, Gunicorn, 啥玩意儿?

    因为nginx等优秀的开源项目,有不少本来不是做服务器的同学也可以写很多服务器端的程序了.但是在聊天中会发现,大家虽然写了不少代码,但是对wsgi是什么,gunicorn是什么,反向代理又是什么并不了 ...

  8. 关于nginx做代理,uwsgi gunicorn等服务器做后端时

    (1) 响应数据过大 被截断的问题 通常看buffers参数的设置(缓冲从后端服务器的应答) uwsgi的参数是 uwsgi_buffers 4 128k gunicorn 设置代理参数 proxy_ ...

  9. Docker容器优雅重启

    默认情况下,当 Docker 守护进程终止时,它将关闭正在运行的容器.您可以配置守护程序,以便容器在守护程序不可用时保持运行.此功能称为live-restore.live-restore选项有助于减少 ...

  10. 优雅的重启uwsgi 告别uwsgi reload过程中造成的无法请求、请求延迟等问题

    [uwsgi]#使用优雅重启 lazy-apps = true #监听monitor文件 当monitor文件发生改变是重启uwsgi touch-chain-reload = /home/monit ...

随机推荐

  1. 通过写脚本的方式自动获取JVM内的进程堆栈信息等内容

    公司转java之后 经常会遇到java进程占用CPU特别多的情况. 每次连上机器进行处理都比较慢了. 索性自己写一个脚本, 把想要查询的信息直接汇总进去. 这样的话 就简单很多了. 脚本也很简单主要如 ...

  2. IPV6的简单学习与整理

    背景 大概2018年时曾经突击学习过一段时间IPV6 当时没太有写文档的习惯,导致这边没有成型的记录了. 今天又有项目要求使用IPV6, 想了想就将之前学习的部分 还有想继续学习提高的部分进行一下总结 ...

  3. Nginx 解决 413 问题的配置.

    Nginx 解决 413 问题的配置. Nginx 容易出现一个错误提示问题: worker_processes 1; events { worker_connections 1024; } http ...

  4. 【K哥爬虫普法】老铁需要车牌靓号吗?判刑的那种

    我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识, ...

  5. [2] HEVD 学习笔记:栈溢出漏洞训练

    2. HEVD 栈溢出漏洞训练 2.1 漏洞原理 ​ 当函数退出的时候,会将保存在栈中的返回地址取出,跳转到该地址继续执行,以此来执行函数调用以后的程序.而如果用户的输入没有得到控制,覆盖掉了这个返回 ...

  6. Asp .Net Core 部署在阿里云Centos上 :使用Docker部署

    参照 https://www.cnblogs.com/xiaxiaolu/p/9973631.html 运行环境 使用SecureCrt连接服务器 1.阿里云ECS 4核 16 GiB 8Mbps 带 ...

  7. 【踩坑记录】SpringBoot跨域配置不生效

    问题复现: 明明在拦截器里配置了跨域,就是不生效,使用PostMan等后端调试工具调试,均正常,Response中有Access-Control-Allow-Origin: *,这个Header,但是 ...

  8. 【四】多智能体强化学习(MARL)近年研究概览 {Learning cooperation(协作学习)、Agents modeling agents(智能体建模)}

    相关文章: [一]最新多智能体强化学习方法[总结] [二]最新多智能体强化学习文章如何查阅{顶会:AAAI. ICML } [三]多智能体强化学习(MARL)近年研究概览 {Analysis of e ...

  9. C/C++ 提权与强制卸载DLL

    权限提升 #include <Windows.h> #include <stdio.h> BOOL SetPrivilege(LPCTSTR lpszPrivilege, BO ...

  10. 最新力作,爱来自rand函数

    AWCU47EF;D5F]ET[a8a9K6G5IRHB6RS\cD8YDC:AGN<Z@6ZI3ab8D3O3La7:Sc;5_B]BS5S6Q]baWGcTE94IX7cW=9F>BJ ...