從零開始學架構二 架構設計流程

從零開始學架構二 架構設計流程

識別複雜度

架構的複雜度主要來源於「高性能」「高可用」「可擴展」等幾個方面nginx

  1. 「高性能」主要從軟件系統將來的TPS、響應時間、服務器資源利用率等客觀指標,也能夠從用戶的主觀感覺方面去考慮。
  2. 「可用性」主要從服務不中斷等質量屬性,符合行業政策、國家法規等方面去考慮。
  3. 「擴展性」則主要從功能需求的將來變動幅度等方面去考慮。

常見的性能指標:nginx負載均衡性能是3萬左右,mc的讀取性能5萬左右,kafka號稱百萬級,zookeeper寫入讀取2萬以上,http請求訪問大概在2萬左右。算法

消息隊列的複雜性主要體如今這幾個方面:高性能消息讀取、高可用消息寫入、高可用消息存儲、高可用消息讀取。數據庫

設計備選方案

(1)備選方案不要過於詳細。備選=階段解決的是技術選型問題,而不是技術細節。
(2)備選方案的數量以 3~5個爲最佳。
(3)備選方案的技術差別要明顯。
(4)備選方案不要只侷限於已經熟悉的技術。編程

評估和選擇備選方案

RocketMQ 和 Kafka 有什麼區別?

(1) 適用場景
Kafka適合日誌處理;RocketMQ適合業務處理。
公號-Java大後端
2018-05-24
極客時間
hongfenghuoju/7832[2018/8/6 9:13:44]
(2) 性能
Kafka單機寫入TPS號稱在百萬條/秒;RocketMQ大約在10萬條/秒。Kafka單機性能更高。
(3) 可靠性
RocketMQ支持異步/同步刷盤;異步/同步Replication;Kafka使用異步刷盤方式,異步Replication。RocketMQ所支持的同步方式提高了數據的可靠性。
(4) 實時性
均支持pull長輪詢,RocketMQ消息實時性更好
(5) 支持的隊列數
Kafka單機超過64個隊列/分區,消息發送性能下降嚴重;RocketMQ單機支持最高5萬個隊列,性能穩定(這也是適合業務處理的緣由之一)後端

詳細方案設計

Nginx的負載均衡策略,五個

備選有輪詢、權重分配、ip_hash、fair、url_hash緩存

輪詢(默認)服務器

每一個請求按時間順序逐一分配到不一樣的後端服務器,後端服務器分配的請求數基本一致,若是後端服務器「down掉」,能自動剔除。
加權輪詢
根據權重來進行輪詢,權重高的服務器分配的請求更多,主要適應於後端服務器性能不均的狀況,如新老服務器混用。
ip_hash
每一個請求按訪問IP的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,主要用於解決session的問題,如購物車類的應用。
fair
按後端服務器的響應時間來分配請求,響應時間短的優先分配,可以最大化地平衡各後端服務器的壓力,能夠適用於後端服務器性能不均衡的狀況,也能夠防止某臺後端服務器性能
不足的狀況下還繼續接收一樣多的請求從而形成雪崩效應。
url_hash
按訪問URL的hash結果來分配請求,每一個URL定向到同一個後端服務器,適用於後端服務器可以將URL的響應結果緩存的狀況。網絡

1.數據庫表如何設計?

數據庫設計兩類表,一類是日誌表,用於消息寫入時快速存儲到MySQL中;另外一類是消息表,每一個消息隊列一張表。
業務系統發佈消息時,首先寫入到日誌表,日誌表寫入成功就表明消息寫入成功;後臺線程再從日誌表中讀取消息寫入記錄,將消息內容寫入到消息表中。
業務系統讀取消息時,從消息表中讀取。
日誌表表名爲MQ_LOG,包含的字段:日誌ID、發佈者信息、發佈時間、隊列名稱、消息內容。
消息表表名就是隊列名稱,包含的字段:消息ID(遞增生成)、消息內容、消息發佈時間、消息發佈者。
日誌表須要及時清除已經寫入消息表的日誌數據,消息表最多保存30天的消息數據。session

2.數據如何複製?

直接採用MySQL主從複製便可,只複製消息存儲表,不復制日誌表。架構

3.主備服務器如何倒換?

採用ZooKeeper來作主備決策,主備服務器都鏈接到ZooKeeper創建本身的節點,主服務器的路徑規則爲「/MQ/server/分區編號/master」,備機爲「/MQ/server/分區編
號/slave」,節點類型爲EPHEMERAL。
備機監聽主機的節點消息,當發現主服務器節點斷連後,備服務器修改本身的狀態,對外提供消息讀取服務。

4.業務服務器如何寫入消息?

消息隊列系統設計兩個角色:生產者和消費者,每一個角色都有惟一的名稱。
消息隊列系統提供SDK供各業務系統調用,SDK從配置中讀取全部消息隊列系統的服務器信息,SDK採起輪詢算法發起消息寫入請求給主服務器。若是某個主服務器無響應或者
返回錯誤,SDK將發起請求發送到下一臺服務器。

5.業務服務器如何讀取消息?

消息隊列系統提供SDK供各業務系統調用,SDK從配置中讀取全部消息隊列系統的服務器信息,輪流向全部服務器發起消息讀取請求。
消息隊列服務器須要記錄每一個消費者的消費狀態,即當前消費者已經讀取到了哪條消息,當收到消息讀取請求時,返回下一條未被讀取的消息給消費者。

6.業務服務器和消息隊列服務器之間的通訊協議如何設計?

考慮到消息隊列系統後續可能會對接多種不一樣編程語言編寫的系統,爲了提高兼容性,傳輸協議用TCP,數據格式爲ProtocolBufer

補充:

一、發送端和消費端如何尋址
利用zookeeper作註冊中心,把broker的地址註冊到zk上,發送端和消費端只要配置註冊中心的地址便可獲取集羣因此broker地址,當有broker下線時,發送端和消費端能及時更新broker地
址。
二、發送端消息重試
當發送消息發生網絡異常時(不包括超時異常),能夠從新選擇下一臺broker來重試發送,重試策略能夠自定義。
三、消息消費採用pull仍是push?
考慮push模式會更復雜,故放棄,採用pull模式,消費端主動去拉,爲了達到與push模式相同的低延遲效果,能夠採用長輪詢的方式,消費端輪詢拉取消息費,當有消費可消費時,返回消息,
若是沒有可消費的消息,掛起當前線程,直到超時或者有可消費的消息爲止。
四、消息重複問題
消息中間件不解決消息重複的問題,有業務系統本身根據業務的惟一id去重。
五、順序消息
發送端在發生順序消息時,只發送到相同broker的相同隊列,消費端消費時,順序消息只能由同一個消費端消息。
六、定時消息
發送端指定消息延時多長時間消費,broker端定時掃描定時消息,達到延時時間的消息加入到消費隊列。
七、事務消息
發送端分兩步,先預發送消息,broker端只記錄消息爲預發送狀態,再執行本地事務,而後再根據本地事務的成功或者失敗發送確認消息(回滾仍是提交),這步若是發生異常,broker啓動定
時任務,把未確認的消息發送給發送端回查事務狀態(須要發送端提供回查接口)。

Memcache是純內存緩存,支持基於一致性hash的集羣;而Redis同時支持持久化、 支持數據字典、支持主備、支持集羣,看起來比Memcache好不少啊

相關文章
相關標籤/搜索