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

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