爬蟲平臺Crawlab核心原理--分布式架構

      網友投稿 879 2022-05-30

      背景

      Crawlab自第一版發布已經幾個月了,其中經歷了好幾次迭代:版本從v0.1到了v0.3.0;后端語言從Python到了Golang;從最初使用Celery作為任務調度引擎,到自己開發分布式任務調度引擎;從只能運行自定義爬蟲到可以運行可配置爬蟲(雖然還沒遷移到最新版本);從手動部署爬蟲到自動部署爬蟲;從自己搭建環境到Docker部署;從手動執行任務到定時任務;等等(詳情見CHANGELOG)。在使用者們的反饋下,Crawlab爬蟲平臺也逐漸變得穩定和實用,能夠真正幫助到有爬蟲管理需求的用戶。如今在Github上有近1k的star,相關社區(微信群、微信公眾號)也建立起來,四分之一的用戶表示已經將Crawlab應用于企業爬蟲管理。可以看出,Crawlab是受開發者們關注和喜歡的。

      Github: https://github.com/tikazyq/crawlab

      為什么需要爬蟲管理平臺

      對于一般的爬蟲愛好者來說,寫一個單機爬蟲腳本已經足夠,而且Scrapy這樣的優秀爬蟲框架能夠讓開發者輕松調試、編寫一個簡單的爬蟲,需要定時任務就直接上Crontab,分分鐘搞定。然而,一般的企業對爬蟲的要求相對較高,其中主要涉及一個問題,也就是規模(Scale)。當然,這里的規模是指大型規模。爬蟲的規模分為兩種:一種是爬蟲需要抓取大量的數據(Volume),例如全網抓取淘寶的商品;另一種是爬蟲需要涵蓋大量的網站(Coverage),例如搜索引擎。

      不同的規模需要有不同的架構策略(如下圖):

      當網站數量只有一個,抓取結果不多時,只需要單機即可,并不需要分布式爬蟲;

      但當需要抓取結果量級提升時,例如全網抓取淘寶,就需要用分布式爬蟲了,這是因為單個機器的帶寬和計算資源不足以做到全網抓取,而且為了應對反爬蟲技術,還需要大量的代理IP;

      同理,當需要抓取網站的數量增多時,例如你需要創建一個新聞搜索引擎,你同樣需要多臺機器來獲取足夠的帶寬和計算資源;

      對于同時要求Volume和Coverage的應用,不是一般的小企業或個人能做的,對不管是人力和機器的資源都非常高。

      而爬蟲管理平臺就是針對情況(2)、(3)、(4)而存在的分布式管理平臺,能夠讓用戶輕松管理多個爬蟲或多機運行的爬蟲。

      Crawlab從誕生之初就解決了分布式爬蟲問題,最早采用了Celery作為分布式任務調度引擎,以Redis作為消息隊列,HTTP請求作為節點通信媒介,簡單地實現了分布式管理。但隨著用戶不斷使用Crawlab,發現這樣的方式并不是很方便,用戶需要指定節點的IP地址和API端口,而且還不能指定節點執行任務。因為各種問題,在最新版本v0.3.0用Golang重構后端的時候,就將Celery棄用了,轉而自己開發分布式節點的監控和通信應用,這樣更加靈活和高效。本文是核心原理介紹,下面將著重介紹Crawlab的分布式架構原理(Golang版本)。

      整體架構

      Crawlab的整體架構如下圖,由五大部分組成:

      主節點(Master Node):負責任務派發、API、部署爬蟲等;

      工作節點(Worker Node):負責執行爬蟲任務;

      MongoDB數據庫:存儲節點、爬蟲、任務等日常運行數據;

      Redis數據庫:儲存任務消息隊列、節點心跳等信息。

      前端客戶端:Vue應用,負責前端交互和向后端請求數據。

      以執行爬蟲任務為例,它是Crawlab中常見的使用場景,我們來看看它具體是如何工作的:

      前端向主節點發起請求,要求指定在某一工作節點執行任務;

      主節點收到該請求,并將任務數據推送到Redis任務隊列中;

      工作節點持續監聽Redis任務隊列,并利用LPOP獲取任務;

      工作節點執行任務,并將結果寫回到儲存數據庫;

      以上就是執行爬蟲任務的大致流程。當然,這還不是全部,我們還需要考慮日志處理、并發執行、取消任務等細節問題。具體的處理信息,請查看相關文檔和源代碼。

      總的來說,可以將主節點看作是Crawlab整體架構的中控系統,理解為Crawlab的大腦;工作節點是實際干活的部分,是Crawlab的運動軀體;MongoDB和Redis是負責通信交流的,可以看作Crawlab的血液和神經網絡。這些模塊一起構成了一個完整、自洽、相互協作的系統。

      節點注冊和監控

      節點監控主要是通過Redis來完成的(如下圖)。

      工作節點會不斷更新心跳信息在Redis上,利用HSET nodes ,心跳信息包含節點MAC地址,IP地址,當前時間戳。

      主節點會周期性獲取Redis上的工作節點心跳信息。如果有工作節點的時間戳在60秒之前,則考慮該節點為離線狀態,會在Redis中刪除該節點的信息,并在MongoDB中設置為"離線";如果時間戳在過去60秒之內,則保留該節點信息,在MongoDB中設置為"在線"。

      該架構的優點

      這樣,就做到了一個監控節點是否在線的節點注冊系統。這樣架構的好處在于,節點之間根本不用像HTTP、RPC那樣IP或端口,只需要知道Redis的地址就可以完成節點注冊和監控。因此,也就減少了用戶配置節點的操作,簡化了使用流程。同時,由于隱藏了IP地址和端口,也更為安全。另外,相較于Celery版本的監控,我們去除了Flower服務,不用在服務中單獨起一個Flower服務的進程,減少了開銷。

      下圖是Crawlab UI界面上的節點之間的關系圖(拓撲圖)。

      該架構的缺點

      相較于一些常見的分布式架構,例如Zookeeper,Crawlab還存在一些不完善的地方。

      高可用性(High Availability)是Crawlab暫時還沒有做得很好的。例如,當主節點宕機的時候,整個系統就會癱瘓,因為主節點是Crawlab的大腦中樞,負責很多功能。如果主節點宕機,前端就無法獲取API數據,任務無法調度,當然也無法監控節點了。雖然Zookeeper沒有將可用性(Availability)做得非常完善,但其投票選舉機制保證了其一定程度的高可用。如果Crawlab要改善這一點的話,會在主節點宕機后,用一定的方式選舉出另一個主節點,保證高可用。

      節點通信

      如果仔細看上面的整體架構圖的話,你可能會注意到Crawlab中通信有兩種。一種是同步信息(Sync via Msg),另一種是派發任務(Assign Tasks)。這兩種通信分別叫即時通信和延遲通信。下面分別介紹。

      爬蟲平臺Crawlab核心原理--分布式架構

      即時通信

      即時通信是指某節點A通過某種媒介向另一節點B發送信息,取決于是否為雙向通信,節點B收到信息后可能會通過同一種媒介將信息回復給節點A。

      Crawlab的即時通信是通過Redis的PubSub來實現的(如下圖)。

      所謂PubSub,簡單來說是一個發布訂閱模式。訂閱者(Subscriber)會在Redis上訂閱(Subscribe)一個通道,其他任何一個節點都可以作為發布者(Publisher)在該通道上發布(Publish)消息。

      在Crawlab中,主節點會訂閱nodes:master通道,其他節點如果需要向主節點發送消息,只需要向nodes:master發布消息就可以了。同理,各工作節點會各自訂閱一個屬于自己的通道nodes:(node_id是MongoDB里的節點ID,是MongoDB ObjectId),如果需要給工作節點發送消息,只需要發布消息到該通道就可以了。

      一個網絡請求的簡單過程如下:

      客戶端(前端應用)發送請求給主節點(API);

      主節點通過Redis PubSub的通道發布消息給相應的工作節點;

      工作節點收到消息之后,執行一些操作,并將相應的消息通過通道發布給主節點;

      主節點收到消息之后,將消息返回給客戶端。

      Crawlab的獲取日志、獲取系統信息、取消任務、告知節點獲取爬蟲文件都是通過即時通信完成的。

      而實現代碼相對來說有些復雜。下面是主節點的PubSub回調函數。

      func?MasterNodeCallback(channel?string,?msgStr?string)?{

      //?反序列化

      var?msg?NodeMessage

      if?err?:=?json.Unmarshal([]byte(msgStr),?&msg);?err?!=?nil?{

      log.Errorf(err.Error())

      debug.PrintStack()

      return

      }

      if?msg.Type?==?constants.MsgTypeGetLog?{

      //?獲取日志

      fmt.Println(msg)

      time.Sleep(10?*?time.Millisecond)

      ch?:=?TaskLogChanMap.ChanBlocked(msg.TaskId)

      ch?<-?msg.Log

      }?else?if?msg.Type?==?constants.MsgTypeGetSystemInfo?{

      //?獲取系統信息

      fmt.Println(msg)

      time.Sleep(10?*?time.Millisecond)

      ch?:=?SystemInfoChanMap.ChanBlocked(msg.NodeId)

      sysInfoBytes,?_?:=?json.Marshal(&msg.SysInfo)

      ch?<-?string(sysInfoBytes)

      }

      }

      這里其實是用msg.Type來區分消息類別,如果要擴展的話需要寫不少if/else。工作節點的回調函數也需要寫類似的邏輯。

      這個可能跟HTTP請求和RPC通信相較來說麻煩一些。不過,這其實和WebSocket非常像(對WebSocket不了解的同學可以看看韋世東最近的文章《開發者必知必會的 WebSocket 協議》),都需要在客戶端和服務端定義回調函數。一個改進方法是不用if/else來區分信息類別,轉而用PubSub頻道名稱,監聽多個頻道。總之,具體實踐中怎么選擇,還需要考慮實際情況。

      延遲通信

      延遲通信對即時性要求不高,不需要節點或客戶端對請求即時回復。通常來說,延遲通信的實現方式有隊列、輪詢等方式。這樣的方式不要求即時性。延遲通信主要是用作需要長時間的操作,例如發送郵件、數據處理、構建應用等等。

      Crawlab中的延遲通信主要包含任務隊列以及輪詢,都是通過Redis來實現的。任務隊列是用作爬蟲任務執行:主節點接收抓取請求后,將執行任務的消息推到任務隊列中,工作節點不斷輪詢任務隊列,獲取任務并執行(如下圖)。Crawlab爬蟲任務執行的詳情請參見相關文檔和源代碼。

      爬蟲任務執行

      Crawlab的延遲通信主要包括爬蟲任務執行和爬蟲部署。爬蟲任務執行這里不再贅述。下面簡單介紹一下爬蟲部署(流程如下圖)。

      爬蟲部署

      整個爬蟲部署的生命周期:

      主節點每5秒,會從爬蟲的目錄獲取爬蟲信息,然后更新到數據庫(這個過程不涉及文件上傳);

      主節點每60秒,從數據庫獲取所有的爬蟲信息,然后將爬蟲打包成zip文件,并上傳到MongoDB GridFS,并且在MongoDB的spiders表里寫入file_id文件ID;

      主節點通過Redis PubSub發布消息(file.upload事件,包含文件ID)給工作節點,通知工作節點獲取爬蟲文件;

      工作節點接收到獲取爬蟲文件的消息,從MongoDB GridFS獲取zip文件,并解壓儲存在本地。

      這樣,所有爬蟲將被周期性的部署在工作節點上。

      在后續的開發中,Crawlab將會加入郵件通知、短信通知、微信推送等功能。而這些都是屬于延遲通信的范疇,主要實現方法無外乎隊列和輪詢。

      分布式實踐 - 抓取上百個新聞網站

      下面將介紹一個多機爬蟲的實際應用場景,幫助大家深入理解Crawlab的分布式原理。

      首先,你可能需要足夠的網絡帶寬,因為需要抓取的網站上百了,不是簡簡單單的單機爬蟲,你需要多臺機器。這里只是簡單介紹下拓撲架構,并不會詳細介紹大規模爬蟲的去重、反爬、容錯等邏輯。如下圖,每一個工作節點可以限制抓取一部分網站,總共M個網站平均分配給N個工作節點。在Crawlab中就是用指定節點的方式了,這個不難。另外,你也可以通過隨機分配的方式來派發任務,每一個工作節點統計上也會均勻分配到任務,這其實也就是一個負載均衡(Load Balancing)的過程。

      當然,你可能好奇上百個新聞網站是不是需要寫上百個爬蟲。對于這個問題,沒有確切的準確回答。答案應該是“看情況”。對于自動提取字段的算法不夠自信的開發者來說,可以選擇Crawlab的可配置爬蟲(看這篇文章《我是如何在3分鐘內開發完一個爬蟲的》),這樣的開發成本相對來說比較小。但是對于已經有技術實力的可以寫出很好的通用提取規則的選手來說,只寫一個通用爬蟲就足夠了(簡單的列表頁提取規則參考《爬蟲平臺Crawlab核心原理--自動提取字段算法》),抓取多個網站等于抓取一個網站,不過還是需要部署在多個機器上,以求最大的帶寬和計算資源。當然,不管是哪一種,都繞不開去重、反爬、錯誤監控,不過這些不在本文討論范圍,網上有很多教程可以多學習一下。

      往期文章

      爬蟲管理平臺Crawlab v0.3.0發布(Golang版本)

      爬蟲管理平臺Crawlab部署指南(Docker and more)

      爬蟲平臺Crawlab核心原理--自動提取字段算法

      [爬蟲手記] 我是如何在3分鐘內開發完一個爬蟲的

      手把手教你如何用Crawlab構建技術文章聚合平臺(二)

      手把手教你如何用Crawlab構建技術文章聚合平臺(一)

      分布式通用爬蟲管理平臺Crawlab

      背景

      Crawlab自第一版發布已經幾個月了,其中經歷了好幾次迭代:版本從v0.1到了v0.3.0;后端語言從Python到了Golang;從最初使用Celery作為任務調度引擎,到自己開發分布式任務調度引擎;從只能運行自定義爬蟲到可以運行可配置爬蟲(雖然還沒遷移到最新版本);從手動部署爬蟲到自動部署爬蟲;從自己搭建環境到Docker部署;從手動執行任務到定時任務;等等(詳情見CHANGELOG)。在使用者們的反饋下,Crawlab爬蟲平臺也逐漸變得穩定和實用,能夠真正幫助到有爬蟲管理需求的用戶。如今在Github上有近1k的star,相關社區(微信群、微信公眾號)也建立起來,四分之一的用戶表示已經將Crawlab應用于企業爬蟲管理。可以看出,Crawlab是受開發者們關注和喜歡的。

      Github: https://github.com/tikazyq/crawlab

      為什么需要爬蟲管理平臺

      對于一般的爬蟲愛好者來說,寫一個單機爬蟲腳本已經足夠,而且Scrapy這樣的優秀爬蟲框架能夠讓開發者輕松調試、編寫一個簡單的爬蟲,需要定時任務就直接上Crontab,分分鐘搞定。然而,一般的企業對爬蟲的要求相對較高,其中主要涉及一個問題,也就是規模(Scale)。當然,這里的規模是指大型規模。爬蟲的規模分為兩種:一種是爬蟲需要抓取大量的數據(Volume),例如全網抓取淘寶的商品;另一種是爬蟲需要涵蓋大量的網站(Coverage),例如搜索引擎。

      不同的規模需要有不同的架構策略(如下圖):

      當網站數量只有一個,抓取結果不多時,只需要單機即可,并不需要分布式爬蟲;

      但當需要抓取結果量級提升時,例如全網抓取淘寶,就需要用分布式爬蟲了,這是因為單個機器的帶寬和計算資源不足以做到全網抓取,而且為了應對反爬蟲技術,還需要大量的代理IP;

      同理,當需要抓取網站的數量增多時,例如你需要創建一個新聞搜索引擎,你同樣需要多臺機器來獲取足夠的帶寬和計算資源;

      對于同時要求Volume和Coverage的應用,不是一般的小企業或個人能做的,對不管是人力和機器的資源都非常高。

      而爬蟲管理平臺就是針對情況(2)、(3)、(4)而存在的分布式管理平臺,能夠讓用戶輕松管理多個爬蟲或多機運行的爬蟲。

      Crawlab從誕生之初就解決了分布式爬蟲問題,最早采用了Celery作為分布式任務調度引擎,以Redis作為消息隊列,HTTP請求作為節點通信媒介,簡單地實現了分布式管理。但隨著用戶不斷使用Crawlab,發現這樣的方式并不是很方便,用戶需要指定節點的IP地址和API端口,而且還不能指定節點執行任務。因為各種問題,在最新版本v0.3.0用Golang重構后端的時候,就將Celery棄用了,轉而自己開發分布式節點的監控和通信應用,這樣更加靈活和高效。本文是核心原理介紹,下面將著重介紹Crawlab的分布式架構原理(Golang版本)。

      整體架構

      Crawlab的整體架構如下圖,由五大部分組成:

      主節點(Master Node):負責任務派發、API、部署爬蟲等;

      工作節點(Worker Node):負責執行爬蟲任務;

      MongoDB數據庫:存儲節點、爬蟲、任務等日常運行數據;

      Redis數據庫:儲存任務消息隊列、節點心跳等信息。

      前端客戶端:Vue應用,負責前端交互和向后端請求數據。

      以執行爬蟲任務為例,它是Crawlab中常見的使用場景,我們來看看它具體是如何工作的:

      前端向主節點發起請求,要求指定在某一工作節點執行任務;

      主節點收到該請求,并將任務數據推送到Redis任務隊列中;

      工作節點持續監聽Redis任務隊列,并利用LPOP獲取任務;

      工作節點執行任務,并將結果寫回到儲存數據庫;

      以上就是執行爬蟲任務的大致流程。當然,這還不是全部,我們還需要考慮日志處理、并發執行、取消任務等細節問題。具體的處理信息,請查看相關文檔和源代碼。

      總的來說,可以將主節點看作是Crawlab整體架構的中控系統,理解為Crawlab的大腦;工作節點是實際干活的部分,是Crawlab的運動軀體;MongoDB和Redis是負責通信交流的,可以看作Crawlab的血液和神經網絡。這些模塊一起構成了一個完整、自洽、相互協作的系統。

      節點注冊和監控

      節點監控主要是通過Redis來完成的(如下圖)。

      工作節點會不斷更新心跳信息在Redis上,利用HSET nodes ,心跳信息包含節點MAC地址,IP地址,當前時間戳。

      主節點會周期性獲取Redis上的工作節點心跳信息。如果有工作節點的時間戳在60秒之前,則考慮該節點為離線狀態,會在Redis中刪除該節點的信息,并在MongoDB中設置為"離線";如果時間戳在過去60秒之內,則保留該節點信息,在MongoDB中設置為"在線"。

      該架構的優點

      這樣,就做到了一個監控節點是否在線的節點注冊系統。這樣架構的好處在于,節點之間根本不用像HTTP、RPC那樣IP或端口,只需要知道Redis的地址就可以完成節點注冊和監控。因此,也就減少了用戶配置節點的操作,簡化了使用流程。同時,由于隱藏了IP地址和端口,也更為安全。另外,相較于Celery版本的監控,我們去除了Flower服務,不用在服務中單獨起一個Flower服務的進程,減少了開銷。

      下圖是Crawlab UI界面上的節點之間的關系圖(拓撲圖)。

      該架構的缺點

      相較于一些常見的分布式架構,例如Zookeeper,Crawlab還存在一些不完善的地方。

      高可用性(High Availability)是Crawlab暫時還沒有做得很好的。例如,當主節點宕機的時候,整個系統就會癱瘓,因為主節點是Crawlab的大腦中樞,負責很多功能。如果主節點宕機,前端就無法獲取API數據,任務無法調度,當然也無法監控節點了。雖然Zookeeper沒有將可用性(Availability)做得非常完善,但其投票選舉機制保證了其一定程度的高可用。如果Crawlab要改善這一點的話,會在主節點宕機后,用一定的方式選舉出另一個主節點,保證高可用。

      節點通信

      如果仔細看上面的整體架構圖的話,你可能會注意到Crawlab中通信有兩種。一種是同步信息(Sync via Msg),另一種是派發任務(Assign Tasks)。這兩種通信分別叫即時通信和延遲通信。下面分別介紹。

      即時通信

      即時通信是指某節點A通過某種媒介向另一節點B發送信息,取決于是否為雙向通信,節點B收到信息后可能會通過同一種媒介將信息回復給節點A。

      Crawlab的即時通信是通過Redis的PubSub來實現的(如下圖)。

      所謂PubSub,簡單來說是一個發布訂閱模式。訂閱者(Subscriber)會在Redis上訂閱(Subscribe)一個通道,其他任何一個節點都可以作為發布者(Publisher)在該通道上發布(Publish)消息。

      在Crawlab中,主節點會訂閱nodes:master通道,其他節點如果需要向主節點發送消息,只需要向nodes:master發布消息就可以了。同理,各工作節點會各自訂閱一個屬于自己的通道nodes:(node_id是MongoDB里的節點ID,是MongoDB ObjectId),如果需要給工作節點發送消息,只需要發布消息到該通道就可以了。

      一個網絡請求的簡單過程如下:

      客戶端(前端應用)發送請求給主節點(API);

      主節點通過Redis PubSub的通道發布消息給相應的工作節點;

      工作節點收到消息之后,執行一些操作,并將相應的消息通過通道發布給主節點;

      主節點收到消息之后,將消息返回給客戶端。

      Crawlab的獲取日志、獲取系統信息、取消任務、告知節點獲取爬蟲文件都是通過即時通信完成的。

      而實現代碼相對來說有些復雜。下面是主節點的PubSub回調函數。

      func?MasterNodeCallback(channel?string,?msgStr?string)?{

      //?反序列化

      var?msg?NodeMessage

      if?err?:=?json.Unmarshal([]byte(msgStr),?&msg);?err?!=?nil?{

      log.Errorf(err.Error())

      debug.PrintStack()

      return

      }

      if?msg.Type?==?constants.MsgTypeGetLog?{

      //?獲取日志

      fmt.Println(msg)

      time.Sleep(10?*?time.Millisecond)

      ch?:=?TaskLogChanMap.ChanBlocked(msg.TaskId)

      ch?<-?msg.Log

      }?else?if?msg.Type?==?constants.MsgTypeGetSystemInfo?{

      //?獲取系統信息

      fmt.Println(msg)

      time.Sleep(10?*?time.Millisecond)

      ch?:=?SystemInfoChanMap.ChanBlocked(msg.NodeId)

      sysInfoBytes,?_?:=?json.Marshal(&msg.SysInfo)

      ch?<-?string(sysInfoBytes)

      }

      }

      這里其實是用msg.Type來區分消息類別,如果要擴展的話需要寫不少if/else。工作節點的回調函數也需要寫類似的邏輯。

      這個可能跟HTTP請求和RPC通信相較來說麻煩一些。不過,這其實和WebSocket非常像(對WebSocket不了解的同學可以看看韋世東最近的文章《開發者必知必會的 WebSocket 協議》),都需要在客戶端和服務端定義回調函數。一個改進方法是不用if/else來區分信息類別,轉而用PubSub頻道名稱,監聽多個頻道。總之,具體實踐中怎么選擇,還需要考慮實際情況。

      延遲通信

      延遲通信對即時性要求不高,不需要節點或客戶端對請求即時回復。通常來說,延遲通信的實現方式有隊列、輪詢等方式。這樣的方式不要求即時性。延遲通信主要是用作需要長時間的操作,例如發送郵件、數據處理、構建應用等等。

      Crawlab中的延遲通信主要包含任務隊列以及輪詢,都是通過Redis來實現的。任務隊列是用作爬蟲任務執行:主節點接收抓取請求后,將執行任務的消息推到任務隊列中,工作節點不斷輪詢任務隊列,獲取任務并執行(如下圖)。Crawlab爬蟲任務執行的詳情請參見相關文檔和源代碼。

      Crawlab的延遲通信主要包括爬蟲任務執行和爬蟲部署。爬蟲任務執行這里不再贅述。下面簡單介紹一下爬蟲部署(流程如下圖)。

      整個爬蟲部署的生命周期:

      主節點每5秒,會從爬蟲的目錄獲取爬蟲信息,然后更新到數據庫(這個過程不涉及文件上傳);

      主節點每60秒,從數據庫獲取所有的爬蟲信息,然后將爬蟲打包成zip文件,并上傳到MongoDB GridFS,并且在MongoDB的spiders表里寫入file_id文件ID;

      主節點通過Redis PubSub發布消息(file.upload事件,包含文件ID)給工作節點,通知工作節點獲取爬蟲文件;

      工作節點接收到獲取爬蟲文件的消息,從MongoDB GridFS獲取zip文件,并解壓儲存在本地。

      這樣,所有爬蟲將被周期性的部署在工作節點上。

      在后續的開發中,Crawlab將會加入郵件通知、短信通知、微信推送等功能。而這些都是屬于延遲通信的范疇,主要實現方法無外乎隊列和輪詢。

      分布式實踐 - 抓取上百個新聞網站

      下面將介紹一個多機爬蟲的實際應用場景,幫助大家深入理解Crawlab的分布式原理。

      首先,你可能需要足夠的網絡帶寬,因為需要抓取的網站上百了,不是簡簡單單的單機爬蟲,你需要多臺機器。這里只是簡單介紹下拓撲架構,并不會詳細介紹大規模爬蟲的去重、反爬、容錯等邏輯。如下圖,每一個工作節點可以限制抓取一部分網站,總共M個網站平均分配給N個工作節點。在Crawlab中就是用指定節點的方式了,這個不難。另外,你也可以通過隨機分配的方式來派發任務,每一個工作節點統計上也會均勻分配到任務,這其實也就是一個負載均衡(Load Balancing)的過程。

      當然,你可能好奇上百個新聞網站是不是需要寫上百個爬蟲。對于這個問題,沒有確切的準確回答。答案應該是“看情況”。對于自動提取字段的算法不夠自信的開發者來說,可以選擇Crawlab的可配置爬蟲(看這篇文章《我是如何在3分鐘內開發完一個爬蟲的》),這樣的開發成本相對來說比較小。但是對于已經有技術實力的可以寫出很好的通用提取規則的選手來說,只寫一個通用爬蟲就足夠了(簡單的列表頁提取規則參考《爬蟲平臺Crawlab核心原理--自動提取字段算法》),抓取多個網站等于抓取一個網站,不過還是需要部署在多個機器上,以求最大的帶寬和計算資源。當然,不管是哪一種,都繞不開去重、反爬、錯誤監控,不過這些不在本文討論范圍,網上有很多教程可以多學習一下。

      往期文章

      爬蟲管理平臺Crawlab v0.3.0發布(Golang版本)

      爬蟲管理平臺Crawlab部署指南(Docker and more)

      爬蟲平臺Crawlab核心原理--自動提取字段算法

      [爬蟲手記] 我是如何在3分鐘內開發完一個爬蟲的

      手把手教你如何用Crawlab構建技術文章聚合平臺(二)

      手把手教你如何用Crawlab構建技術文章聚合平臺(一)

      分布式通用爬蟲管理平臺Crawlab

      MongoDB 分布式 Go Redis

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:微服務下使用GraphQL構建BFF
      下一篇:性能測試--需求提取
      相關文章
      国产精品日本亚洲777| 亚洲风情亚Aⅴ在线发布| 日韩精品亚洲专区在线观看| 亚洲三级在线观看| 久久精品国产亚洲av麻豆图片| 亚洲成av人片在线看片| 亚洲精品亚洲人成在线麻豆| 亚洲高清免费在线观看| 亚洲人成在线观看| 亚洲人成电影福利在线播放| 亚洲综合成人网在线观看| 亚洲天天在线日亚洲洲精| 精品亚洲成a人片在线观看少妇| 97久久精品亚洲中文字幕无码| 亚洲天堂中文字幕| 亚洲日本乱码一区二区在线二产线 | 亚洲va在线va天堂va四虎| 精品久久香蕉国产线看观看亚洲| 亚洲精品成人片在线播放| 亚洲AV无码专区电影在线观看| 亚洲情a成黄在线观看动漫尤物| 亚洲毛片在线免费观看| 亚洲av乱码一区二区三区| 亚洲一区二区三区国产精华液| 亚洲国产精品无码久久九九大片| xvideos亚洲永久网址| 亚洲精品老司机在线观看| 91麻豆国产自产在线观看亚洲| 中文字幕精品无码亚洲字 | 人人狠狠综合久久亚洲高清| 亚洲av高清在线观看一区二区| 亚洲女人被黑人巨大进入| 亚洲国产精品一区二区第一页免| 亚洲爽爽一区二区三区| 亚洲欧洲∨国产一区二区三区 | 亚洲heyzo专区无码综合| 亚洲精品成人片在线观看| 国产成人无码综合亚洲日韩| 中文字幕亚洲综合久久2| 国产成人精品日本亚洲18图| 亚洲avav天堂av在线网毛片|