自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

馬蜂窩消息總線——面向業(yè)務(wù)的消息服務(wù)設(shè)計

開發(fā) 開發(fā)工具
在消息總線上線前,馬蜂窩大部分業(yè)務(wù)中的異步需求是通過 Redis 隊列來實現(xiàn)。隨著消息量增加,經(jīng)常會出現(xiàn)消息積壓、不同消息之間互相影響的問題。為解決這些問題,電商研發(fā)團隊開始規(guī)劃和設(shè)計消息總線。

 我們?yōu)槭裁葱枰⒖偩€?

在消息總線上線前,馬蜂窩大部分業(yè)務(wù)中的異步需求是通過 Redis 隊列來實現(xiàn)。隨著消息量增加,經(jīng)常會出現(xiàn)消息積壓、不同消息之間互相影響的問題。為解決這些問題,電商研發(fā)團隊開始規(guī)劃和設(shè)計消息總線。

為什么會有消息總線,而不是讓業(yè)務(wù)系統(tǒng)直接用 PHP 或者其他語言對接 RabbitMQ,Kafka 這樣的消息系統(tǒng)?

「消息總線和直接使用消息系列有什么實際的區(qū)別?」,這是很多研發(fā)同學一開始不太理解的地方。假如只是為了用一個性能更好的消息系統(tǒng)代替 Redis,確實并不需要消息總線的這個角色。

但當我們從實際業(yè)務(wù)角度出發(fā),對公司整體技術(shù)架構(gòu)和開發(fā)場景的梳理時,發(fā)現(xiàn)如果直接讓業(yè)務(wù)系統(tǒng)對接消息系統(tǒng),并不是一個很好的方式,并且至少會面臨以下問題:

系統(tǒng)分散。各開發(fā)團隊需要維護各自的消息服務(wù),彼此之間相對隔離。

增加開發(fā)難度。用戶需要關(guān)注具體消息所在消息服務(wù)的配置,關(guān)注不同業(yè)務(wù)的消息可能要對接不同種類的消息系統(tǒng)。

維護成本高。用戶需要管理自己消費服務(wù)的穩(wěn)定性,處理各種服務(wù)異常,保證消費的可靠性。特別對于 PHP 來說,這個成本還是比較高的。

管理難度大。沒法對業(yè)務(wù)消息的創(chuàng)建和訂閱關(guān)系進行統(tǒng)一管理,也不方便對業(yè)務(wù)消息中的敏感數(shù)據(jù)進行權(quán)限管理。

不易擴展。無法統(tǒng)一消息系統(tǒng)擴展功能(路由、延時、重試、消費確認等)的使用。

總體來說,直接使用消息系統(tǒng)可以被看成是一個面向技術(shù)的接入方式;而消息總線則期望通過隱藏部署、分組和通信等細節(jié),實現(xiàn)一個面向業(yè)務(wù)的接入方式。

架構(gòu)設(shè)計和技術(shù)實現(xiàn)

1. 架構(gòu)設(shè)計

消息總線隱藏了消息發(fā)送、路由、分組、存儲、消費負載、通信、高可用等一些列問題。對使用者來說,只需要在發(fā)送端調(diào)用一個 SDK 消息發(fā)送方法,在消費端提供一個 PHP 消費方法即可。

 

圖1 馬蜂窩消息總線架構(gòu)設(shè)計

馬蜂窩消息總線當前使用 RabbitMQ 作為消息引擎,在發(fā)送端提供了 SDK,作為消息總線的 Broker 角色,包含了消息路由分組的功能,負責消息的 Publish。

消息的訂閱關(guān)系,目前是持久化在 MySQL 中,在消息發(fā)送時會根據(jù)訂閱關(guān)系把消息投遞到對應(yīng)的業(yè)務(wù)消費者。

而在消費端,并沒有直接用 PHP 去接入 RabbitMQ,而是使用 Deliver 服務(wù)集群 (Golang 服務(wù)) 來負責把 AMQP 協(xié)議轉(zhuǎn)為 HTTP 協(xié)議,然后通過 PHPService 進行消費 PHP 代碼的執(zhí)行。

這個方案在設(shè)計時,同時考慮到了未來系統(tǒng)規(guī)模擴展后的消息分組,以及關(guān)鍵環(huán)節(jié)的可替代性。

  • SDK 充當了消息服務(wù) Broker 的角色,可以控制消息的路由、分組。未來在微服務(wù)體系中可以保持整體架構(gòu)不變,只采用其他方案實現(xiàn) Broker。
  • 可以根據(jù)業(yè)務(wù)場景對接不同的消息引擎,比如對業(yè)務(wù)一致性要求高的業(yè)務(wù)使用 RabbitMQ,而對并發(fā)要求較高的可以使用 Kafka。對業(yè)務(wù)來說是無感知的。
  • Deliver 和 Application Service 之間可擴展更多的通信協(xié)議,支持應(yīng)用更靈活的消費方式,包括支持未來在微服務(wù)中的消費服務(wù)。

