成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Celery使用過程中遇到的一些問題

開發 項目管理
做項目時,其中用了Celery這種工具。前段時間,遇到過一些問題,解決后沒有進行總結,今天就抽個空把它記錄下來。

 [[335445]]

本文轉載自微信公眾號「新鈦云服」,作者黃平安 。轉載本文請聯系新鈦云服公眾號。

做項目時,其中用了Celery這種工具。前段時間,遇到過一些問題,解決后沒有進行總結,今天就抽個空把它記錄下來。

用過Celery的程序員,都知道它是一種異步執行程序的工具。里面有Worker、Task等概念,這里我就不贅述了。

1、功能需求

在使用Celery的過程中,我需要知道Task的狀態。Task就是異步任務,用戶沒執行一次異步任務,就會新創建一個Task,代表此異步任務。

該Task對象中,包含著許多信息,其中也包括狀態。我的項目中,需要根據Task的狀態來判斷,這次異步任務是否還在執行中。

2、 出現問題

既然,我需要Task的狀態,那我就需要查看Task的狀態怎么獲取啊!我查看了一下Celery的源碼!發現在Celery的AsyncResult對象中,有個state字段。如下圖所示:

根據,該源碼中的注釋說明,該字段有好幾個值。分別是:PENDING、STARTED、RETRY、FAILURE、SUCCESS。

 

然后,我就趕緊寫個demo驗證一下,看看這個state字段是不是我想要的。demo如下:

 

我執行項目中的Celery異步任務,根據我之前查出來的task id。執行demo查詢該Task的狀態。

這時候,問題就出來了,根據demo返回的Task狀態為PENDING。表示Task還在等待中,尚未執行。

這就不對了,此時的狀態應該是STARTED,因為我的Task已經執行好一段時間了,它返回的結果不準確。

3、 解決問題

難道我用的字段不正確,然后我就谷歌搜索。發現Celery官網和網上的大多數反饋也是表示Task的狀態字段就是state。

那我為什么測出的結果和理論的不同呢?然后,我詳細查看Celery的配置,發現了一個參數:CELERY_TRACK_STARTED。

該參數默認是關閉的,表示只要Celery開始執行Task就會追蹤該Task。所以,開啟該參數后,Task的狀態是時刻記在BACKEND中的。

好,我在Celery的配置文件處,加了該參數。

 

然后再執行Celery的異步任務,得到的結果是我想要的。

4、 引申思考以及問題

我的問題是解決了,但是這引起了我對Celery的一些興趣。

當時,我就考慮到,如果我把正在運行中的Task任務,直接kill掉。那么此時我再去看Task的狀態,它會是啥呢?

STARTED,正在執行中的狀態。

而此時,Task已經關掉,它不應該是這種狀態。為此,我猜測這應該是,Task意外結束,沒有改變Task的狀態導致的。

但是這樣就不太好了,因為只要是程序,那它就一定有意外退出的可能。假設,我的項目需要查看Task的狀態,當Task被意外kill掉時,項目中查看Task的狀態就不準確了。

5、 引申問題解決思路一

當時我想:既然Task被kill掉之后,還能顯示運行中,說明此Task的狀態一定是保存在某個地方,我把該Task的數據清空了不就完了。

而Celery的數據存儲,只有可能存在三個地方:使用RabbitMQ的消息代理(BROKER),使用Redis的任務結果保存處(BACKEND),以及文件保存(當然這點基本上沒可能,Celery沒這樣用過,我主要是死馬當活馬醫)。

這三個地方,其實只有Redis可能存放Task的狀態,按照Celery的機制,也只有它最有可能存放。

但是呢?為了弄清Celery的存儲機制,我想試試Celery會把數據存到RabbitMQ中嗎?然后,我執行了,以下命令,清空RabbitMQ隊列。

 

此時,RabbitMQ隊列的數據已經為空。然后我查看Task的狀態,依然還為STARTED。說明不是它存儲Task的狀態。

然后,我進入redis中。使用keys *命令,發現許多帶有celery-task-meta前綴的記錄。

 

后經查明,這些記錄的后綴就是Celery中Task的id。

我根據我的Task的id,查出如下內容:

