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. [转帖]Redis命令详解:Keys

    https://jackeyzhe.github.io/2018/09/22/Redis%E5%91%BD%E4%BB%A4%E8%AF%A6%E8%A7%A3%EF%BC%9AKeys/ 介绍完Re ...

  2. Linux的free命令与OOM的简单总结

    简介 查看操作系统配置最关键的几个命令是 lscpu 查看CPU信息 以及free 查看内存信息. 不过free信息有一个疑惑点 他的 free的值可能很小. 会让搭建产生误解. 这里简单说明一下. ...

  3. window.addEventListener注册滚动scroll事件不生效

    先了解一下滚动事件触发的条件 视图或者一个元素在滚动时,会触发元素的 scroll 事件. 备注: 在 iOS UIWebViews 中,滚动进行时不会触发 scroll 事件:只有当滚动结束后事件才 ...

  4. Vue基础系列文章10---单文件组件

    1.单文件组件的结构 <template> <!--这里用于定义VUE组件的模块内容--> <dvi> <h1>这是 APP 根组件</h1> ...

  5. TienChin 渠道管理-权限分配

    添加权限 如果您不想手动添加可以使用我如下的SQL,但是有一个注意点就是 parent_id 是渠道管理菜单的主键 id 即可一键插入. INSERT INTO `TienChin`.`sys_men ...

  6. 深度学习应用篇-推荐系统[11]:推荐系统的组成、场景转化指标(pv点击率,uv点击率,曝光点击率)、用户数据指标等评价指标详解

    深度学习应用篇-推荐系统[11]:推荐系统的组成.场景转化指标(pv点击率,uv点击率,曝光点击率).用户数据指标等评价指标详解 1. 推荐系统介绍 在网络技术不断发展和电子商务规模不断扩大的背景下, ...

  7. 4.9 x64dbg 内存处理与差异对比

    LyScript 插件中针对内存读写函数的封装功能并不多,只提供了最基本的内存读取和内存写入系列函数的封装,本章将继续对API接口进行封装,实现一些在软件逆向分析中非常实用的功能,例如ShellCod ...

  8. python函数:匿名函数,闭包,装饰器

    匿名函数 可以只有一个入参或多个入参,但返回值只能是一个函数 #普通函数 def sum(a,b): return a+b #等价的匿名函数 add = lambda a,b: a+b  闭包 举一个 ...

  9. 基于Wireshark的ARP协议分析和IP报文、ICMP报文的分析|网络数据抓包|课程设计|traceroute|ping|

    前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总https://blog.cs ...

  10. 自定义RecyclerView下拉刷新上拉加载更多

    自定义ListView下拉刷新上拉加载更多 自定义RecyclerView下拉刷新上拉加载更多