2. 技術(shù)實現(xiàn)

1). 減少流轉(zhuǎn)復雜度

為了保證消息在消息總線內(nèi)各環(huán)節(jié)流轉(zhuǎn)時減少復雜度,能夠被統(tǒng)一處理,消息體被設(shè)計為統(tǒng)一的結(jié)構(gòu)。主要分為以下 3 個部分:

 

圖2 消息體的定義

  • Parameter——參數(shù)部分包含消息 ID,來源,時間等參數(shù)。
  • Conetent——消息內(nèi)容,在 PHP 中使用者可以把消費方法的輸入?yún)?shù)放入 Content 中。
  • Receiver——標注了消息的接收者 (PHP 中為消費者的方法)。

2). 在線服務(wù)異步

點對點模式是業(yè)務(wù)中常用的一種異步模式,

 

圖3 點對點消息模式

業(yè)務(wù)應(yīng)用把不需要在同步請求中執(zhí)行的邏輯放到異步去執(zhí)行。發(fā)送消息的業(yè)務(wù)需要明確處理消息的接收者 (消費的 PHP 方法)。消息在發(fā)送時需要明確指定唯一的一個 Receiver。

當前通過消息總線 SDK 提供的 invoke 方法可以指定消費的應(yīng)用方法。

 

3). 解耦

消息的發(fā)布訂閱模式,是一個標準的業(yè)務(wù)解耦模式。

 

圖4 發(fā)布訂閱(廣播)

App 1 的應(yīng)用只負責發(fā)出消息,至于什么業(yè)務(wù)需要關(guān)注,下游業(yè)務(wù)應(yīng)用自己訂閱該消息就可以。很大程度上減少了上游業(yè)務(wù)和下游業(yè)務(wù)的耦合程度和開發(fā)調(diào)試成本。

消息總線使用 DB 來進行消息訂閱關(guān)系的存儲,上游業(yè)務(wù)的消息經(jīng)過消息總線 Broker 時會根據(jù)訂閱關(guān)系,裂變?yōu)?Receiver 是訂閱應(yīng)用的多條消息。這樣的消息裂變方式使消息后續(xù)在消息總線流轉(zhuǎn)時目標明確,在進行消費負載,消費確認,失敗重試等場景時可以按照 Receiver 進行隔離。

同樣調(diào)用方可以使用 SDK 提供的 pub 方法進行消息的發(fā)送,訂閱方通過消息管理系統(tǒng)進行消息訂閱的申請。

 

4). 防消息干擾

很多使用消息總線的同學比較關(guān)心不同消息之間是否會相互干擾,比如由于某個消息短時間內(nèi)大量涌入是否會造成其他消息被阻塞。

通過前面架構(gòu)的介紹,可以看到所有的消息經(jīng)過 Broker 時可以進行路由、分組。消息總線未來會根據(jù)業(yè)務(wù)和消息量來做一些物理隔離,保障業(yè)務(wù)之間不會相互影響。

而在一個分組內(nèi),消息總線也有一些機制保障分組內(nèi)的不同消息不會相互影響。

 

圖5 防消息干擾機制

消息經(jīng)過 Broker 默認會進入一個 Online Queue 的隊列中,Deliver 集群中會有多個 Deliver 監(jiān)聽 Online Queue。在 Deliver 服務(wù)內(nèi),通過 Dispatcher 來控制消息總并發(fā)消費量,以及同類型消息的并發(fā)消費量。當某種類型的并發(fā)消息數(shù)量超過閾值時,就會被轉(zhuǎn)發(fā)到 Offline Queue,避免消費 Worker 都被同一個類型的消息占用。而 Offline Queue 會被獨立的 Deliver 服務(wù)監(jiān)聽進行消費,不影響 Online Queue 的消費。

5). 消費服務(wù)高可用

為了保證消費時的高可用,Deliever 群在負責進行消費協(xié)議轉(zhuǎn)換之外,也做了一些策略來保證消費端的高可用。

  • 熔斷

在消息一段時間內(nèi)失敗數(shù)量超過閾值時,停止對隊列的消費,避免由于服務(wù)抖動和線上故障引起的大面積消息。

  • 消費失敗

熔斷后,Deliver 服務(wù)會對后端應(yīng)用服務(wù)健康度進行監(jiān)控,在服務(wù)恢復后可自動恢復消費。

  • 系統(tǒng)失敗重試

消息總線服務(wù)發(fā)生故障時,可對期間的失敗消息采用重試策略進行重試,避免由于基礎(chǔ)服務(wù)問題造成的消費失敗。

  • 業(yè)務(wù)失敗重試

