成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Flask+Celery+Redis實(shí)現(xiàn)隊(duì)列化異步任務(wù)

Ali_ / 1848人閱讀

摘要:使用異步框架,例如等等,裝飾異步任務(wù)。它是一個(gè)專注于實(shí)時(shí)處理的任務(wù)隊(duì)列,同時(shí)也支持任務(wù)調(diào)度。不存儲(chǔ)任務(wù)狀態(tài)。標(biāo)識(shí)要使用的默認(rèn)序列化方法的字符串。指定該任務(wù)的結(jié)果存儲(chǔ)后端用于此任務(wù)。

概述:

????????我們考慮一個(gè)場(chǎng)景,公司有一個(gè)需求,現(xiàn)在需要做一套web系統(tǒng),而這套系統(tǒng)某些功能需要使用一些開(kāi)源工具的sdk和api,或是運(yùn)行一些耗時(shí)比較大的任務(wù)(單個(gè)大任務(wù)下可能有多個(gè)小任務(wù)),需要一段時(shí)間才能提供執(zhí)行結(jié)果,而前端同事要求不能讓用戶在頁(yè)面等待,需要馬上提供一個(gè)返回結(jié)果給他,任務(wù)執(zhí)行完后可以拿到最終結(jié)果,并且用戶退出web界面或?yàn)g覽器異常關(guān)閉之后,再次返回界面,執(zhí)行的過(guò)程不會(huì)中斷,并且支持多用戶同時(shí)執(zhí)行不同操作的需要。

? ? ? ? 很明顯,這是一個(gè)-異步多線程-的場(chǎng)景,在Python中可以想到的有:

????????1.引入Asyncio模塊,利用多協(xié)程實(shí)現(xiàn)。

????????2.使用Threading模塊,自己編寫(xiě)線程任務(wù),線程等待,睡眠,釋放線程的過(guò)程。

????????3.使用異步框架,例如Cerely、Tornado、Twisted等等,裝飾異步任務(wù)。

? ? ? ? 這里邊最便捷且開(kāi)發(fā)效率最高的應(yīng)該是使用異步框架,咱們選擇使用Celery來(lái)實(shí)現(xiàn)這個(gè)需求。

Celery介紹:

? ? ? ? 截圖與描述來(lái)自celery官網(wǎng):Celery - Distributed Task Queue — Celery 5.2.0 documentation

????????Celery 是一個(gè)簡(jiǎn)單、靈活且可靠的分布式系統(tǒng),用于處理大量消息,同時(shí)為操作提供維護(hù)此類(lèi)系統(tǒng)所需的工具。

????????它是一個(gè)專注于實(shí)時(shí)處理的任務(wù)隊(duì)列,同時(shí)也支持任務(wù)調(diào)度。

????????Celery 擁有龐大而多樣化的用戶和貢獻(xiàn)者社區(qū),您應(yīng)該加入我們的 IRC?或我們的郵件列表。

????????Celery 是開(kāi)源的,并在BSD 許可下獲得許可。

消費(fèi)者與消費(fèi)結(jié)果:

????????我們除了需要Celery做異步任務(wù)的處理,還需要一個(gè)中間件來(lái)充當(dāng)消費(fèi)者,并保存最終的任務(wù)處理結(jié)果(消費(fèi)結(jié)果),這里有很多中間件可以選,例如常用的消息中間件,rabbitmq,kafka等,還可以使用mysql,redis等作為消費(fèi)者并保存消費(fèi)結(jié)果(因?yàn)樽罱K的處理結(jié)果要返回給前端同事),樓主最終選擇了redis。

Redis安裝與配置:

????????這里不再贅述windows下安裝redis步驟,只介紹linux下安裝redis與配置,我的機(jī)器是centos7.6:

????????yum方式安裝(注意:這樣安裝的redis不是最新版本的,如有對(duì)版本要求比較高的,建議去官網(wǎng)下載源碼包去手動(dòng)安裝,官網(wǎng)地址:Redis,最新版本:6.2.6)

