Python大資料開發技術學習,程式中不同的重啟機制

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

科多大資料帶你看看,大資料開發技術學習之Python程式中不同的重啟機制

分析典型案例:

Celery 分布式非同步任務架構

Gunicorn Web容器

之所以挑這兩個,不僅僅是應用廣泛,而且兩個的進程模型比較類似,都是Master、Worker的形式,在熱重啟上思路和做法又基本不同,比較有參考意義


知識點:

atexit

os.execv

模組共用變數

訊號處理

sleep原理:select

檔案描述符共用

這幾個知識點不難,區別只在於Celery和Gunicorn的應用方式。如果腦海中有這樣的知識點,這篇文章也就是開闊下視野而已。。。

Celery和Gunicorn都會在接收到HUP訊號時,進行熱重啟操作

Celery的重啟:關舊Worker,然後execv重新啟動整個進程

Gunicorn的重啟:建立新Worker,再關舊Worker,Master不動

下面具體的看下它們的操作和核心代碼。

對於Celery:

def _reload_current_worker():

platforms.close_open_fds([

sys.__stdin__, sys.__stdout__, sys.__stderr__,

])

os.execv(sys.executable, [sys.executable] + sys.argv)

def install_worker_restart_handler(worker, sig='SIGHUP'):

def restart_worker_sig_handler(*args):

"""Signal handler restarting the current python program."""

import atexit

atexit.register(_reload_current_worker)

from celery.worker import state

state.should_stop = EX_OK

platforms.signals[sig] = restart_worker_sig_handler

HUP上掛的restart_worker_sig_handler 就做了兩件事:

註冊atexit函數

設定全域變數

考慮到這個執行順序,應該就能明白Celery 是Master和Worker都退出了,嶄新呈現。。


python零基礎開發入門視頻教學

看過APUE的小夥伴,應該比較熟悉 atexit 了,這裡也不多說。os.execv還挺有意思,根據Python文檔,這個函數會執行一個新的函數用於替換掉 當前進程 ,在Unix裡,新的進程直接把可執行程式讀進進程,保留同樣的PID。

在Python os標準庫中,這是一整套基本一毛一樣的函數,也許應該叫做函數族了:

os. execl ( path , arg0 , arg1 , … )

os. execle ( path , arg0 , arg1 , … , env )

os. execlp ( file , arg0 , arg1 , … )

os. execlpe ( file , arg0 , arg1 , … , env )

os. execv ( path , args )

os. execve ( path , args , env )

os. execvp ( file , args )

os. execvpe ( file , args , env )

以exec開頭,尾碼中的l和v兩種,代表命令列參數是否是變長的(前者不可變),p代表是否使用PATH定位程式檔案,e自然就是在新進程中是否使用ENV環境變數了

然後給worker的state.should_stop變數設定成False。。。 模組共用變數 這個是PythonFAQ裡提到的一種方便的跨模組訊息傳遞的方式,運用了Python module的單例。我們都知道Python只有一個進程,所以單例的變數到處共用

而should_stop這個變數也是簡單粗暴,worker在執行任務的迴圈中判斷這個變數,即執行非同步任務->查看變數->獲得非同步任務->繼續執行 的迴圈中,如果True就拋出一個【應該關閉】異常,worker由此退出。

這裡面有一個不大不小的坑是:訊號的發送對於外部的工具,例如kill,是非阻塞的,所以當HUP訊號被發出後,worker可能並沒有完成重啟(等待正在執行的舊任務完成 才退出和建立),因此如果整個系統中只使用HUP訊號挨個灰階各個機器,那麼很有可能出現全部worker離線的情況

接下來我們看看Gunicorn的重啟機制:

訊號實質上掛在在Arbiter上,Arbiter相當於master,守護和管理worker的,管理各種訊號,事實上它init的時候就給自己起好Master的名字了,列印的時候會打出來點選連結加入群【我愛python大神】:https://jq.qq.com/

class Arbiter(object):

def __init__(self, app):

#一部分略

self.master_name = "Master"

def handle_hup(self):

"""\

HUP handling.

- Reload configuration

- Start the new worker processes with a new configuration

- Gracefully shutdown the old worker processes

"""

self.log.info("Hang up: %s", self.master_name)

self.reload()

這裡的函數文檔裡寫了處理HUP訊號的過程了,簡單的三行:

讀取配置

開啟新worker

優雅關閉舊Worker

reload函數的實現本身沒什麼複雜的,因為Gunicorn 是個Web容器,所以master裡面是沒有商務邏輯的,worker都是master fork出來的,fork是可以帶著檔案描述符(自然也包括socket)過去的。這也是Gunicorn可以隨意增減worker的根源

master只負責兩件事情:

拿著被Fork的worker的PID,以供關閉和處理

1秒醒來一次,看看有沒有worker逾時了需要被幹掉

while True:

sig = self.SIG_QUEUE.pop(0) if len(self.SIG_QUEUE) else None

if sig is None:

self.sleep()

self.murder_workers()

self.manage_workers()

continue

else:

#處理訊號

在sleep函數中,使用了select.select+timeout實現,和time.sleep的原理是一樣的,但不同之處在於select監聽了自己建立的一個PIPE,以供wakeup立即喚醒點選連結加入群【我愛python大神】:https://jq.qq.com/

總結

以上就介紹了Celery和Gunicorn的重啟機制差異。

從這兩者的設計來看,可以理解他們這樣實現的差異。

Celery是個分布式、非同步任務隊列,任務資訊以及排隊資訊實質上是持久化在外部的MQ中的,例如RabbitMQ和redis,其中的持久化方式,這應該另外寫一篇《進階訊息佇列協議AMQP介紹》,就不在這裡說了,對於Celery的Master和Worker來說,可以說是完全沒有狀態的。由Celery的部署方式也可以知道,近似於一個服務發現的架構,下線的Worker不會對整個分布式系統帶來任何影響。唯一的例外可能是Beat組件,作為Celery定時任務的節拍器,要做少許改造以適配分布式的架構,並且實現Send Once功能。

Gunicorn作為Python的Web容器之一,會接收使用者的請求,雖然我們通常都會使用nginx放在Gunicorn前方做反向 Proxy,通常也可以使用nginx來做upstream offline、online的熱重啟,但那就不是一個層次的事情了

這裡回頭來再吐槽Golang

項目中使用到了Golang的一個Web架構,Golang在1.8中也已經支援Http.Server的熱關閉了,但是一是因為剛出不就(竟然現在才出),二是因為Golang的進程模型和Python大相近庭,go協程嘛,目前還沒有看到那個Web架構中真正實現Gunicorn類似的熱重啟。

Golang 在fcgi的操作應該就類似Python之於wsgi了。。我感覺我是選擇錯了一個web架構

也沒看見有人用syscall.Exec來用一下execve系統調用,Golang也沒看見有人用socket REUSE。。作為一個懶惰的人感覺很蛋疼。。。

先讓nginx大法做這件事情好了。

也可以加下python大神QQ群:304-050-799

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.