在業(yè)務(wù)應(yīng)用消費時產(chǎn)生業(yè)務(wù)異常,可在訂閱消息時指定是否進行重試。消息總線會對需要失敗的消息按照一定的時間周期進行多次重試。

  • Graceful 重啟

Deliver 實現(xiàn)了 Graceful 重啟和退出,保障當前正在消費的消息都處理完成后才會進程退出。

未來規(guī)劃

 

圖7 未來演進方向

1. 產(chǎn)品化

當前消息總線在功能上經(jīng)過近一年的迭代,已經(jīng)基本穩(wěn)定。但在消息管理,監(jiān)控,統(tǒng)計等環(huán)節(jié)對開發(fā)者來說還不夠友好,接下來一段時間會著重優(yōu)化系統(tǒng)的易用性。

目前已經(jīng)在規(guī)劃以下方向的優(yōu)化改進:

開發(fā)者可以通過消息管理系統(tǒng)進行新增消息,訂閱消息 (加入權(quán)限的審核) 等操作,代替當前手工提 issue 的方式。

開發(fā)者可以通過系統(tǒng)關(guān)注到自己消息的消費情況,并及時接收到消息處理異常的報警。

完善監(jiān)控體系,提供更精細維度的系統(tǒng)監(jiān)控數(shù)據(jù)。

2. 微服務(wù)

關(guān)于在微服務(wù)架構(gòu)內(nèi)提供消息總線服務(wù),也已經(jīng)在計劃當中。包括在微服務(wù)內(nèi)進行消息發(fā)送和使用某個微服務(wù)進行消息的消費。未來整個消息總線計劃會往下圖的架構(gòu)進行演進,增加對多語言和不同架構(gòu)服務(wù)的支持。適應(yīng)更多的業(yè)務(wù)開發(fā)場景,提供更穩(wěn)定,友好的消息總線服務(wù)。

另外對消息引擎的技術(shù)選型,未來也會考慮接入 Kafka,RocketMQ 等其他消息隊列服務(wù)。根據(jù)不同業(yè)務(wù)場景的消息特性,在發(fā)布時選擇進入不同的消息隊列服務(wù)。比如對可靠性,數(shù)據(jù)安全性要求高的消息會進入 RabbitMQ,而對高吞吐量的消息可以進入 Kafka。但對消息的發(fā)送方和訂閱方來說都可以不用關(guān)心這些細節(jié),仍然按照統(tǒng)一的方式進行接入。

馬蜂窩消息總線服務(wù)當前也在不斷迭代中,在很多地方還有不少沒有考慮到的問題。歡迎大家多提寶貴意見,您可以掃描下方二維碼訂閱「馬蜂窩技術(shù)」更多內(nèi)容。

本文作者:梁亮,馬蜂窩電商研發(fā)團隊技術(shù)專家。2004 年畢業(yè)于西安郵電大學,曾在新浪,開心網(wǎng),阿里巴巴等公司工作。先后從事搜索,社交,視頻,電商等多個方向的研發(fā)工作。于 2017 年加入馬蜂窩,現(xiàn)負責馬蜂窩電商平臺服務(wù)系統(tǒng)開發(fā)。

【本文是51CTO專欄作者馬蜂窩技術(shù)的原創(chuàng)文章,作者微信公眾號馬蜂窩技術(shù)(ID:mfwtech)】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2019-06-11 11:18:40

容災緩存設(shè)計

2019-06-11 12:19:10

ABTest分流系統(tǒng)

2019-02-27 15:24:54

馬蜂窩游搶單系統(tǒng)

2019-04-26 15:16:02

馬蜂窩火車票系統(tǒng)

2019-02-18 15:23:21

馬蜂窩MESLambda

2019-03-25 15:14:19

Flutter馬蜂窩開發(fā)

2022-06-20 09:00:00

深度學習人工智能研究

2020-03-22 15:49:27

Kafka馬蜂窩大數(shù)據(jù)平臺

2020-01-03 09:53:36

Kafka集群優(yōu)化

2018-10-29 12:27:20

2019-03-29 08:21:51

馬蜂窩Golang并發(fā)代理

2020-02-21 16:20:37

系統(tǒng)驅(qū)動項目管理

2018-10-26 16:00:39

程序員爬蟲馬蜂窩

2017-03-20 09:50:35

消息隊列架構(gòu)消息

2019-12-17 14:59:27

數(shù)據(jù)中臺數(shù)據(jù)倉庫馬蜂窩

2022-12-22 10:03:18

消息集成

2018-08-15 08:52:49

爬蟲出行城市數(shù)據(jù)

2019-04-12 14:22:40

馬蜂窩機票訂單

2025-04-14 05:00:00

2021-05-17 16:24:58

Spring Clou
點贊
收藏

51CTO技術(shù)棧公眾號