yum -y install redis

????????安裝完成之后配置redis.conf文件:

vi /etc/redis.conf

????????修改這一行,改成 0.0.0.0,這樣別的應(yīng)用和組件才可以訪問(wèn)到redis的服務(wù)與端口:

????????同理,redis的默認(rèn)端口也可以在此配置里修改:

????????還有一些關(guān)閉匿名訪問(wèn),設(shè)置密碼等配置的修改,項(xiàng)目若要上到公網(wǎng)環(huán)境下,建議配置。

????????啟動(dòng)并測(cè)試redis服務(wù)功能是否正常:

????????啟動(dòng)redis:????????

redis-cli -h 0.0.0.0

????????測(cè)試redis:

1 redis> set name "zzz"2 3 OK4 5 redis> get name6 7 "zzz"

????????記住,代碼并沒(méi)有實(shí)際引用redis,但也需要安裝redis模塊,否則會(huì)報(bào)錯(cuò)。(redis模塊版本不要太高,高了也會(huì)報(bào)錯(cuò),這些坑都是樓主親自趟過(guò)的,我這里使用2.10.6)

pip install redis==2.10.6

?Celery的安裝和配置:

????????windos和linux下都可以使用pip安裝:

?pip install celery==3.1.25

? ? ? ? 我的項(xiàng)目目錄:(celeryconfig.py與__init__.py文件為celery與redis配置文件):

??????????

????????在項(xiàng)目中先創(chuàng)建一個(gè)名為config的python目錄,并在__init__.py中導(dǎo)入celery模塊并配置:

__init__.py:

from celery import Celery,platformsplatforms.C_FORCE_ROOT = Trueapp = Celery("prod")  # 創(chuàng)建 Celery 實(shí)例app.config_from_object("kernel.config.celeryconfig")  # 通過(guò) Celery 實(shí)例加載配置模塊

????????platforms.C_FORCE_ROOT = True 這個(gè)配置一定要有,否則會(huì)報(bào)權(quán)限問(wèn)題。

????????在config目錄下的celeryconfig.py中配置任務(wù)隊(duì)列消費(fèi)者與消費(fèi)結(jié)果保存在redis的地址:

celeryconfig.py:

## celery配置BROKER_URL = "redis://redis-host:6379/1"  # 指定 Broker消費(fèi)者,我們使用redis 1號(hào)數(shù)據(jù)庫(kù)CELERY_RESULT_BACKEND = "redis://redis-host:6379/2"  # 指定 Backend,最終消費(fèi)結(jié)果,我們使用redis 2號(hào)數(shù)據(jù)庫(kù)CELERY_TIMEZONE = "Asia/Shanghai"  # 指定時(shí)區(qū),默認(rèn)是 UTCCELERY_IMPORTS = (  # 指定導(dǎo)入的任務(wù)模塊    "kernel.views.api"   ## 異步任務(wù)代碼文件路徑即可)

????????至此,前期需要的工具準(zhǔn)備工作全部完畢,我們開(kāi)始我們的開(kāi)發(fā)任務(wù)。

異步任務(wù)開(kāi)發(fā):

? ? ? ? 樓主因?yàn)橹饕?fù)責(zé)后端這塊,這里選擇使用flask來(lái)寫(xiě),整體的項(xiàng)目模塊與版本,大概羅列下:

????????????????????????Python 3.5.4
????????????????????????Mysql ?5.5.64????????
????????????????????????Celery==3.1.25
????????????????????????Flask==1.1.4
????????????????????????Redis==2.10.6

????????這時(shí)我們與前端同事再次詳細(xì)溝通了下,初步約定如下:

? ? ? ? 1.前端通過(guò)form表單傳數(shù)據(jù)給后端,格式為json,分析:需要解析json數(shù)據(jù)。

