鐵人賽來到尾聲,剩下最後的幾天,想開始做一些應用面的總結。今天是第一個總結,要講講關於每個中大型系統都會有的高併發任務設計,結尾會再補一個應用是關於網路爬蟲系統實例。講精確一點,每個系統總是會碰到定期要做一些事情或是像非同步請求用一個很大的中繼層收起來在慢慢消化掉,我們今天就是要來探討一下大概有什麼作法然後有什麼演進。
支援其實很多,通常程式語言本體就都會有支援一些簡單版的,進階的在框架的實作也會看到,又或者你想要把它設計在系統環境面都是可以的,端看你如何去設計及考量。
部屬多台一模一樣的架構,然後去搶一個外部鎖,也許是 ZK、Redis、DB,搶到的人可以執行任務。操作粒度很粗,但作法很簡單。
分成兩種節點,Master & Agent。Master 節點不做事只負責調度,分派工作給 Agent 去做,這是十分常見的主流作法。
通常會配上一個 MOM (Message Oriented Middleware),實作生產與消費者模型。現代的 MOM 多半都已經非常的強壯,線上能把它灌爆的場景並不是很多,在硬體條件容許的狀況下,會被視為大黑洞什麼都吃的下去慢慢讓 Producer 消化。所以只要碰到那種巨量請求又可以允許非同步的場景,擋 Queue 是很經典的一招。
使用分散式節點計算,這跟流式處理通常也有一點關係。重點在把你的系統設計成多個節點,需要分流時就分散出去各個節點執行再視情況要不要一一把結果收回來,有人可能會聯想到 Map Reduce,基本上概念上就是這樣。那跟流式處理啥關係?其實就是把本來是在單體內的流式處理加上通訊的功能,也許是 HTTP 或是其他協定,讓他有辦法散出去收回來即可。
只有 Master 能做,可用Redis ZK DB 確立誰為 Master,其他時間的 Instance 是 Hot Standby 等著。
概念上就沒有那種誰是 Master 誰能做事的感覺。大家一樣大,變成每一個 Method 執行之前都要去搶鎖。
最簡單的作法就是發 GET 出去然後把整個 Response 弄回來當文本解析,通常會在配上 Regular Expression 的技巧來快速解析。
第二種就上面差不多,但透過框架幫你作掉一些基礎功能,同時會有一些比較先進的功能例如 CSS Selector 來增加你開發的效率。
再來是更厲害一點的就是直接調用它那些不是 GET 的 Request。例如直接發 POST 到它回資料的那隻 API,不過這招難是難在對方也不會傻傻讓你打,一定會有驗證的部份,怎麼破它驗證才是重點。
最後是用瀏覽器內核做出的框架,你在寫程式基本上就已經是在模擬假的用戶瀏覽器操作了。所以原本你怎麼用滑鼠操作看到那些資料,現在就改成編程的方式來做。
如果你每一個爬蟲寫成一個 Method,那只需定時驅動它就好,但如果你有很多個爬蟲那你可能要上多執行緒,定時用不同的執行緒驅動他們。執行緒一多就會有管理問題,那通常就是引入 Thread Pool 去控。當然上面的事很基底的事情,自然也有框架可以幫你做掉
引入多執行緒跟 Thread Pool 之後那其實接下來就是 這篇 在講的事情了。我也就不多說,直接一個連結跳回去。
About Me
Jian-Min Huang
wide range skill set backend engineer
Research, Architecture, Coding, DB, Ops, Infra.
mainly write Java but also ❤️ Scala, Kotlin and Go