用消息中間件猶如小馬過河,選擇合適的才最重要,這須要貼合自身的業務需求,技術服務於業務。具體在選擇上可從下面功能、性能、可靠性和可用性、運維管理、社區和生態、團隊技術棧等維度來進行篩選。html
具體技術選型指標1:功能ios
首要的就是功能維度,這個直接決定了你可否最大程度上的實現開箱即用,進而縮短項目週期、下降成本等。若是一款消息中間件的功能達不到想要的功能,那麼就須要進行二次開發,這樣會增長項目的技術難度、複雜度以及增大項目週期等。程序員
功能維度又能夠劃分個多個子維度,大體能夠分爲如下這些。編程
具體技術選型指標2:性能緩存
功能維度是消息中間件選型中的一個重要的參考維度,但這並非惟一的維度。有時候性能比功能還要重要,何況性能和功能不少時候是相悖的,魚和熊掌不可兼得,Kafka 在開啓冪等、事務功能的時候會使其性能下降,RabbitMQ 在開啓 rabbitmq_tracing 插件的時候也會極大的影響其性能。消息中間件的性能通常是指其吞吐量,雖然從功能維度上來講,RabbitMQ 的優點要大於 Kafka,可是 Kafka 的吞吐量要比 RabbitMQ 高出 1 至 2 個數量級,通常 RabbitMQ 的單機 QPS 在萬級別以內,而 Kafka 的單機 QPS 能夠維持在十萬級別,甚至能夠達到百萬級。安全
消息中間件的吞吐量始終會受到硬件層面的限制。就以網卡帶寬爲例,若是單機單網卡的帶寬爲 1Gbps,若是要達到百萬級的吞吐,那麼消息體大小不得超過 (1Gb/8)/100W,即約等於 134B,換句話說若是消息體大小超過 134B,那麼就不可能達到百萬級別的吞吐。這種計算方式一樣能夠適用於內存和磁盤。性能優化
時延做爲性能維度的一個重要指標,卻每每在消息中間件領域所被忽視,由於通常使用消息中間件的場景對時效性的要求並非很高,若是要求時效性徹底能夠採用 RPC 的方式實現。消息中間件具有消息堆積的能力,消息堆積越大也就意味着端到端的時延也就越長,與此同時延時隊列也是某些消息中間件的一大特點。那麼爲何還要關注消息中間件的時延問題呢?消息中間件可以解耦系統,對於一個時延較低的消息中間件而言,它可讓上游生產者發送消息以後能夠迅速的返回,也可讓消費者更加快速的獲取到消息,在沒有堆積的狀況下可讓總體上下游的應用之間的級聯動做更加高效,雖然不建議在時效性很高的場景下使用消息中間件,可是若是所使用的消息中間件的時延方面比較優秀,那麼對於總體系統的性能將會是一個不小的提高。服務器
具體技術選型指標3:可靠性 + 可用性網絡
消息丟失是使用消息中間件時所不得不面對的一個同點,其背後消息可靠性也是衡量消息中間件好壞的一個關鍵因素。尤爲是在金融支付領域,消息可靠性尤其重要。然而說到可靠性必然要說到可用性,注意這二者之間的區別,消息中間件的可靠性是指對消息不丟失的保障程度;而消息中間件的可用性是指無端障運行的時間百分比,一般用幾個 9 來衡量。架構
不少時候,對於可靠性方面也容易存在一個誤區: 想要找到一個產品來保證消息的絕對可靠,很不幸的是這世界上沒有絕對的東西,只能說盡可能趨於完美 。想要儘量的保障消息的可靠性也並不是單單隻靠消息中間件自己,還要依賴於上下游,須要從生產端、服務端和消費端這 3 個維度去努力保證,《RabbitMQ 消息可靠性分析》這篇文章就從這 3 個維度去分析了 RabbitMQ 的可靠性。從狹義的角度來講,分佈式系統架構是一致性協議理論的應用實現,對於消息可靠性和可用性而言也能夠追溯到消息中間件背後的一致性協議。對於 Kafka 而言,其採用的是相似 PacificA 的一致性協議,經過 ISR(In-Sync-Replica)來保證多副本之間的同步,而且支持強一致性語義(經過 acks 實現)。對應的 RabbitMQ 是經過鏡像環形隊列實現多副本及強一致性語義的。多副本能夠保證在 master 節點宕機異常以後能夠提高 slave 做爲新的 master 而繼續提供服務來保障可用性。Kafka 設計之初是爲日誌處理而生,給人們留下了數據可靠性要求不高的不良印象,可是隨着版本的升級優化,其可靠性獲得極大的加強,詳細能夠參考 KIP101。就目前而言,在金融支付領域使用 RabbitMQ 居多,而在日誌處理、大數據等方面 Kafka 使用居多,隨着 RabbitMQ 性能的不斷提高和 Kafka 可靠性的進一步加強,相信彼此都能在之前不擅長的領域分得一杯羹。
同步刷盤是加強一個組件可靠性的有效方式,消息中間件也不例外,Kafka 和 RabbitMQ 均可以支持同步刷盤,可是筆者對同步刷盤有必定的疑問:絕大多數情景下,一個組件的可靠性不該該由同步刷盤這種極其損耗性能的操做來保障,而是採用多副本的機制來保證。
這裏還要說起的一個方面是擴展能力,這裏我狹隘地將此概括到可用性這一維度,消息中間件的擴展能力可以加強其用可用能力及範圍,好比前面提到的 RabbitMQ 支持多種消息協議,這個就是基於其插件化的擴展實現。還有從集羣部署上來說,歸功於 Kafka 的水平擴展能力,其基本上能夠達到線性容量提高的水平,在 LinkedIn 實踐介紹中就說起了有部署超過千臺設備的 Kafka 集羣。
具體技術選型指標4:運維管理
在消息中間件的使用過程當中不免會出現各式各樣的異常狀況,有客戶端的,也有服務端的,那麼怎樣及時有效的進行監測及修復。業務線流量有峯值又低谷,尤爲是電商領域,那麼怎樣前進行有效的容量評估,尤爲是大促期間?腳踢電源、網線被挖等事件層出不窮,如何有效的作好異地多活?這些都離不開消息中間件的衍生產品——運維管理。
運維管理也能夠進行進一步的細分,好比:申請、審覈、監控、告警、管理、容災、部署等。
申請、審覈很好理解,在源頭對資源進行管控,既能夠進行有效校訂應用方的使用規範,配和監控也能夠作好流量統計與流量評估工做,通常申請、審覈與公司內部系統交融性較大,不適合使用開源類的產品。
監控、告警也比較好理解,對消息中間件的使用進行全方位的監控,便可覺得系統提供基準數據,也能夠在檢測到異常的狀況配合告警,以便運維、開發人員的迅速介入。除了通常的監控項(好比硬件、GC 等)以外,對於消息中間件還須要關注端到端時延、消息審計、消息堆積等方面。對於 RabbitMQ 而言,最正統的監控管理工具莫過於 rabbitmq_management 插件了,可是社區內還有 AppDynamics, Collectd, DataDog, Ganglia, Munin, Nagios, New Relic, Prometheus, Zenoss 等多種優秀的產品。Kafka 在此方面也絕不遜色,好比:Kafka Manager, Kafka Monitor, Kafka Offset Monitor, Burrow, Chaperone, Confluent Control Center 等產品,尤爲是 Cruise 還能夠提供自動化運維的功能。
無論是擴容、降級、版本升級、集羣節點部署、仍是故障處理都離不開管理工具的應用,一個配套完備的管理工具集能夠在遇到變動時作到事半功倍。故障可大可小,通常是一些應用異常,也能夠是機器掉電、網絡異常、磁盤損壞等單機故障,這些故障單機房內的多副本足以應付。若是是機房故障就要涉及異地容災了,關鍵點在於如何有效的進行數據複製,對於 Kafka 而言,能夠參考 MirrorMarker、uReplicator 等產品,而 RabbitMQ 能夠參考 Federation 和 Shovel。
具體技術選型指標5:社區力度及生態發展
對於目前流行的編程語言而言,如 Java、Python,若是你在使用過程當中遇到了一些異常,基本上能夠經過搜索引擎的幫助來獲得解決,由於一個產品用的人越多,踩過的坑也就越多,對應的解決方案也就越多。對於消息中間件也一樣適用,若是你選擇了一種「生僻」的消息中間件,可能在某些方面運用的駕輕就熟,可是版本更新緩慢、遇到棘手問題也難以獲得社區的支持而越陷越深;相反若是你選擇了一種「流行」的消息中間件,其更新力度大,不只能夠迅速的彌補以前的不足,並且也能順應技術的快速發展來變動一些新的功能,這樣可讓你以「站在巨人的肩膀上」。在運維管理維度咱們說起了 Kafka 和 RabbitMQ 都有一系列開源的監控管理產品,這些正是得益於其社區及生態的迅猛發展。
消息中間件選型還有一個考量標準就是儘可能貼合團隊自身的技術棧體系,雖說沒有蹩腳的消息中間件只有蹩腳的程序員,可是讓一個 C 棧的團隊去深挖 PhxQueue 總比去深挖 Scala 編寫的 Kafka 要容易的多。
消息中間件選型切忌一味的追求性能或者功能,性能能夠優化,功能能夠二次開發。若是要在功能和性能方面作一個抉擇的話,那麼首選性能,由於整體上來講性能優化的空間沒有功能擴展的空間大。然而對於長期發展而言,生態又比性能以及功能都要重要。
消息中間件大道至簡:一發一存一消費,沒有最好的消息中間件,只有最合適的消息中間件。