一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 在服務器端實現無間斷部署Python應用的教程

在服務器端實現無間斷部署Python應用的教程

2020-06-08 10:04Python教程網 Python

這篇文章主要介紹了在服務器端實現無間斷部署Python應用的教程,方法主要是Gunicorn進行重載,需要的朋友可以參考下

 當你開始著手部署應用時,最簡單的方式莫過于使用管理員身份重啟my_app或者所有服務,使產品升級至當前版本。開始的時候一切都很好,但是最終你會發現一旦應用啟動以后,在重啟期間去嘗試連接會得到眾多HTTP 503 錯誤。

最后你可能發現Gunicorn和uWSGI可以在不關閉套接字的情況下重新加載你的應用,這樣在你的應用啟動時,網絡請求僅僅是被延時了一點點。只要你的應用不會花費很長時間在啟動上,它就會工作的很好。不幸的是,現有的許多應用可能會花費1分鐘的時間在啟動上,對于等待在套接字上的鏈接來說,這太長了。

Gunicorn使用kill -HUP $PID,通過關閉所有工作進程,然后再啟動它們來重新加載。但是工作進程緩慢的初始化過程往往會導致問題的產生。uWSGI使用鏈式重載,它每次只會啟動一個工作進程。我需要對Tornado的支持,它當前并不十分適合uWSGI。


使用負載均衡器

一種常見的技術是從負載均衡器中移除單個服務器,升級/重啟應用,然后再把它加載回來。我們正在使用負載均衡器,但是為了調度整個過程,在配置節點的時候需要協調使用HAProxy來管理套接字。我們當前的部署方案是同時部署到所有節點,而不是一個接一個的來,一個相當大的變化。在等待LBs(譯注:負載均衡器)將節點移出池期間,可以使用404'ing狀態頁來欺騙healthcheck。這比我想要的時間要多一點,對于每個服務器來說,兩次healthcheck失敗間隔5秒鐘,這包括了升級完成后web進程恢復的時間。

Gunicorn 重載 ++

Gunicorn會自動重啟失敗的web進程,所以它可能會殺掉每個進程,在其間休眠,直到所有的子進程執行完畢。這很有效,不過如果應用啟動的次數變動顯著的話,我們要么會為重啟等待過長時間,要么會等待不長的時間并承擔一些故障宕機的風險。

因為Gunicorn包含了指向應用的Python鉤子,所以完全可能寫出一小段代碼,在工作進程準備就緒的時候通知重啟進程。Gunicorn并不包含需要的鉤子,但做出改變非常簡單。在新版本發布前它需要一些修改。

現在重啟進程發揮了這樣的事實優勢,就是說單個的soket具有接受連接的多個進程。重啟只會極微弱的減少服務能力(1/N),但我們因此可以繼續處理流量而無需讓連接等待過長時間。

這種進程一般是這樣的
 

?
1
2
3
for child_pid of gunicorn-master:
 kill child_pid
 wait for app startup

我的第一個版本使用shell和nc來監聽應用啟動的UDP數據包。盡管將我們的進程管理器集成到shell環境比我預想的要麻煩一點,但它工作的很好。


重啟腳本被調用的時候應該帶上Gunicorn的PID,就是masterrestart.sh的 $PID
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
echo 'Killing children of ' $1;
 
children=$(pgrep -P $1)
for child in $children
do
 echo 'Killing' $child
 kill $child
 response=$(timeout 60 nc -w 0 -ul 4012)
 if [ "$response" != '200 OK' ]; then
  echo 'BROKEN'
  exit 1;
 fi
done

在串聯上post_worker_init腳本,以便app運行的時候通知重啟腳本。
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import socket
import time
 
def post_worker_init(worker):
 _send_udp('200 OK\n')
 
def _send_udp(message):
 
 udp_ip = "127.0.0.1"
 udp_port = 4012
 
 sock = socket.socket(socket.AF_INET, # Internet
       socket.SOCK_DGRAM) # UDP
 sock.sendto(message, (udp_ip, udp_port))
如果我們有這樣一個WSGI( Python Web Server Gateway Interface)應用:
 
from werkzeug.wrappers import Request, Response
 
@Request.application
def application(request):
 resp = Response('Hello World!')
 if request.path == '/_status':
  resp.status = '200 OK'
 else:
  resp.status ='404 Not Found'
 return resp

我們甚至可以去做檢查/_status頁面之類的事情,以此來驗證應用是否已運行。
 

?
1
2
3
4
5
6
7
8
9
def post_worker_init(worker):
 env = {
  'REQUEST_METHOD': 'GET',
  'PATH_INFO': '/_status',
 }
 def start_response(*args, **kwargs):
  _send_udp(args[0])
 
 worker.wsgi(env, start_response)


注意不要試圖在這個健康檢測中運行太多的應用,如果不管什么原因你的post_worker_init產生了一個錯誤,那么工作進程將會退出,并阻止應用的啟動。在你檢查可能失效的DB鏈接的時候這會是一個問題,即使你的應用可以工作,它也無法再次啟動。

現在通過一分鐘的應用啟動,我們實現了滾動重啟,而無需停止應用或者丟棄任何鏈接!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美操大逼视频 | 午夜国产精品福利在线观看 | 日本国产在线视频 | 亚洲国产精品日本无码网站 | 嗯啊在线观看免费影院 | 好男人资源免费播放在线观看 | 乌克兰呦12~14 | 亚洲 日韩 自拍 视频一区 | 成人免费福利网站在线看 | 微福利92合集 | 动漫在线观看h | 视频一区二区三区在线 | 国产一区日韩二区欧美三区 | 日本特级大片 | 日本最大的黄色网站 | 亚洲激情在线视频 | 饭冈加奈子黑人解禁在线播放 | 亚洲高清无在码在线电影 | 女生被爆操 | 闺蜜的样子小说安沁在线阅读 | 把美女屁股眼扒开图片 | 四虎影院久久久 | 粗了大了 整进去好爽视频 刺激一区仑乱 | 91碰碰 | 盲井在线 | 亚洲www美色 | 婷婷综合在线 | 亚洲成人伦理 | 精品日韩欧美一区二区三区在线播放 | 婷婷综合缴情亚洲五月伊 | 91精品国产品国语在线不卡 | 午夜福利理论片在线播放 | 免费的毛片视频 | 插鸡网站 | chinesexxxxhd人妖| 国产精品久久一区 | 亚洲色图影院 | 久久99r66热这里有精品 | 91精品国产高清久久久久 | 亚洲AV无码国产精品色午夜情 | 小鸟酱视频在线观看 |