????????2.因?yàn)榇嬖陂L(zhǎng)耗時(shí)的任務(wù),要求一旦前端請(qǐng)求過(guò)來(lái),后端要馬上返回一個(gè)中間結(jié)果給前端(這樣解決了前端頁(yè)面等待的問(wèn)題),分析:需要馬上提供一個(gè)返回結(jié)果。

? ? ? ? 3.前端最終要拿到任務(wù)的最終執(zhí)行結(jié)果,分析:我們需要把長(zhǎng)耗時(shí)異步任務(wù)的最終結(jié)果推送給前端,需要任務(wù)代碼最后推送執(zhí)行結(jié)果。(自己先定義回調(diào)接口去測(cè)試)

1.后端Flask接口代碼:

文件名稱與路徑:

????????項(xiàng)目名稱-kernel-view-api.py,與celery配置下的任務(wù)模塊對(duì)應(yīng)。

?api.py:

# -*- coding: utf-8 -*-import json, sysimport loggingimport requestsimport datetime,pymysqlimport os,subprocessfrom flask import render_template, Blueprint, request, g, abort, url_for, jsonify, session, redirect,Responsefrom kernel.models.playbook import PlayBook_filefrom kernel.utils import render_response, Retvalfrom kernel.models import dbfrom sqlalchemy import or_,textimport gitlab  ## 導(dǎo)入gitlab模塊from kernel.config import app, cmdb_config,hcacp_configimport pymysql,uuid,hashlib,timefrom datetime import timezonebp = Blueprint("test", __name__)  ## 藍(lán)圖自己定義,這里只是實(shí)例化log = logging.getLogger(__name__)    ## 日志自己定義,這里只是實(shí)例化class status:  ## 定義一些狀態(tài)碼    success = 0    warning = 1    pending = 2    faild = -1## 回調(diào)接口@bp.route("/test/callback/", methods=["GET", "POST"])def ansible_aaa():    data1 = request.get_data(as_text=True)    # data2 = json.loads(data1)    log.info(data1)    return [email protected]("/test/add/", methods=["POST", "GET"])def devops_add():    """        獲取form表單json數(shù)據(jù)    """    # return True    try:        data = request.get_data()        _data = json.loads((str(data, "utf-8")))        print(_data)    except Exception as requestdata_except:        log.error("獲取表單數(shù)據(jù)異常,異常原因:%s" % requestdata_except)        return render_response(status.faild, u"獲取表單數(shù)據(jù)異常,異常原因:%s" % requestdata_except, {})        ## 獲取標(biāo)識(shí)tag的結(jié)果    try:        """        工單json數(shù)據(jù)要帶工單標(biāo)識(shí)符select_tag:        create_project:新建項(xiàng)目申請(qǐng)工單        """        select_tag = _data.get("select_tag")    except Exception as request_select_tag_except:        log.error("獲取表單需求標(biāo)識(shí)select_tag異常,異常原因:%s" % request_select_tag_except)        return render_response(status.faild, u"獲取表單需求標(biāo)識(shí)select_tag異常,異常原因:%s" % request_select_tag_except, {})    try:        """             !--當(dāng)參數(shù)select_tag == create_project 時(shí),建立項(xiàng)目--!         """        if select_tag == "create_project":            projname = _data.get("projname")            add_project_result = add_project.delay(cmdb_config, _data)            return render_response(status.pending, u"devops系統(tǒng)添加項(xiàng)目工單任務(wù)執(zhí)行中--pending--", {"項(xiàng)目中文名稱": projname})    except Exception as do_celery_job_except:        log.error("執(zhí)行異步celery任務(wù)異常,異常原因:%s" % do_celery_job_except)        return render_response(status.faild, u"執(zhí)行異步celery任務(wù)異常,異常原因:%s" % do_celery_job_except, {})

這里代表前端請(qǐng)求過(guò)來(lái)之后,馬上返回一個(gè)執(zhí)行結(jié)果,滿足需求2:

在devops_add接口里執(zhí)行異步任務(wù):? ? ? ??

????????add_project_result = add_project.delay(cmdb_config, _data)

官網(wǎng)的示例:

