Gunicorn啟動Thrift服務

2021-07-11 14:02:18 字數 4115 閱讀 6464

開始寫部落格,記錄,總結,分享。

今天寫一下關於gunicorn和thrift的使用,也是最近做專案時用到的技術。關於thrift,網上都有很多介紹,不必多說。thrift支援很多語言,我們現在需要用到python做一些服務的事情,所以下面主要說的是thrift server端的內容。雖說是針對thrift的內容,但是thrift只是問題所在,主要的解決方式是使用gunicorn,所以後面說的主要是gunicorn的內容。

thrift裡面有介紹各種server型別以及如何啟動,類似於以下這種(摘自於thrift/tutorial/py原始碼):

handler = calculatorhandler()

processor = calculator.processor(handler)

transport = tsocket.tserversocket(port=9090)

tfactory = ttransport.tbufferedtransportfactory()

pfactory = tbinaryprotocol.tbinaryprotocolfactory()

server = tserver.t******server(processor, transport, tfactory, pfactory)

server.serve()

thrift支援多執行緒的server用於提高併發處理能力,如 tserver.tthreadedserver 和 tserver.tthreadpoolserver。但僅這些離實際的分布式系統使用還不夠,還需做一些工作。受限於gil,python多執行緒並不能很好的利用多核cpu。可以對此做測試,即使用tthreadpoolserver啟動server,在我8核電腦環境下,cpu使用率也上不了100%,好尷尬啊。

對於高併發後台服務,還需要考慮以下問題:

- 集群下如何部署啟動;

- 服務掛了如何自動恢復以保持可用;

- client端如何找到server位址及埠,也就是服務發現的問題。

thrift並沒有在這方面做什麼內容,或者說這些並不算它應包含的範疇之內,但是實際的後台應用都需要涉及這些內容。

class

arbiter

(object):

defrun

(self):

# 程式入口,在master程序中,start建立socket,manage管理worker程序

self.start()

self.manage_workers()

defstart

(self):

self.listeners = create_sockets() # 在master中建立socket,監聽埠

defmanage_workers

(self):

self.spawn_workers() # master程序管理worker

defspawn_workers

(self):

self.spawn_worker()

defspawn_worker

(self):

# 建立worker類的物件,worker_class就是使用者選擇的worker種類,包括sync、gevent等

pid = os.fork() # fork出worker程序

worker.init_process() # worker程序初始化,開始執行

說了這麼多,master-worker模型有啥好處?

多程序當然比單程序能支撐更多請求,而且由於是多程序模型,每個程序各自處理請求,某個程序掛了不會影響其他程序的服務。而且master會隨時監控worker程序的狀態,具有自動恢復工作程序的能力。

這是官方找出的使用方法,當然可選的引數設定還有:

-c config, --config=config, 指定config檔案

-b bind, --bind=bind, 指定繫結埠

-k workerclass, --worker-class=workerclass,指定worker-class型別

...

出來的,動態建立設定類,並控制這些類建立時的行為,簡直是藝術!

最後,提一下server hooks配置。從原始碼可以看到,setting的子類裡面,有一部分定義了一些方法,但是沒有實現。剛一開始我很奇怪,函式裡都寫著pass,怎麼用啊。後來檢視gunicorn的example才明白。以when_ready例。在arbiter的start裡面,有呼叫到cfg.when_ready方法,明顯就是呼叫setting裡配置的方法。對於這些server hooks,可以在自己定義的conf檔案裡重新實現這些方法,用來控制自己需要的一些行為。下面是gunicorn的乙個example片段:

bing = '127.0.0.1:8000'

workers = 1

worker_class = 'sync'

loglevel = 'info'

defpost_fork

(server, worker):

server.log.info("worker spawned (pid : %s)", worker.pid)

defwhen_ready

(server):

server.log.info("server is ready. spawning workers")

可以看到,對於server hooks的配置,可以由使用者在conf.py中自己定義具體實現,來控制程式的行為。這一點有時非常重要,後面會講到!!!

前面提到的那個開源專案gunicorn_thrift登場了。

用gunicorn啟動thrift的使用方法,如同gunicorn啟動其它server的方式一樣,就不再贅述了。不同的就是worker類的選擇,選好thrift實現的worker類,選好thrift自身包含的protocol(協議)、transport(傳輸層)等引數,其它的和gunicorn都一致。下面主要說一下,對於上面thrift part部分提到的問題,用gunicorn_thrift如何解決。

對於故障自動恢復問題,主要是關注gunicorn的master程序監控的問題。因為對於worker程序來講,master會自動監控worker程序,所以不需要再另外關注。程序監控,有很多任務具,如god,supervisor等。

在集群上部署(或者說分布式服務),說白了就是在多個伺服器上部署相同的service,對外提供一致服務。其實單機和多機的部署是一樣的,主要的區別是多伺服器下,client端請求如何指向到可用的service位址,將請求分散到不同機器上。對於web應用來說,也就是如何做路由和負載均衡的問題,對於thrift server,同樣也有這個問題。其實對於這個問題,可以拆分成兩個問題,乙個是動態提供集群的可用伺服器位址,另乙個是在此基礎上做負載均衡。對於第乙個問題,也就是服務發現的問題。

服務發現,也就是集群管理(個人理解),有很多解決的利器,常用的有zookeeper、etcd等,下面以zookeeper舉例。當利用集群提供服務,必須知道每台伺服器的狀態,如果有乙個機器上的server掛掉,需要讓client端知道並且把請求分流到其它的server端;如果新加一台server到集群中,同樣的道理,client端請求也可以知道並且把請求流量加到新的服務節點上。如果利用zookeeper做服務發現,一般是用server在zookeeper上建立ephemeral(臨時)節點,這樣當server掛掉的時候,臨時節點也自動刪除,能夠感知server的存在。

gunicorn_thrift提供了這種邏輯!

class

defrun

(self):

if self.cfg.service_register_cls:

service_register_cls = utils.load_obj(self.cfg.service_register_cls)

self.service_watcher = service_register_cls(self.cfg.service_register_conf, self)

instances =

for i in self.cfg.address:

port = i[1]

self.service_watcher.register_instances(instances)

如何使用gunicorn來啟動Django專案

相信熟悉django的小夥伴,一定都知道經典的python manage.py runserver 這個命令來啟動,但是在實際專案中,我們一般不能或者不會使用這種方式來啟動,那麼要怎麼處理呢?接下來,我們來介紹一種現在比較流行的方式 gunicorn方式來啟動。首先,在我們的 目錄中新建乙個虛擬環境...

python操作hbase 基於thrift服務

特別注意 thrift thrift2,新版本的hbase,預設使用thrift2,而thrift2相比thrift,去掉了很多對hbase的命令支援。如果你要換用thrift,只要停止thrift2 服務,啟動thrift服務即可 啟動 停止命令 hbase bin hbase daemon.sh...

gunicorn工作原理

gunicorn 綠色獨角獸 是乙個被廣泛使用的高效能的python wsgi unix http伺服器,移植自ruby的獨角獸 unicorn 專案,使用pre fork worker模式,具有使用非常簡單,輕量級的資源消耗,以及高效能等特點。gunicorn pre fork worker模型中...