gunicorn不停服重启更新服务

gunicorn不停服重启更新服务

每次项目更新最头疼的就是重启服务的那一段空白期,如果没有负载均衡或者负载均衡没有做好,那么在重启服务的这段时间中都会造成短暂的“宕机”,给用户的体验很不好,gunicorn使用prefork master-worker模型,可以管理自己fork的进程,这就可以让你动态的添加减少worker进程。这次就直接讲gunicorn如何不停机更新服务,这里是官方文档 https://docs.gunicorn.org/en/stable/signals.html

信号

gunicorn是通过信号处理来达到对进程管理的目的,先看一下他接收的几种信号

  • QUIT: 快速关闭

  • TERM: 优雅的关闭。等待worker完成当前请求直到达到超时时间

  • HUP: 重新加载配置,使用新的配置启动新的工作进程,并优雅地关闭较老的工作进程。

  • TTIN: 增加一个进程

  • TTOU: 减少一个进程

  • USR1: 重新打开日志文件

  • USR2: 在线升级gunicorn

  • WINCH: 优雅地关闭守护进程(后台运行的进程)

上面的信号这次只说三个HUP,USR2,TERM

HUP

文档中的意思使用HUP可以达到重启的效果,测试的日志是这样的

[2021-01-21 17:25:14 +0800] [20388] [INFO] Handling signal: hup
[2021-01-21 17:25:14 +0800] [20388] [INFO] Hang up: Master
[2021-01-21 17:25:14 +0800] [29249] [INFO] Booting worker with pid: 29249
[2021-01-21 17:25:14 +0800] [29248] [INFO] Booting worker with pid: 29248
[2021-01-21 17:25:14 +0800] [29250] [INFO] Booting worker with pid: 29250
[2021-01-21 17:25:14 +0800] [28643] [INFO] Shutting down
[2021-01-21 17:25:14 +0800] [28643] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2021-01-21 17:25:14 +0800] [28640] [INFO] Shutting down
[2021-01-21 17:25:14 +0800] [28640] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2021-01-21 17:25:14 +0800] [28642] [INFO] Shutting down
[2021-01-21 17:25:14 +0800] [28642] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2021-01-21 17:25:14 +0800] [28643] [INFO] Finished server process [28643]
[2021-01-21 17:25:14 +0800] [28643] [INFO] Worker exiting (pid: 28643)
[2021-01-21 17:25:14 +0800] [28640] [INFO] Finished server process [28640]
[2021-01-21 17:25:14 +0800] [28640] [INFO] Worker exiting (pid: 28640)
[2021-01-21 17:25:14 +0800] [28642] [INFO] Finished server process [28642]
[2021-01-21 17:25:14 +0800] [28642] [INFO] Worker exiting (pid: 28642)
[2021-01-21 17:25:15 +0800] [29248] [INFO] Started server process [29248]
[2021-01-21 17:25:15 +0800] [29248] [INFO] Waiting for application startup.
[2021-01-21 17:25:15 +0800] [29248] [INFO] ASGI 'lifespan' protocol appears unsupported.
[2021-01-21 17:25:15 +0800] [29248] [INFO] Application startup complete.
[2021-01-21 17:25:15 +0800] [29249] [INFO] Started server process [29249]
[2021-01-21 17:25:15 +0800] [29249] [INFO] Waiting for application startup.
[2021-01-21 17:25:15 +0800] [29249] [INFO] ASGI 'lifespan' protocol appears unsupported.
[2021-01-21 17:25:15 +0800] [29249] [INFO] Application startup complete.</pre>

通过日志可以看到他是先停止了旧进程然后再启动了新的进程,但是从gunicorn源码中看是先启动了进程然后通过进程数和配置的进程数对比来kill掉老的进程:

# 简化后的处理HUP方法
# spawn new workers
for _ in range(self.cfg.workers):
   self.spawn_worker()  # 这里启动了进程
