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請求程序處理
defrun(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函式處理,源**如下:
defhandle_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程序在每次輪訓的時候修改該臨時檔案的屬性
defnotify(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程序檢查臨時檔案最新一次修改時間是否超過閾值
deflast_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...