首頁 運維 安全 如何進行gunicorn Arbiter 原始碼解析

如何進行gunicorn Arbiter 原始碼解析

May 12, 2023 pm 04:28 PM
gunicorn arbiter

如前所述,Arbiter是gunicorn master進程的核心。 Arbiter主要負責管理worker進程,包括啟動、監控、殺死Worker進程;同時,Arbiter在某些訊號發生的時候還可以熱更新(reload)App應用,或是在線上升級gunicorn。 Arbiter的核心程式碼在一個檔案裡面,程式碼量也不大,原始碼在此:https://github.com/benoitc/gunicorn。

Arbiter主要有以下方法:

setup:

    處理設定項,最重要的是worker數量和worker工作模型

init_signal:

##    註冊訊號處理函數

handle_xxx:

    個別訊號特定的處理函數

kill_worker,kill_workers:

    向worker程式發出訊號

spawn_worker, spawn_workers:

#    fork出新的worker進程

murder_workers:

    殺死一段時間內未回應的worker進程

manage_workers:

#    根據檔案的worker數量,以及目前active的worker數量,決定是要fork或kill worker程序

reexec

    接收到訊號SIGUSR2調用,線上升級gunicorn

reload:

    接收到訊號SIGHUP調用,會根據新的配置新啟動worker進程,並殺死先前的worker進程

sleep

    在沒有訊號處理的時候,利用select的timeout進行sleep,可被喚醒

wakeup

    透過向管道寫訊息,喚醒進程

run

    主循環

  Arbiter真正被其他程式碼(Application)呼叫的函數只有__init__和run方法,在一句程式碼裡:

    Arbiter(self).run()

  上面程式碼中的self即為Application實例,其中_ _init__呼叫setup進行配置項設定。以下是run方法偽代碼


def run()
    self.init_signal()
    self.LISTENERS = create_sockets(self.cfg, self.log)
    self.manage_workers()    while True:        if no signal in SIG_QUEUE
            self.sleep()        else:
            handle_signal()
登入後複製


# 關於fork子程序

  fork子程序的程式碼在spawn_worker, 原始碼如下:

 Arbiter.spawn_worker如何进行gunicorn Arbiter 源码解析

  主要流程:

    (1)載入worker_class並實例化(預設為同步模型SyncWorker)

    (2)父進程(master進程)fork之後return,之後的邏輯都在子進程中運行

    (3)呼叫worker.init_process 進入循環,新航道雅思培訓的所有工作都在這個循環中

    (4)循環結束之後,呼叫sys.exit(0)

    (5)最後,在finally中,記錄worker進程的退出

#    

    下面是我自己寫的一點程式碼,簡化了主要的fork流程


 1 # prefork.py 2 import sys 3 import socket 4 import select 5 import os 6 import time 7   8 def do_sub_process(): 9     pid = os.fork()10     if pid < 0:11         print &#39;fork error&#39;12         sys.exit(-1)13     elif pid > 0:14         print 'fork sub process %d'  % pid15         return16  17     # must be child process18     time.sleep(1)19     print 'sub process will exit', os.getpid(), os.getppid()20     sys.exit(0)21  22 def main():23     sub_num = 224     for i in range(sub_num):25         do_sub_process()26     time.sleep(10)27     print 'main process will exit', os.getpid()28  29 if __name__ == '__main__':30     main()
登入後複製




在測試環境下輸出:  fork sub process 9601

  fork sub process 9602

  sub process will 9602 9600

  main process will exit 9600

  需要注意的是第20行呼叫了

sys.exit

, 保證子程序的結束,否則會繼續main函數中for迴圈,以及之後的邏輯。註解掉第19行重新運行,看輸出就懂了。
  • 關於kill子程序  master程序要kill worker程序就很簡單了,直接發訊號,原始碼如下:

  • #
     1     def kill_worker(self, pid, sig): 2         """\ 3         Kill a worker 4  5         :attr pid: int, worker pid 6         :attr sig: `signal.SIG*` value 7          """ 8         try: 9             os.kill(pid, sig)10         except OSError as e:11             if e.errno == errno.ESRCH:12                 try:13                     worker = self.WORKERS.pop(pid)14                     worker.tmp.close()15                     self.cfg.worker_exit(self, worker)16                     return17                 except (KeyError, OSError):18                     return19             raise
    登入後複製

  • 關於sleep與wakeup

#  我們再來看看Arbiter的sleep和wakeup。 Arbiter在沒有訊號需要處理的時候會"sleep",當然,不是真正呼叫time.sleep,否則訊號來了也不能第一時間處理。這裡得實現比較巧妙,利用了管道和select的timeout。看程式碼就知道了

        def sleep(self):        """\
        Sleep until PIPE is readable or we timeout.
        A readable PIPE means a signal occurred.        """
            ready = select.select([self.PIPE[0]], [], [], 1.0) # self.PIPE = os.pipe()
            if not ready[0]: 
                return
            while os.read(self.PIPE[0], 1):                pass
登入後複製

  程式碼裡面的註解寫得非常清楚,要嘛PIPE可讀立即返回,要嘛等待逾時。管道可讀是因為有訊號發生。這裡看看pipe函數

############  os.######pipe###()############Create a pipe. Return a pair of file descriptors ###(r,w)### usable for reading and writing, respectively.############  那我們看一下什麼時候管道可讀:一定是往管道寫入的東西,這就是wakeup函數的功能###
        def wakeup(self):            """
            Wake up the arbiter by writing to the PIPE            """
            os.write(self.PIPE[1], b'.')