? ? ? ? ## 1.擴(kuò)號(hào)里為異步任務(wù)所需的參數(shù)

????????## 2.add_project_result?是異步任務(wù)執(zhí)行的對(duì)象,包含很多屬性方法,下邊介紹一些常用的:

????????獲取任務(wù)結(jié)果和狀態(tài):
????????add_project_result =?task.apply_async()
????????add_project_result.ready()?????#?查看任務(wù)狀態(tài),返回布爾值,??任務(wù)執(zhí)行完成,?返回?True,?否則返回?False.
????????add_project_result.wait()??????#?會(huì)阻塞等待任務(wù)完成,?返回任務(wù)執(zhí)行結(jié)果,很少使用;
????????add_project_result.get(timeout=1)???????#?獲取任務(wù)執(zhí)行結(jié)果,可以設(shè)置等待時(shí)間,如果超時(shí)但任務(wù)未完成返回None;
????????add_project_result.result??????#?任務(wù)執(zhí)行結(jié)果,未完成返回None;
????????add_project_result.state???????#?PENDING,?START,?SUCCESS,任務(wù)當(dāng)前的狀態(tài)
????????add_project_result.status??????#?PENDING,?START,?SUCCESS,任務(wù)當(dāng)前的狀態(tài)
????????add_project_result.successful??#?任務(wù)成功返回true
????????add_project_result.traceback??#?如果任務(wù)拋出了一個(gè)異常,可以獲取原始的回溯信息

? ? ?

2.異步任務(wù)代碼:

文件名稱與路徑:

????????項(xiàng)目名稱-kernel-view-api.py

api.py

解釋:

????????因?yàn)橐獫M足需求3,把最終異步耗時(shí)任務(wù)的真正結(jié)果給到前端,所以我們需要在異步任務(wù)里寫(xiě)一個(gè)回調(diào)的操作。

?????????header = {"Content-Type": "application/json"}? ## 構(gòu)造請(qǐng)求頭和數(shù)據(jù)類(lèi)型
????????_json = {"status": sttaus.faild, "msg": u"失敗", "data": {}}? ## 失敗就返回給前端json類(lèi)型失敗

????????_json = {"status": sttaus.success, "msg": u"成功", "data": {}}? ## 成功就返回給前端json類(lèi)型成功

????????requests.post(callback_url, headers=header, data=json.dumps(_json)) ## 帶參回調(diào)請(qǐng)求

