多態 編譯時的多態:方法重載 運行時的多態:動態綁定 多態的三大前提 類之間要有繼承關係 要出現方法重寫 父類的引用指向了子類的對象 測試樣例 // 定義Person類 public class Person { public String name; public String sex; publ ...
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 測試優雅重啟
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優雅重啟完成