登入後複製
######最後附上Arbiter的訊號處理###:######退出,INT:快速關閉###### #TERM: 優雅關機。等待工作人員完成其當前請求,直到逾時。 ###

HUP:重新載入配置,用新配置啟動新的工作進程,並優雅地關閉舊的工作進程。如果應用程式未預先載入(使用--preload選項),Gunicorn也會載入新版本。

TTIN:將進程數增加一個

TTOU:將進程數減少一個

USR1:重新開啟日誌檔案

USR2:在飛行中升級Gunicorn。應使用單獨的術語訊號終止舊進程。此訊號也可用於使用預先載入應用程式的新版本。

絞盤:當Gunicorn被守護時,優雅地關閉工作流程。

以上是如何進行gunicorn Arbiter 原始碼解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

一文搞懂 Gunicorn 與 Python GIL 一文搞懂 Gunicorn 與 Python GIL Apr 12, 2023 am 10:40 AM

什麼是 Python GIL,它是如何運作的,以及它如何影響 gun​​icorn。生產環境我該選擇哪一種 Gunicorn worker類型? Python 有一個全域鎖 (GIL),它只允許一個執行緒運行(即解釋字節碼)。在我看來,如果你想優化你的 Python 服務,理解 Python 如何處理並發是必不可少的。 Python 和 gunicorn 為您提供了處理並發的不同方法,並且由於沒有涵蓋所有用例的靈丹妙藥,因此最好了解每個選項的選項、權衡和優勢。 Gunicorn worker類型Gunico

比較Flask應用部署的Gunicorn和uWSGI效能對比 比較Flask應用部署的Gunicorn和uWSGI效能對比 Jan 17, 2024 am 08:52 AM

Flask應用部署:GunicornvsuWSGI的比較引言:Flask作為一種輕量級的PythonWeb框架,受到了許多開發者的喜愛。在將Flask應用程式部署到生產環境時,選擇適合的伺服器閘道介面(ServerGatewayInterface,簡稱SGI)是至關重要的決策。 Gunicorn和uWSGI是兩種常見的SGI伺服器,本文將對它們進行詳細的

深入了解Gunicorn的基本原理與功能 深入了解Gunicorn的基本原理與功能 Jan 03, 2024 am 08:41 AM

Gunicorn的基本概念和作用Gunicorn是一個用於在PythonWeb應用程式中運行WSGI伺服器的工具。 WSGI(Web伺服器閘道介面)是Python語言定義的一種規範,用來定義Web伺服器與Web應用程式之間的通訊介面。 Gunicorn透過實作WSGI規範,使得PythonWeb應用程式可以被部署和運行在生產環境中。 Gunicorn的作用是作

Flask應用的Gunicorn部署指南 Flask應用的Gunicorn部署指南 Jan 17, 2024 am 08:13 AM

如何使用Gunicorn部署Flask應用程式? Flask是一個輕量級的PythonWeb框架,被廣泛應用於開發各種類型的Web應用。而Gunicorn(GreenUnicorn)是一個基於Python的HTTP伺服器,用於運行WSGI(WebServerGatewayInterface)應用程式。本文將介紹如何使用Gunicorn部署Flask應用,並附

Gunicorn是什麼 Gunicorn是什麼 Nov 23, 2023 pm 03:07 PM

Gunicorn是一個用Python編寫的WSGI(HTTP伺服器) Web伺服器網關介面規範,是一個輕量級、高效的伺服器,專門用於運行Python web應用程式。其主要特點和功能包括:1、高效能,可以輕鬆地處理高並發請求;2、穩定可靠,可以提供持久的長時間運行,大大減少了伺服器崩潰的可能性;3、容錯性,可以做到保持服務的穩定性;4、多種部署方式等等。

部署Gunicorn和Flask的無懈可擊的組合 部署Gunicorn和Flask的無懈可擊的組合 Jan 17, 2024 am 10:24 AM

Gunicorn和Flask:完美的部署組合,需要具體程式碼範例概述:對於開發者來說,選擇適合的部署方式是非常重要的,尤其是對於Python的Web應用程式而言。在Python的Web框架中,Flask是非常流行的選擇,而Gunicorn則是一種部署Python應用程式的伺服器。本文將介紹Gunicorn和Flask的組合,並提供一些具體的程式碼範例,以幫助讀者

CentOS安裝Gunicorn及CentOS安裝分區教程 CentOS安裝Gunicorn及CentOS安裝分區教程 Feb 10, 2024 pm 09:20 PM

LINUX是一個強大的作業系統,被廣泛應用於伺服器和開發環境,CentOS是基於RedHatEnterpriseLinux(RHEL)的一個開源作業系統,被廣泛使用於伺服器環境中,在CentOS上安裝Gunicorn和進行分區可以提高伺服器的效能與安全性,本文將詳細介紹如何在CentOS上安裝Gunicorn以及如何進行分割區。 CentOS安裝GunicornGunicorn是一個Python的WSGIHTTP伺服器,用於運行Python的Web應用程序,以下是在CentOS上安裝Gunicorn

提升Flask應用性能的方法:使用Gunicorn 提升Flask應用性能的方法:使用Gunicorn Jan 17, 2024 am 10:42 AM

Gunicorn如何提升Flask應用的效能?隨著網路的快速發展,Web應用程式的效能對於使用者體驗和企業競爭力變得越來越重要。在處理高並發請求時,Flask框架預設的開發伺服器往往無法滿足需求。因此,我們需要使用Gunicorn(GreenUnicorn)來提升Flask應用的效能。 Gunicorn是一個基於Python的HTTP伺服器,它採用了預派生進

See all articles