# -*- coding: utf-8 -*-import json, sysimport loggingimport requestsimport datetime,pymysqlimport os,subprocessfrom flask import render_template, Blueprint, request, g, abort, url_for, jsonify, session, redirect,Responsefrom kernel.utils import render_response, Retvalfrom datetime import timezonefrom kernel.config import *  ## 導(dǎo)入config目錄下的celery配置bp = Blueprint("test", __name__)  ## 藍(lán)圖自己定義,這里只是實(shí)例化log = logging.getLogger(__name__)    ## 日志自己定義,這里只是實(shí)例化class status:  ## 定義一些狀態(tài)碼    success = 0    warning = 1    pending = 2    faild = -1## 示例函數(shù):一個(gè)添加信息函數(shù),前端給我們json數(shù)據(jù),后端接受之后去插入數(shù)據(jù)庫(kù),完成操作并告訴前端@app.task  ## celery添加項(xiàng)目任務(wù)def add_project(mysql_config, _data):    try:        ## 系統(tǒng)添加項(xiàng)目信息工單        projname = _data.get("projname")  ## 項(xiàng)目名稱,必填        prodesc= _data.get("prodesc")  ## 項(xiàng)目描述,必填        projctime = datetime.datetime.now()  ## 項(xiàng)目發(fā)布時(shí)間        callback_url = _data.get("callback_url")  ## 回調(diào)接口地址    except Exception as describe_form_except:        log.error("解析表單數(shù)據(jù)出現(xiàn)異常,異常原因:%s" % describe_form_except)        header = {"Content-Type": "application/json"}  ## 回調(diào)接口請(qǐng)求頭        _json = {"status": status.faild, "msg": u"失敗", "data": {}}        requests.post(callback_url, headers=header, data=json.dumps(_json))    try:        # 獲取數(shù)據(jù)庫(kù)連接        conn = pymysql.connect(cmdb_config.server, cmdb_config.user, cmdb_config.password, database=cmdb_config.db)        # 返回連接        cursor = conn.cursor()    except Exception as connect_except:        log.error("系統(tǒng)數(shù)據(jù)庫(kù)連接出現(xiàn)異常,異常原因:%s" % connect_except)        _json = {"status": status.faild, "msg": u"失敗", "data": {}}        requests.post(callback_url, headers=header, data=json.dumps(_json))    try:        proj_sql = "insert into project_tb_project (projname,prodesc,projctime) VALUES ("{}","{}","{}");".format(projname, prodesc, projctime)        cursor.execute(proj_sql)        conn.commit()        _json = {"status": status.success, "msg": u"成功", "data": {}}        requests.post(callback_url, headers=header, data=json.dumps(_json))        ## 任務(wù)執(zhí)行完成之后調(diào)用回調(diào)接口,返回任務(wù)執(zhí)行成功結(jié)果        log.info("系統(tǒng)建項(xiàng)目工單執(zhí)行成功,%s" % proj_sql)    except Exception as do_add_project_except:        _json = {"status": status.faild, "msg": u"失敗", "data": {}}        requests.post(callback_url, headers=header, data=json.dumps(_json))        log.error("執(zhí)行添加項(xiàng)目工單異常,異常原因:%s" % do_add_project_except)        ## 任務(wù)執(zhí)行完成之后調(diào)用回調(diào)接口,返回任務(wù)執(zhí)行失敗結(jié)果

????????樓主用的最簡(jiǎn)單,沒(méi)有在task里寫(xiě)一些屬性,類(lèi)似下邊的這種方式還可以給task添加一些屬性:

[email protected](name="test",bind=True,base=BaseTask)

? ? ? ?補(bǔ)充介紹下異步task有的一些屬性:

????????TASK的一般屬性:
????????Task.name:任務(wù)名稱;
????????Task.request:當(dāng)前任務(wù)的信息;
????????Task.max_retries:設(shè)置重試的最大次數(shù)
????????Task.throws:預(yù)期錯(cuò)誤類(lèi)的可選元組,不應(yīng)被視為實(shí)際錯(cuò)誤,而是結(jié)果失?。?br /> ????????Task.rate_limit:設(shè)置此任務(wù)類(lèi)型的速率限制
????????Task.time_limit:此任務(wù)的硬限時(shí)(以秒為單位)。
????????Task.ignore_result:不存儲(chǔ)任務(wù)狀態(tài)。默認(rèn)False;
????????Task.store_errors_even_if_ignored:如果True,即使任務(wù)配置為忽略結(jié)果,也會(huì)存儲(chǔ)錯(cuò)誤。
????????Task.serializer:標(biāo)識(shí)要使用的默認(rèn)序列化方法的字符串。
????????Task.compression:標(biāo)識(shí)要使用的默認(rèn)壓縮方案的字符串。默認(rèn)為task_compression設(shè)置。
????????Task.backend:指定該任務(wù)的結(jié)果存儲(chǔ)后端用于此任務(wù)。
????????Task.acks_late:如果設(shè)置True為此任務(wù)的消息將在任務(wù)執(zhí)行后確認(rèn)?,而不是在執(zhí)行任務(wù)之前(默認(rèn)行為),即默認(rèn)任務(wù)執(zhí)行之前就會(huì)發(fā)送確認(rèn);
????????Task.track_started:如果True任務(wù)在工作人員執(zhí)行任務(wù)時(shí)將其狀態(tài)報(bào)告為“已啟動(dòng)”。默認(rèn)是False;

我們啟動(dòng)celery來(lái)看下celery里在執(zhí)行任務(wù)的過(guò)程中有什么變化