我們能清晰的看出,內容中Task的狀態為STARTED。這說明的確是存放在Redis中的。然后,我把這條記錄刪除,再執行demo,Task的狀態不再是STARTED,項目中顯示的狀態就正確了。

 

但是,這又引出了一個問題,怎么刪除這條記錄,或者什么時候刪除這條記錄。當然,我們刪除很容易,編程語言的redis模塊或者Celery自己提供的代碼都能刪除。Celery中根據task id刪除backend中的數據。

 

那么,什么時候刪除這條記錄呢?Celery默認的是保留此數據24小時。我左思右想,還是不刪這條記錄了。換種思路解決這個問題吧!

6、 引申問題解決思路二

要知道,Celery的Task是運行在Worker上的。只要判斷此時的Worker程序是否還正常運行,不就可以判斷Task的狀態是否還在運行中了嗎?

說干就干,我們通過ps命令,可以查看Celery運行的程序。

 

然后,我們執行task時,把它本身運行的程序進程pid記錄下來,發現正好就是Worker的進程pid。

這樣就簡單了,我們只需要結合Celery提供查看Task狀態的接口,以及Python提供的Psutil查看進程的模塊。就能最終判斷Task是不是真在運行中。只有Task的狀態為STARTED,并且Task所在的Worker進程在運行中,Task才是真正在運行狀態。

Psutil查看進程是否運行代碼如下:

 

7、 總結

今天只是把我前段時間遇到的問題以及解決思路記錄下來,也沒寫Celery的內部機制等等,這些東西網上一大把,我也不是很有寫它們的必要。

做過幾年的程序員,感觸最多的就是解決問題的思路。一旦遇到某個問題了,一種思路解決不了,可以換種思路解決,另一種思路可能也不一定能完美解決,但可以加深對問題的理解。而怎么想到另一種思路,就需要平時的多積累和提高自己的認知范圍了,這還是比較難的。

 

責任編輯:武曉燕 來源: 新鈦云服
相關推薦

2016-03-23 11:03:40

2021-11-15 15:43:28

Windows 11升級微軟

2024-09-09 08:02:27

2010-06-07 16:51:06

rsync 使用

2011-03-04 13:49:38

FileZilla

2011-04-13 13:54:03

HttpClient

2022-01-16 08:04:44

集群部署canal

2009-12-29 14:14:22

2011-03-08 14:28:03

proftpdGentoo

2022-02-07 00:10:28

Docker容器開發

2018-04-12 09:29:56

HTTP服務器問題

2017-07-03 17:20:55

Android軟鍵盤控制開發問題

2016-10-18 22:10:02

HTTP推送HTML

2010-05-11 19:01:11

Unix系統

2018-06-12 15:39:41

容器部署云平臺

2009-06-12 10:25:42

Webservices

2009-11-02 08:56:17

2010-06-29 16:56:49

SQL Server數

2017-10-13 12:23:17

蘋果

2012-06-25 10:13:00

Java.NET
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产黄色一级电影 | 欧洲av一区| 亚洲国产一区二区三区在线观看 | 热久久免费视频 | 国产亚洲精品综合一区 | 狠狠综合久久av一区二区小说 | 国产九九九 | 国产精品欧美一区二区 | 久久久久久久久国产 | 天天射天天干 | 国产精品视频一二三区 | 亚洲视频中文 | av在线免费网 | 国产一级在线观看 | 久久国产精品久久久久久 | 色婷婷久久久亚洲一区二区三区 | www亚洲免费国内精品 | 91精品国产91久久久久久最新 | 国产精品伦理一区 | 国产一区二区三区久久久久久久久 | 亚洲人人舔人人 | 97视频久久 | 欧美精品在线播放 | 午夜影院在线观看视频 | 亚洲精品视频观看 | 亚洲国产精品99久久久久久久久 | 国产精品一区在线观看你懂的 | 久久久观看| 国产福利一区二区 | 成人美女免费网站视频 | 69av网| 给我免费的视频在线观看 | 欧美国产激情二区三区 | 日韩一区二区在线播放 | www精品美女久久久tv | 正在播放国产精品 | 自拍视频一区二区三区 | 97成人在线 | 日韩一区二区在线视频 | 国偷自产av一区二区三区 | 日本久久网 |