爬虫为什么使用asyncio以及邮件系统为什么使用celery
#--------------------------------下面是asyncio-------------------------------------------
[1]中有一句非常好:
爬蟲主要運行時間消耗是請求網頁時的io阻塞
?
假設爬取10個網頁,每個網頁的響應時間是300ms,那么同步爬取耗時就是3s,
使用asyncio,在網頁響應的300ms內,去發(fā)起另外一個爬取動作,這樣,網頁一邊響應,爬蟲客戶端就可以一邊做別的事情了。
涉及第三方API(例如網頁)的事情,例如阿里物流API,支付寶API接口,都要改成asyncio異步.
等待的事情,甩鍋給網頁的服務器,爬蟲繼續(xù)發(fā)起下一輪爬取動作
#--------------------------------下面是celery-------------------------------------------
django用來實現(xiàn)郵件系統(tǒng)常用celery,
celery是個異步隊列,輸入和輸出處理的速度可以不一致,
django頁面告訴客戶郵件已經發(fā)送,其實發(fā)送郵件的動作只是托管給了celery,并不是真的已經發(fā)送到你郵箱了。
所以發(fā)送郵件的是smtp服務器,并不是django,django中發(fā)送郵件的函數(shù)只是在通知smtp服務器,實則并沒有發(fā)送
但是如果幾百上千客戶注冊,需要郵件激活, 設計成同步的話,那就存在最糟糕情況,有的客戶要等幾十分鐘才能被發(fā)送注冊郵件。
那么怎么辦呢?
django把這幾千個帳號激活的郵件托管給celery,celery發(fā)給smtp,smtp有成千上萬臺服務器,smtp從celery串行接收到發(fā)送郵件的任務后,通過負載均衡,分派不同的smtp子服務器發(fā)送給客戶的注冊郵箱,大大提升響應。
?
等待的事情,甩鍋給celery和smtp服務器,郵件系統(tǒng)繼續(xù)發(fā)起下一輪發(fā)送注冊激活郵件的動作。
?
有的人反駁,如果smtp子服務器只有一臺咋辦?
沒錯,這個時候,你的django以及celery,全部失效,我們甩鍋的原因是有比當前服務器的資源更好的smtp,如果連smtp的子服務器也只有一臺,那你甩鍋也沒用,上述場景,用戶體驗就是直接卡死.
#---------------------------------------------------------------------------
celery和asyncio能不能互換使用?
首先概念上肯定不是一個東西,
那么如果無視概念,具體應用的時候,"效果"上,是否可以互相替換呢?
取決于使用場景和資源限制。
| 使用場景 | asyncio案例 | celery案例 | 是否可以互換 |
| 郵件系統(tǒng) | [3] | 天天生鮮 | 是 |
| 單機爬蟲 | [5] | [4] | 是 |
| 分布式爬蟲 | X | √ | 否 |
| 硬件限制只允許單線程 | 只需要單進程即可開啟 | 需要另外多開一個進程 | 否 |
| 工程主進程需要接收異步任務結果 | √ | X | 否 |
?
效果的提升角度(并發(fā)/并行):
| ? | 業(yè)務 | 并發(fā) | 并行 |
| celery | 單機爬蟲 | 單機 | X |
| celery | 分布式爬蟲(集群) | 主機 | 從機(集群) |
| asyncio | 單機爬蟲 | 單機 | X |
?
另外,根據[2]:
if its something that shouldn't be done if the connection is aborted, or service unavailable, then go ahead and use a async task.(如果鏈接斷開希望任務不再執(zhí)行,那么我們需要使用的就是asyncio而不是celery)
這句話的意思是,主線程如果希望快速釋放請求資源,那么用celery更加合適,因為請求的時候,都托管給celery了,但是asyncio中的協(xié)程就不能及時被釋放,因為需要以非阻塞形式來等待請求結果。
?
celery中的異步和asyncio異步,兩種異步是不是同一個概念?
是,都是非阻塞
?
celery中的異步和asyncio異步,兩種異步性能是否接近一致?
肯定不是,參考[6]:
?Do not get confused with terminology... Celery?is?asynchronous, but it is not "Python async" as it predates the Python's asyncio... Maybe Celery 5 will get its async parts replaced/refactored to use Python 3+ asyncio and related.(意思是celery中的異步模塊和asyncio不是一個東西,不要混淆)
兩者無法公平地進行比較,因為celery需要額外多開一個進程。
?
另外注意,指令級別的并行是時刻存在的,
線程級別的并行要看代碼情況.單核機器不存在線程的并行
但是絕對并行(統(tǒng)一時刻執(zhí)行統(tǒng)一函數(shù))是不存在的
?
支持celery以及asyncio的web框架:
| ? | celery | asyncio |
| Flask | √ | X |
| Django | √ | X |
| Tornado | √ | √ |
?
#---------------------------------------------------------------------------------------------------------------------------------------------
舉例:
網上瘋傳的天天生鮮的項目里面的支付寶接口是這么寫的:
response = alipay.api_alipay_trade_query(order_id)雖然在整個代碼文件中,
沒有看到我們眼熟的urllib之類的網絡請求庫,
但是,這句代碼中,sdk底層封裝了網絡請求,網絡IO是真實存在的,人多鐵定會卡死.
#---------------------------------------------------------------------------
異步的關鍵就是:
怎么甩鍋,讓自己的服務器更加輕松。
異步應用上的思想是:
能讓別人等,就不要讓自己等.
asyncio是雙向通信場景.
celery是單向通信場景.
asyncio以及celery跑個小case非常容易,但是要在自己的工程中"有意識的"去應用它,
培養(yǎng)這種意識,就一定要根據自己的業(yè)務分析出哪些地方可以讓別人等,而不是自己等.
?
Reference:
[1]多線程爬蟲實現(xiàn)(上)
[2]Can we use python asyncio in place of celery?
[3]Sending Emails Using asyncio and aiohttp From a Django Application
[4]Python爬蟲之使用celery加速爬蟲
[5]asyncio高并發(fā)爬蟲
[6]Is Celery really async?
總結
以上是生活随笔為你收集整理的爬虫为什么使用asyncio以及邮件系统为什么使用celery的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基本SCTP套接字编程常用函数
- 下一篇: DMP文件的生成和使用