面試必問的celery,你瞭解多少?

來源商業新知網,原標題:十面九問的逆天異步神器-celery,你瞭解多少?前端

 

celery是什麼,有什麼用?python

對於celery,各類文檔解釋一堆,能夠本身看下,根據平常互動,公衆號用戶小白居多,官方用到的不少名詞可能你理解起來不是那麼容易,我這裏就不照本宣科了,就以我這邊的理解簡單如下方圖示解釋下,若是有誤,歡迎指正:web

首先理解一個概念: 阻塞redis

理解阻塞,先從耗時操做講起,常見的場景好比用戶輸入、等待(sleep)這些都屬於,具體到實際項目中好比說發郵件、發短信、機器/深度學習訓練模型、自動化測試中的各類操做流程等待都會產生耗時,耗時操做一般咱們也會稱之爲阻塞,意思就是程序一行一行代碼執行,你這些耗時操做沒執行完畢,後面的代碼就不會執行,阻塞了後面的代碼執行chrome

理解了阻塞之後,就很容易引出一個問題?我若是想提升程序執行效率不讓程序阻塞,那該怎麼辦?有沒有一種方式,能在程序阻塞的時候,不影響我後面代碼的執行?數據庫

通常來講,咱們能夠用線程、進程、協程,都是能夠實現的,只不過在實際項目中,有成熟開源而且普遍應用的的東西,咱們會用框架,而不去手寫多線程、進程、協程,也不是說這些不用去學,這是編程的基本知識,也是必須掌握的,很能體現編程基本功底django

celery基本原理:編程

一、客戶端也就是python(django/flask等)發佈任務flask

二、發佈的任務存到任務隊列裏面,能夠以redis、rabbitMQ、MessageQueue、MySQL存儲,通常在django/flask程序裏redis居多後端

三、任務處理者會不斷從任務隊列裏面獲取任務執行

知識圖譜,十面九問的逆天異步神器-celery,你瞭解多少?

一、安裝django/celery庫

django==2.0.6

celery==3.1.26

django-celery==3.3.0

redis==2.10.6

都用pip安裝,我這邊這幾個版本測試沒問題,版本有些時候不兼容,若是報錯,網上找下解決

二、redis數據庫安裝

redis安裝:http://www.python88.cn/book/redis10/

注意如下幾點:

一、redis.conf改bind127.0.0.1爲bind 真實ip,這樣能夠遠程訪問

二、若是是阿里雲服務器,須要在控制檯將6379端口開放

三、redis啓動服務端:redis-server,啓動客戶端:redis-cli

三、演示代碼demo

知識圖譜,十面九問的逆天異步神器-celery,你瞭解多少?

總體流程是在前面頁面點擊表格裏面的執行,會用selenium打開瀏覽器,執行耗時操做,至關於每一個執行都是一個單獨耗時任務

四、demo前端代碼:

給按鈕綁定run_case2方法,獲取當前表格行號(映射要用selenium打開的網站連接),做爲參數傳到後端

function run_case2(obj){
    row_tr = obj.parentNode.parentNode.rowIndex;//獲取當前行數
    console.log(row_tr);
    param = {"url":row_tr};
    $.post('/web/yzm/', param, function (data) {
    console.log(data.result)
    })
}

五、demo後端代碼:(阻塞寫法)

看下面代碼,前端傳的行號,我這只是爲了測試傳參數,隨便構造的,分別跟3個網址進行映射,對於下面的這種寫法,就是典型的阻塞線程,webdriver在執行的時候,只有當把quit()關閉瀏覽器執行完畢時候,纔會return返回結果並在控制檯打印success,以下圖演示,我點擊的是第三個執行按鈕

知識圖譜,十面九問的逆天異步神器-celery,你瞭解多少?

from selenium import webdriver
import time
@csrf_exempt
@login_required
def yzm(request):
  url_num = request.POST.get("url")
  if int(url_num)==1:
    url_str = "https://www.baidu.com"
   elif int(url_num==2:
    url_str = "http://www.python66.cn"
   elif int(url_num)==3:
    url_str = "http://www.python88.cn"
   print(url_num,url_str)

  # 下面webdriver打開網站,並休眠5秒鐘都是耗時任務
   driver = webdriver.Chrome(executable_path="C:chromedriver_win32chromedriver.exe")
   driver.get(url_str)
   time.sleep(5)
   driver.quit()

   # 耗時任務執行完畢開始return
   return JsonResponse({"result": "success"})

六、demo後端代碼:(celery異步)

異步: 名字雖然爲異步,你能夠理解爲同步,就是一邊作耗時操做,通常執行後面代碼,二者同時執行

文件目錄,我在項目目錄下面創建了celery_task包,建立tasks.py文件

知識圖譜,十面九問的逆天異步神器-celery,你瞭解多少?

一、建立app,表明一個celery對象,broker表明隊列,用的redis 0號數據庫

二、而後將上一步咱們selenium打開瀏覽器的方法封裝成open_url方法

三、@app.task表明定義任務,指明這個open_url方法是一個任務,能夠在視圖裏面調用發佈

from celery import Celery
from selenium import webdriver
import time

# 建立celery的應用
app = Celery("celery_task", broker="redis://47.101.203.45:6379/0")

@app.task
def open_url(url):
    driver = webdriver.Chrome(executable_path="C:chromedriver_win32chromedriver.exe")
    driver.get(url)
    time.sleep(5)
    driver.quit()

views.py視圖裏面這樣寫

一、from celery_task.tasks import  open_url爲導入任務

二、open_url.delay(url_str)爲發佈任務,其中delay裏面能夠傳參數,你前端傳過來的參數views.py視圖函數接收,能夠再傳到celery任務中去

效果圖以下:當點擊執行時候,return的success很快就返回並打印了,跟我操控瀏覽器的過程沒一點牽涉,無需等待selenium,這樣就實現了非阻塞異步,完美解決了耗時問題

知識圖譜,十面九問的逆天異步神器-celery,你瞭解多少?

from celery_task.tasks import open_url
@csrf_exempt
@login_required
def yzm2(request):
 url_num = request.POST.get("url")
    if int(url_num)==1:
 url_str = "https://www.baidu.com"
    elif int(url_num)==2:
 url_str = "http://www.python66.cn"
 elif int(url_num)==3:
    url_str = "http://www.python88.cn"
 print(url_num,url_str)

 open_url.delay(url_str)
return JsonResponse({"result":"success"})

七、多個任務同時執行

對於多個任務同時執行,我這裏連續點擊三個執行按鈕,立馬先打印了3個success,說明3個任務都被celery異步處理了,對於多任務的參數問題,上面也說了,咱們在delay裏面傳入參數便可,傳到定義任務的tasks.py文件裏面的對於方法中去,本例中我演示的是傳了一個url_str參數

知識圖譜,十面九問的逆天異步神器-celery,你瞭解多少?

八、啓動程序

打開兩個終端,都切換到項目目錄下面

一、先啓動celery:

celery -A celery_task.tasks worker -l info

二、再啓動django:

python manage.py runserver

本文重要的是理解原理,celery的牛逼遠不止於此,有興趣能夠看看在爬蟲、機器學習、深度學習領域的使用,會對celery的使用場景有更清晰的認識

相關文章
相關標籤/搜索