gunicorn syncworker 原始碼解析

2021-09-08 04:25:17 字數 2641 閱讀 5100

gunicorn支援不同的worker型別,同步或者非同步,非同步的話包括基於gevent、基於eventlet、基於aiohttp(python版本需要大於3.3),也有多執行緒的版本。下面是gunicorn當前版本(19.6.0)支援的worker型別:

本文主要對同步模型進行分析。同步模型實現(gunicorn.workers.sync.syncworker)繼承自gunicorn.workers.base.worker,絕大多數方法都是定義在基類,包括

init_signal

註冊訊號處理函式

handle_***:

各個訊號具體的處理函式

notify:

通知父程序自己還活著

run:

需要子類實現的介面,用於處理具體的請求。

init_process:

提供給arbiter的介面,呼叫inti_signal和run方法

syncworker實現了run方法,對http請求程序處理

def

run(self):

if len(self.sockets) > 1:

self.run_for_multiple(timeout)

#使用select

else

: self.run_for_one(timeout)

#如果只有乙個監聽socket,那麼阻塞accept就行了

run方法根據監聽的埠數量進行區分,如果只在乙個埠監聽,那麼呼叫accept; 如果是多個埠,那麼用select輪訓再accept。不管哪種方式,新的連線請求到達後 都呼叫handle_request函式處理,源**如下:

def

handle_request(self, listener, req, client, addr):

environ ={}

resp =none

try:

self.cfg.pre_request(self, req)

request_start =datetime.now()

resp, environ =wsgi.create(req, client, addr,

listener.getsockname(), self.cfg)

#force the connection closed until someone shows

#a buffering proxy that supports keep-alive to

#the backend.

resp.force_close()

self.nr += 1

if self.nr >=self.max_requests:

self.log.info(

"autorestarting worker after current request.")

self.alive =false

respiter =self.wsgi(environ, resp.start_response)

try:

if isinstance(respiter, environ['

']):

resp.write_file(respiter)

else

:

for item in

respiter:

resp.write(item)

resp.close()

request_time = datetime.now() -request_start

self.log.access(resp, req, environ, request_time)

respiter = self.wsgi(environ, resp.start_response)

前面提到

worker通過notify來向master程序做心跳,具體的**在workertmp.py。原理很簡單:

(1)首先通過tempfile.mkstemp建立乙個臨時檔案

(2)worker程序在每次輪訓的時候修改該臨時檔案的屬性

def

notify(self):

try:

self.spinner = (self.spinner + 1) % 2os.fchmod(self._tmp.fileno(), self.spinner)

except

attributeerror:

#python < 2.6

self._tmp.truncate(0)

os.write(self._tmp.fileno(), b"x

")

(3)master程序檢查臨時檔案最新一次修改時間是否超過閾值

def

last_update(self):

return os.fstat(self._tmp.fileno()).st_ctime

references:

signals.html

azkaban web server原始碼解析

azkaban主要用於hadoop相關job任務的排程,但也可以應用任何需要排程管理的任務,可以完全代替crontab。azkaban主要分為web server 任務上傳,管理,排程 executor server 接受web server的排程指令,進行任務執行 1.資料表 projects 工...

JDK LinkedHashMap原始碼解析

今天來分析一下jdk linkedhashmap的源 public class linkedhashmapextends hashmapimplements map可以看到,linkedhashmap繼承自hashmap,並且也實現了map介面,所以linkedhashmap沿用了hashmap的大...

Redux原始碼createStore解讀常用方法

const store createstore reducer,preloadedstate enhancer 直接返回當前currentstate,獲取state值,return state 我覺得應該深轉殖乙個新的物件返回,不然有可能會被外部修改 function getstate consol...