本小節(jié)開始介紹之前多次提到過的消息隊(duì)列。再講之前,問大家各問題.你們遇到過有些時候,爬蟲有很大一部分時間抓取解析模塊是空閑的情況么?我猜應(yīng)該大多數(shù)都遇到過.產(chǎn)生這個現(xiàn)象的原因就在于寫入數(shù)據(jù)庫的時間比起抓取解析的時間要慢的多.所以就開始出現(xiàn)了性能瓶頸.通過分析,是寫入數(shù)據(jù)庫的性能跟不上抓取解析的性能.那么怎么樣才能讓兩邊的速率達(dá)成平衡呢?沒錯,就是前面前面說過多次的消息隊(duì)列.
從名字上來看,我們就能知道這是一個傳遞消息的隊(duì)列.通過分布式的消息隊(duì)列服務(wù),我們可以用來存儲進(jìn)程間傳輸?shù)南ⅲ瑸榉植际讲渴鸬牟煌瑧?yīng)用之間或者一個應(yīng)用的不同組件之間提供基于消息的可靠的異步通信服務(wù)。消息被存儲在高可靠、高可用的消息隊(duì)列中,多進(jìn)程可以同時讀寫,互不干擾。使用消息隊(duì)列,用戶可以在執(zhí)行不同任務(wù)的應(yīng)用程序的分布式組件之間傳遞信息,既不會丟失消息,也不要求各個組件始終處于可用狀態(tài)。隊(duì)列在數(shù)據(jù)發(fā)送端以及數(shù)據(jù)接收端之間起到緩沖作用。這樣,在數(shù)據(jù)發(fā)送端的工作速度快于數(shù)據(jù)接收端的情況下,隊(duì)列可解決因此而產(chǎn)生的問題。
同時,消息隊(duì)列還可以解決原來構(gòu)架中另一個存在的風(fēng)險,那就是原來的模塊之間存在傳遞數(shù)據(jù)的關(guān)系,萬一其中某個模塊出現(xiàn)了問題,那么就會導(dǎo)致蔓延到整體,最終出錯停止.在爬蟲架構(gòu)中,模塊與模塊之間只需要數(shù)據(jù)交換,不需要太多邏輯上的關(guān)系.這種情況我們就可以把消息隊(duì)列當(dāng)成一個消息中間件.模塊之前的數(shù)據(jù)傳遞通過中間件來完成.這樣的話,如果任意模塊出現(xiàn)問題,也只會影響到自身,不會蔓延到整體程序.
現(xiàn)在市面上的消息隊(duì)列有很多,其中比較熱門的有rabbitMQ,kafka,redis,nsq和各大云平臺自己開發(fā)的消息服務(wù)中間件,例如騰訊云的CMQ,阿里云的MQ,AWS的SQS等等.
消息隊(duì)列有這么多好處,那么我們怎么才能應(yīng)用到我們現(xiàn)在的爬蟲中呢,照例,我們先來了解一下消息隊(duì)列是什么.
在隊(duì)列模式下,爬蟲的工作模式大抵是這樣的.抓取解析模塊將數(shù)據(jù)提取出來后,發(fā)送請求給隊(duì)列.而在主題模式下,存儲模塊通過訂閱了topic來獲取消息隊(duì)列主動推送的有關(guān)抓取解析模塊傳遞到消息隊(duì)列的數(shù)據(jù).消費(fèi)信息后,兩種模式都需要刪除已經(jīng)被消費(fèi)過的消息,以便用來保證該數(shù)據(jù)不會被多次重復(fù)使用.
那么,加了消息隊(duì)列后整個爬蟲的組件的流程圖是這樣的:

從這張圖中就能看出,子模塊之間沒有任何關(guān)聯(lián),全都是通過消息隊(duì)列進(jìn)行相互鏈接,這樣就實(shí)現(xiàn)了模塊之間的相互隔離。這樣即使其中一個模塊出現(xiàn)問題,那也不會蔓延至整體。最多只是爬蟲因?yàn)闆]有數(shù)據(jù)而停滯。不過我們可以通過布置多個節(jié)點(diǎn)來防止消息隊(duì)列上消息隊(duì)列為空這個問題.