国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Python程序中不同的重啟機制

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

 [[189945]]

分析典型案例:

  1. Celery 分布式異步任務框架
  2. Gunicorn Web容器

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

知識點:

  • atexit
  • os.execv
  • 模塊共享變量
  • 信號處理
  • sleep原理:select
  • 文件描述符共享

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

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

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

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

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

對于Celery:

  1. def _reload_current_worker(): 
  2.     platforms.close_open_fds([ 
  3.         sys.__stdin__, sys.__stdout__, sys.__stderr__, 
  4.     ]) 
  5.     os.execv(sys.executable, [sys.executable] + sys.argv) 
  6.   
  7.   
  8.    
  9. def install_worker_restart_handler(worker, sig='SIGHUP'): 
  10.     def restart_worker_sig_handler(*args): 
  11.         """Signal handler restarting the current python program.""" 
  12.         import atexit 
  13.         atexit.register(_reload_current_worker) 
  14.         from celery.worker import state 
  15.         state.should_stop = EX_OK 
  16.     platforms.signals[sig] = restart_worker_sig_handler 

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

  1. 注冊atexit函數
  2. 設置全局變量

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

看過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。。。 模塊共享變量 這個是 Python FAQ里提到的一種方便的跨模塊消息傳遞的方式,運用了Python module的單例。我們都知道Python只有一個進程,所以單例的變量到處共享

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

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

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

