原文地址:Django 2.1.7 Celery 4.3.0 使用示例,解決Task handler raised error: ValueError('not enough values to unp...python
簡介: Celery 是一個簡單、靈活且可靠的,處理大量消息的分佈式系統,而且提供維護這樣一個系統的必需工具。 它是一個專一於實時處理的任務隊列,同時也支持任務調度。git
使用情景:用戶發起request,並等待response返回。在某些views中,可能須要執行一段耗時的程序,那麼用戶就會等待很長時間,形成很差的用戶體驗,好比發送郵件、手機驗證碼等。 使用celery後,狀況就不同了。 解決:將耗時的程序放到celery中執行。github
celery名詞:redis
安裝包:django
pip3 install -U Celery
pip3 install django-celery==3.3.0
pip3 install "celery[librabbitmq,redis,auth,msgpack]"
複製代碼
版本 celery 4.3.0瀏覽器
1)在assetinfo/views.py文件中建立視圖sayhello。bash
import time
...
def sayhello(request):
print('hello ...')
time.sleep(2)
print('world ...')
return HttpResponse("hello world")
複製代碼
2)在assetinfo/urls.py中配置。服務器
urlpatterns = [
# ex:/assetinfo/sayhello
path('sayhello', views.sayhello, name='sayhello'),
]
複製代碼
3)啓動服務器,在瀏覽器中輸入以下網址:app
http://127.0.0.1:8000/assetinfo/sayhelloasync
4)因爲視圖設置了sleep 2秒,致使瀏覽器過了2秒以後才訪問完成。
5)在項目/settings.py中安裝。
INSTALLED_APPS = (
...
'djcelery',
}
複製代碼
6)建立celery_tasks的包文件,專門存放tasks.py任務腳本
7)在celery_tasks目錄下建立tasks.py文件。
from celery import Celery
import time
# 建立一個Celery類的實例對象
app = Celery('celery_tasks.tasks', broker='redis://127.0.0.1:6379/8')
@app.task
def async_sayhello():
print('hello ...')
time.sleep(2)
print('world ...')
複製代碼
8)打開assetinfo/views.py文件,修改sayhello視圖以下:
from celery_tasks.tasks import async_sayhello
def sayhello(request):
# print('hello ...')
# time.sleep(2)
# print('world ...')
async_sayhello.delay()
return HttpResponse("hello world")
複製代碼
9)執行遷移生成celery須要的數據表。
python3 manage.py migrate
複製代碼
生成表以下:
10)啓動Redis,若是已經啓動則不須要啓動。
[root@server01 ~]# ps -ef | grep redis
root 3694 3462 0 00:41 pts/4 00:00:00 grep --color=auto redis
root 31054 1 0 Jun27 ? 01:12:52 ./redis-server 127.0.0.1:6379
[root@server01 ~]# redis-cli
127.0.0.1:6379>
複製代碼
11)啓動worker。 celery -A celery_tasks.tasks worker --loglevel=info
12 )再次訪問url ,celery執行報錯。
http://127.0.0.1:8000/assetinfo/sayhello
查看報錯以下:
[2019-08-01 00:16:03,062: ERROR/MainProcess] Task handler raised error: ValueError('not enough values to unpack (expected 3, got 0)')
Traceback (most recent call last):
File "g:\python3\python371\lib\site-packages\billiard\pool.py", line 358, in workloop
result = (True, prepare_result(fun(*args, **kwargs)))
File "g:\python3\python371\lib\site-packages\celery\app\trace.py", line 544, in _fast_trace_task
tasks, accept, hostname = _loc
ValueError: not enough values to unpack (expected 3, got 0)
複製代碼
通過查閱資料,發現這是高版本celery運行在win10存在的問題。
13 ) 解決報錯
原網頁:Unable to run tasks under Windows
看別人描述大概就是說win10上運行celery4.x就會出現這個問題,解決辦法以下,原理未知:
先安裝一個eventlet
pip3 install eventlet
複製代碼
而後啓動worker的時候加一個參數,以下:
celery -A <mymodule> worker -l info -P eventlet
複製代碼
正式執行,以下:
(venv) F:\pythonProject\django-pratice>celery -A celery_tasks.tasks worker -l info -P eventlet
-------------- celery@USC2VG2F9NPB650 v4.3.0 (rhubarb)
---- **** -----
--- * *** * -- Windows-10-10.0.17763-SP0 2019-08-01 00:22:21
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app: celery_tasks.tasks:0x1e4a24170f0
- ** ---------- .> transport: redis://127.0.0.1:6379/8
- ** ---------- .> results: disabled://
- *** --- * --- .> concurrency: 12 (eventlet)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. celery_tasks.tasks.async_sayhello
[2019-08-01 00:22:21,629: INFO/MainProcess] Connected to redis://127.0.0.1:6379/8
[2019-08-01 00:22:21,700: INFO/MainProcess] mingle: searching for neighbors
[2019-08-01 00:22:22,913: INFO/MainProcess] mingle: all alone
[2019-08-01 00:22:23,012: INFO/MainProcess] celery@USC2VG2F9NPB650 ready.
[2019-08-01 00:22:23,045: INFO/MainProcess] pidbox: Connected to redis://127.0.0.1:6379/8.
複製代碼
再次訪問http://127.0.0.1:8000/assetinfo/sayhello
執行任務成功,以下: