小計使用多線程和gevent來提升celery性能及穩定性


前言:python

      有朋友問我,我那個任務隊列是怎麼實現,他的疑問其實主要是celery不支持多線程。先說說我那實現的方法,其實個人作法和celery、rq這樣的框架很像的,都是把任務push到隊列裏面,而後pull取出任務而已,celery裏面還能夠取任務,我這個是經過傳送uuid來實現的。   朋友問celery不支持多線程,那是他沒有好好看文檔。celery是支持多任務併發的,哎。。。 好好看文檔呀。mongodb


wKiom1PUqSvjJ3AUAAFdD7oefQQ360.jpg

原文http://rfyiamcool.blog.51cto.com/1030776/1530826 後端


隊列存儲brokers用的是rabbitmq,後面測試下用mongodb搞搞。我這裏作個測試:bash


下面是tasks.py文件,也就是celery能支持異步的函數。多線程

@app.task
def add(x, y):
    wlog()
    sleep(10)
    return x + y

後端啓動含有100個線程的線程池。併發

celery -A tasks worker  -c 100 --loglevel=info


在ipython測試的結果:app

wKioL1PUnXCz20YaAALEUp9RZ9E781.jpg

看看我本身輸出的日誌,結果很明顯,是併發的:框架

wKioL1PUnlvDpRYuAAKEyrHSVHg980.jpg

原文http://rfyiamcool.blog.51cto.com/1030776/1530826 異步

celery是支持好幾個併發模式的,有prefork,threading,協程(gevent,eventlet)ide


prefork在celery的介紹是,用了multiprocess來實現的。多線程就補多少了,估計你們都懂。


說說協程,進程 線程常常玩,也算熟悉,話說協程算是一種輕量級進程,但又不能叫進程,由於操做系統並不知道它的存在。什麼意思呢,就是說,協程像是一種在程序級別來模擬系統級別的進程,因爲是單進程,而且少了上下文切換,因而相對來講系統消耗不多,並且網上的各類測試也代表,協程確實擁有驚人的速度。而且在實現過程當中,協程能夠用之前同步思路的寫法,而運行起來確是異步的,也確實頗有意思。話說有一種說法就是說進化歷程是多進程->多線程->異步->協程,固然協程也有弊端,可是若是你的任務類型不是那種cpu密集的,那選用協程是個好選擇。


可是須要說明的是,雖然celery官網提示說,只要在啓動worker的時候,指明下類型就好了,可是若是你邏輯裏面的模塊有些不支持協程 gevent或者是eventlet異步的話,他仍是會堵塞的。


gevent1.x以後雖然是支持subprocess的用法,gevent這個模塊給非堵塞了,和他有一樣功能的os.popen('sleep 10').read() 是會堵塞的,聽說gevent官方不支持popen的協程的用法。


看了下celery 針對gevent方面的調用,他其實就是引入了gevent的patch  。 那這樣會形成堵塞的問題,若是gevent不支持這些模塊,那。。。。


from gevent import monkey
monkey.patch_all()


反之threading的用法卻是簡單明瞭,支持把任務放在線程pool裏面來處理。



話說回來,個人title爲何說gevent來提升性能。我和小夥伴作一些gevent支持的模塊寫函數,作多任務處理的時候,性能確實要比threading要高,還要穩定。 


小計:

    清理celery產生的數據

#清空
celery purge
#清空
from celery.task.control import discard_all
discard_all()

  查看celery rabbitmq隊列信息

rabbitmqctl list_queues

 


沒了 !

相關文章
相關標籤/搜索