# manage workers
self.manage_workers()  # 这里根据进程启动的时候给的一个age值来kill掉老的进程</pre>
# manage_workers方法
def manage_workers(self):
 """\
 Maintain the number of workers by spawning or killing
 as required.
 """
 if len(self.WORKERS) < self.num_workers:
 self.spawn_workers()
​
 workers = self.WORKERS.items()
 workers = sorted(workers, key=lambda w: w[1].age)
 while len(workers) > self.num_workers:
 (pid, _) = workers.pop(0)
 self.kill_worker(pid, signal.SIGTERM)
​
 active_worker_count = len(workers)
 if self._last_logged_active_worker_count != active_worker_count:
 self._last_logged_active_worker_count = active_worker_count
 self.log.debug("{0} workers".format(active_worker_count),
 extra={"metric": "gunicorn.workers",
 "value": active_worker_count,
 "mtype": "gauge"})

测试了一下也确实会有问题(我用的django3.1服务用的uvicorn,因为uvicorn没有进程管理的功能所以用gunicorn来启动uvicorn,uvicorn官方文档也是这么建议的),在重启的瞬间发起请求会有异常抛出

USR2

It executes a new binary whose PID file is postfixed with .2 (e.g. /var/run/gunicorn.pid.2), which in turn starts a new master process and new worker processes
大概的意思发送USR2信号后会启动新的主进程和工作进程也就是新的master进程和worker进程

先看一下当前的进程(为了方便观看我删除了ps命令结果的最后一列信息):

[root@Luckybamboo report-web]# ps -ef | grep uvicorn.workers
root      9146     1  0 17:30 pts/7    00:00:00 gunicorn
root      9168  9146  1 17:30 pts/7    00:00:00 gunicorn
root      9169  9146  1 17:30 pts/7    00:00:00 gunicorn
root      9170  9146  1 17:30 pts/7    00:00:00 gunicorn

可以看到当前的master进程为9146,工作进程分别为9168,9169,9170

发送信号后的变化为:

[root@Luckybamboo report-web]# kill -USR2 9146
[root@Luckybamboo report-web]# ps -ef | grep uvicorn.workers
root      9146     1  0 17:30 pts/7    00:00:00 gunicorn 
root      9168  9146  1 17:30 pts/7    00:00:00 gunicorn 
root      9169  9146  1 17:30 pts/7    00:00:00 gunicorn 
root      9170  9146  1 17:30 pts/7    00:00:00 gunicorn 
root     11562  9146  9 17:32 pts/7    00:00:00 gunicorn 
root     11564 11562 30 17:32 pts/7    00:00:00 gunicorn 
root     11565 11562 64 17:32 pts/7    00:00:00 gunicorn 
root     11566 11562 60 17:32 pts/7    00:00:00 gunicorn 

这时候可以看到启动了新的master进程11562,新的工作进程11564,11565,11566

这个时候可以通过TERM信号来停止老的进程9146只保留新的进程就可以了

[root@Luckybamboo report-web]# kill -TERM 9146
[root@Luckybamboo report-web]# ps -ef | grep uvicorn.workers
root     11562     1  0 17:32 pts/7    00:00:00 gunicorn 
root     11564 11562  2 17:32 pts/7    00:00:00 gunicorn 
root     11565 11562  2 17:32 pts/7    00:00:00 gunicorn 
root     11566 11562  2 17:32 pts/7    00:00:00 gunicorn

可以看到这时候就只有新的进程了。我期望的是在新的进程启动之后旧的进程将不再处理新的请求,测试了一下确实是这样,但是因为测试的比较少而且源码中没有看到这个逻辑,而且这个信号是用来在线升级gunicorn的,所以最好还是把旧的进程当成正常的进程来看待处理,文档中也说如果不用新的进程可以kill掉新的进程,也可以接着对旧的进程进行各种信号处理,希望有人能补充我这种期望该怎么操作

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容