(1)啟動(dòng)項(xiàng)目:

樓主用的是gunicorn工具啟動(dòng),配置多線程:

gunicorn.conf

????????workers = 16? ?## 多線程配置

????????bind = "0.0.0.0:7777"

????????proc_name = "websocket(項(xiàng)目名稱)"

????????limit_request_field_size = 0

????????limit_request_line = 0

????????log_level = "error"

????????debug = True

????????chdir = "/data/websocket" ## 項(xiàng)目目錄

????????啟動(dòng)命令:gunicorn -c? /項(xiàng)目目錄/gunicorn.conf kernel:app

(2)啟動(dòng)celery:

????????cd 到項(xiàng)目目錄下,執(zhí)行 celery -A kernel.views.api worker -l info ?

(3)使用postman調(diào)用接口:

????????可以看到直接先返回我們狀態(tài)碼2-等待狀態(tài):

(4)從日志看異步任務(wù)執(zhí)行過(guò)程:

????????1.會(huì)先在celery里出現(xiàn)一個(gè)異步任務(wù),并生成一個(gè)異步任務(wù)的task-id號(hào):

????????2.redis去查看是否已有task任務(wù),task-id號(hào)是一致的:

????????用add_project_result保存異步任務(wù)執(zhí)行結(jié)果的對(duì)象,最終的結(jié)果是在redis中,我們也可以去redis里去拿,redis保存的結(jié)果。

????????我們用的redis 2號(hào)數(shù)據(jù)庫(kù),select 2 號(hào)數(shù)據(jù)庫(kù),keys * 查看redis是否已有任務(wù)

????????任務(wù)最終的執(zhí)行結(jié)果(celery日志里也可以看到,在redis里也可以看到,celery日志看的更直觀,succeded代表異步任務(wù)執(zhí)行成功):

????????3. 查看項(xiàng)目日志,狀態(tài)碼為1,是回調(diào)接口打印出來(lái)的,代表返回給回調(diào)接口最終結(jié)果是成功。

? ? ? ? 4.最終去數(shù)據(jù)庫(kù)看下新添加記錄是否已有,這里就不截圖了,記錄插入成功,異步任務(wù)執(zhí)行成功,也滿足了開(kāi)始我們溝通的三個(gè)需求。

? ? ? ? 5.前端同學(xué)給你豎起了大拇指,直呼你牛!

? ? ? ? ??

?

備注:

??????????????????????????????????????????????????????????????????????????????????????????????????

?

?

? ? ? ? celery還可以用來(lái)做定時(shí)任務(wù),感興趣的伙伴們可以去官網(wǎng)或者其他途徑去研究下,樓主第一次寫(xiě)這么大的博客,有些地方我描述不清楚的或者您沒(méi)太看懂的可以私信我答疑解惑,我的微信zcw576020095,熱愛(ài)python,熱愛(ài)運(yùn)維,一起加油!

????????

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/123089.html