信號實質上掛在在Arbiter上,Arbiter相當于master,守護和管理worker的,管理各種信號,事實上它init的時候就給自己起好Master的名字了,打印的時候會打出來:

  1. class Arbiter(object): 
  2.     def __init__(self, app): 
  3.         #一部分略 
  4.         self.master_name = "Master"    
  5.     def handle_hup(self): 
  6.         """\ 
  7.         HUP handling. 
  8.         - Reload configuration 
  9.         - Start the new worker processes with a new configuration 
  10.         - Gracefully shutdown the old worker processes 
  11.         ""
  12.         self.log.info("Hang up: %s", self.master_name) 
  13.         self.reload() 

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

  1. 讀取配置
  2. 開啟新worker
  3. 優雅關閉舊Worker

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

master只負責兩件事情:

  1. 拿著被Fork的worker的PID,以供關閉和處理
  2. 1秒醒來一次,看看有沒有worker超時了需要被干掉
  1. while True
  2.     sig = self.SIG_QUEUE.pop(0) if len(self.SIG_QUEUE) else None 
  3.     if sig is None: 
  4.         self.sleep() 
  5.         self.murder_workers() 
  6.         self.manage_workers() 
  7.         continue 
  8.     else
  9.         #處理信號 

在sleep函數中,使用了select.select+timeout實現,和time.sleep的原理是一樣的,但不同之處在于select監聽了自己創建的一個PIPE,以供wakeup立即喚醒

總結

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

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

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

Gunicorn作為Python的Web容器之一,會接收用戶的請求,雖然我們通常都會使用nginx放在Gunicorn前方做反向代理,通常也可以使用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大法做這件事情好了。

責任編輯:武曉燕 來源: 36大數據
相關推薦

2024-11-21 12:00:00

字典緩存Python

2009-03-31 11:08:26

B-Tree索引數據庫

2010-02-01 18:13:34

Python

2024-04-24 12:03:20

2017-06-12 17:38:32

Python垃圾回收引用

2011-06-09 14:34:04

C++NVI

2011-06-09 15:04:22

RAII機制

2011-06-09 14:52:09

Pimpl機制

2022-02-17 20:34:12

Python短路機制開發

2011-04-19 10:53:05

SSAS

2015-07-29 13:37:41

妹子處理

2013-03-28 09:07:37

Android開發Intent機制

2017-05-15 19:40:40

AndroidIPC機制

2012-03-01 14:13:36

Java

2010-02-26 13:34:50

WCF編碼機制

2023-03-26 22:48:46

Python引用計數內存

2010-12-23 13:56:55

SharePointIntranet

2011-05-24 09:15:26

JavaC#

2012-08-03 09:46:09

Zend Framew

2009-09-29 10:45:17

UnixLinuxshell
點贊
收藏

51CTO技術棧公眾號

污污的网站18| 日韩av综合| 亚洲色图视频网站| 4444亚洲人成无码网在线观看| 亚洲激情午夜| 91在线观看免费| 97视频热人人精品免费| 国产成人精品一区| 日本午夜精品久久久| 久久亚洲精品一区二区| 久草在线视频网站| 精品久久久久99| 成人影音在线| 亚洲福利视频在线| 欧美日韩一级二级三级| hbad中文字幕| 中文字幕一区二区视频| 国产三级视频| 一区二区三区精品视频在线| 好吊妞这里只有精品| 一区二区在线观看视频| 婷婷六月天丁香| 亚洲美女在线国产| 永久www成人看片| 精品国产乱码久久久久久婷婷| 香蕉视频在线观看免费| 欧美色videos| 99re视频在线观看| **女人18毛片一区二区| 91视频免费在线观看| 国产精品v一区二区三区| 日韩一区二区免费视频| 日本天码aⅴ片在线电影网站| 日韩午夜在线观看| 女厕盗摄一区二区三区| 日韩中文字幕网址| 国产精品chinese在线观看| 欧美在线激情视频| 亚洲女同一区| 午夜欧美性电影| 成人免费精品视频| 91xxxxx| 91福利在线观看| 国产精品探花在线| 欧美巨乳在线观看| 久久一区二区中文字幕| 久久96国产精品久久99软件| 精品系列免费在线观看| 精品久久一二三| 亚洲精品五月天| 黄色精品免费看| www.日韩不卡电影av| 九九热线有精品视频99| 国产欧美在线一区二区| 69堂精品视频在线播放| 久久精品国产91精品亚洲| 亚洲精华一区二区三区| 国产精品日本一区二区| 国产精品一区一区| 日本aa大片在线播放免费看| 3751色影院一区二区三区| 成人四虎影院| 国产精品亚洲片夜色在线| 视频一区视频二区中文| 一本久道中文无码字幕av| 一本一道久久a久久精品| 成人免费网站观看| 欧美在线一区二区三区四| 99精品久久久| 精品久久久噜噜噜噜久久图片| 欧洲视频一区二区| 在线免费成人| 精品视频在线观看| 欧美国产精品一区二区三区| 黄色小网站在线观看| 韩国欧美亚洲国产| 欧美aⅴ一区二区三区视频| 黄色一级片视频| 日韩精品小视频| 99精品综合| 欧美成人精品欧美一级乱| 欧美年轻男男videosbes| caoporn成人免费视频在线| 欧美成人蜜桃| 亚洲精品伦理在线| 在线天堂新版最新版在线8| 在线免费一区三区| 欧美视频免费看| 国产成人精品日本亚洲11| 久久久久久日产精品| 日韩123区| 国产视频999| 久久亚洲一级片| 91在线三级| 亚洲一区二区三区香蕉| 国产日韩成人精品| 亚洲女色av| 精品久久蜜桃| 午夜视黄欧洲亚洲| 9l视频自拍蝌蚪9l视频成人| 尤物国产精品| 欧美乱妇一区二区三区不卡视频| 欧美久久香蕉| 欧美日本视频在线观看| 精品成人一区二区| 成人一区不卡| 国产主播中文字幕| 91美女视频网站| 啦啦啦中文在线观看日本| 亚洲一区亚洲二区| 最新日韩av在线| 欧美大片网站| 无码人妻精品一区二区三区99v| 色婷婷色综合| 狠狠热免费视频| 在线视频欧美性高潮| jizzjizz少妇亚洲水多| 日韩电影天堂视频一区二区| 一本大道久久a久久精二百| 亚洲精品中文字幕99999| 久章草在线视频| 丝袜情趣国产精品| 精品亚洲porn| 手机在线免费观看av| 国模精品一区二区三区| 色婷婷激情综合| 性欧美欧美巨大69| 在线国产三级| 91精品久久久久久久久不口人| 亚洲人成网站精品片在线观看| 精品午夜视频| 国产97在线|亚洲| 国产精品卡一卡二卡三| www.成人在线视频| 女人色极品影院| 中文字幕欧美视频在线| 麻豆国产欧美一区二区三区| 成人免费网址| 国产乱子伦精品| 337p亚洲精品色噜噜| 亚洲免费婷婷| av漫画网站在线观看| 欧美性视频在线播放| 亚洲性69xxxbbb| 美女网站色精品尤物极品姐弟| 免费午夜视频在线观看| 欧美激情二区三区| 99视频精品全国免费| 成人在线小说| 成人精品网站在线观看| 欧美视频自拍偷拍| 日韩精品色哟哟| 亚洲午夜天堂| 日本网站免费在线观看| 97av视频在线| 中文字幕综合网| 午夜片欧美伦| 成a人片在线观看| 中国一级黄色录像| 另类专区欧美制服同性| 最新热久久免费视频| 91麻豆国产自产在线观看亚洲 | 精品视频亚洲| 国产天堂在线| 亚洲免费视频一区| www.久久久久| 一区二区三区中文字幕精品精品| 99久久亚洲精品| 亚洲图区一区| 人妻精品无码一区二区三区 | 国产成人精品亚洲日本在线观看| 午夜免费福利小电影| 97色在线播放视频| 一本色道久久综合狠狠躁的推荐 | 久热精品视频在线免费观看| 亚洲男帅同性gay1069| 欧美日韩国内| 东北少妇不带套对白| 国内精品400部情侣激情| 亚洲成人动漫av| 久久蜜桃精品| 秋霞一区二区| avav免费在线观看| 亚欧无线一线二线三线区别| 国产噜噜噜噜噜久久久久久久久| 日韩视频在线观看一区二区| 91网址在线看| 欧美xxx在线观看| 久久亚洲一区二区三区明星换脸| 久久中文在线| 99久久精品国产导航| 肉丝一区二区| 欧美自拍偷拍午夜视频| 欧美一区二区三区免费视频| 成人免费观看视频| 天天久久综合| 成人亚洲视频| 国产福利在线| 国产v亚洲v天堂无码久久久| 精品伦精品一区二区三区视频|