相關(guān)文章

  • 基于Flask-Angular的項(xiàng)目組網(wǎng)架構(gòu)與部署

    摘要:基于網(wǎng),分享項(xiàng)目的組網(wǎng)架構(gòu)和部署。項(xiàng)目組網(wǎng)架構(gòu)架構(gòu)說(shuō)明流項(xiàng)目訪問(wèn)分為兩個(gè)流,通過(guò)分兩個(gè)端口暴露給外部使用數(shù)據(jù)流用戶訪問(wèn)網(wǎng)站。通過(guò)進(jìn)行配置,使用作為異步隊(duì)列來(lái)存儲(chǔ)任務(wù),并將處理結(jié)果存儲(chǔ)在中。 基于Raindrop網(wǎng),分享項(xiàng)目的組網(wǎng)架構(gòu)和部署。 項(xiàng)目組網(wǎng)架構(gòu) showImg(https://cloud.githubusercontent.com/assets/7239657/1015704...

    kelvinlee 評(píng)論0 收藏0
  • Celery中使用Flask的上下文

    摘要:所以這就現(xiàn)實(shí)了在中使用的應(yīng)用上下文。要引入請(qǐng)求上下文,需要考慮這兩個(gè)問(wèn)題如何在中產(chǎn)生請(qǐng)求上下文。中有和可以產(chǎn)生請(qǐng)求上下文。具體的思路還是在中重載類(lèi),通過(guò),在的上下文環(huán)境下執(zhí)行。將他們傳入,生成偽造的請(qǐng)求上下文可以覆蓋大多數(shù)的使用情況。 其實(shí)我只是想把郵件發(fā)送這個(gè)動(dòng)作移到Celery中執(zhí)行。既然用到了Celery,那么每次發(fā)郵件都單獨(dú)開(kāi)一個(gè)線程似乎有點(diǎn)多余,異步任務(wù)還是交給Celery吧...

    Sourcelink 評(píng)論0 收藏0
  • 基于Celery的分布式爬蟲(chóng)管理平臺(tái): Crawlab

    摘要:基于的爬蟲(chóng)分布式爬蟲(chóng)管理平臺(tái),支持多種編程語(yǔ)言以及多種爬蟲(chóng)框架。后臺(tái)程序會(huì)自動(dòng)發(fā)現(xiàn)這些爬蟲(chóng)項(xiàng)目并儲(chǔ)存到數(shù)據(jù)庫(kù)中。每一個(gè)節(jié)點(diǎn)需要啟動(dòng)應(yīng)用來(lái)支持爬蟲(chóng)部署。任務(wù)將以環(huán)境變量的形式存在于爬蟲(chóng)任務(wù)運(yùn)行的進(jìn)程中,并以此來(lái)關(guān)聯(lián)抓取數(shù)據(jù)。 Crawlab 基于Celery的爬蟲(chóng)分布式爬蟲(chóng)管理平臺(tái),支持多種編程語(yǔ)言以及多種爬蟲(chóng)框架。 Github: https://github.com/tikazyq/...

    legendaryedu 評(píng)論0 收藏0
  • 異步任務(wù)神器 Celery 簡(jiǎn)明筆記

    摘要:我們將窗口切換到的啟動(dòng)窗口,會(huì)看到多了兩條日志這說(shuō)明任務(wù)已經(jīng)被調(diào)度并執(zhí)行成功。本文標(biāo)題為異步任務(wù)神器簡(jiǎn)明筆記本文鏈接為參考資料使用之美分布式任務(wù)隊(duì)列的介紹思誠(chéng)之道異步任務(wù)神器簡(jiǎn)明筆記 Celery 在程序的運(yùn)行過(guò)程中,我們經(jīng)常會(huì)碰到一些耗時(shí)耗資源的操作,為了避免它們阻塞主程序的運(yùn)行,我們經(jīng)常會(huì)采用多線程或異步任務(wù)。比如,在 Web 開(kāi)發(fā)中,對(duì)新用戶的注冊(cè),我們通常會(huì)給他發(fā)一封激活郵件,...

    Ryan_Li 評(píng)論0 收藏0
  • Django下使用celery 異步發(fā)送短信驗(yàn)證碼

    摘要:介紹應(yīng)用舉例是一個(gè)基于開(kāi)發(fā)的分布式異步消息任務(wù)隊(duì)列,通過(guò)它可以輕松的實(shí)現(xiàn)任務(wù)的異步處理,如果你的業(yè)務(wù)場(chǎng)景中需要用到異步任務(wù),就可以考慮使用你想對(duì)臺(tái)機(jī)器執(zhí)行一條批量命令,可能會(huì)花很長(zhǎng)時(shí)間,但你不想讓你的程序等著結(jié)果返回,? celery 1.celery介紹 1.1 celery應(yīng)用舉例 Celery 是一個(gè) 基于python開(kāi)發(fā)的分布式異步消息任務(wù)隊(duì)列,通過(guò)...

    everfly 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<