44.第36章 消息隊列與微服務


一.RabbitMQ

1.1 RabbitMQ簡介

RabbitMQ 采用Erlang 語言開發,Erlang 語言由Ericson 設計,Erlang 在分布式編程和故障恢復方面表現出色,電信領域被廣泛使用。
https://www.erlang.org/

Broker: 接收和分發消息的應用,RabbitMQ Server 就是Message Broker。
Virtual host: 出於多租戶和安全因素設計的,把AMQP 的基本組件划分到一個虛擬的分組中,類似於網絡中的namespace 概念,當多個不同的用戶使用同一個RabbitMQ server 提供的服務時,可以划分出多個vhost,每個用戶在自己的vhost創建exchange/queue 等。
Connection: publisher/consumer 和broker 之間的TCP 連接。
Channel: 如果每一次訪問RabbitMQ 都建立一個Connection,在消息量大的時候建立TCP Connection 的開銷將是巨大的,效率也較低。Channel 是在connection內部建立的邏輯連接,如果應用程序支持多線程,通常每個thread 創建單獨的channel 進行通訊,AMQP method 包含了channel id 幫助客戶端和message broker識別channel,所以channel 之間是完全隔離的。Channel 作為輕量級的Connection極大減少了操作系統建立TCP connection 的開銷。
Exchange: message 到達broker 的第一站,根據分發規則,匹配查詢表中的routing key, 分發消息到queue 中去。常用的類型有: direct (point-to-point), topic (publish-subscribe) and fanout (multicast)。
Queue: 消息最終被送到這里等待consumer 取走。
Binding: exchange 和queue 之間的虛擬連接,binding 中可以包含routing key。Binding 信息被保存到exchange 中的查詢表中,用於message 的分發依據。

rabbitmq 優勢:
基於erlang 語言開發,具有高並發優點、支持分布式
具有消息確認機制、消息持久化機制,消息可靠性和集群可靠性高
簡單易用、運行穩定、跨平台、多語言
開源
Queue 的特性:
消息基於先進先出的原則進行順序消費
消息可以持久化到磁盤節點服務器
消息可以緩存到內存節點服務器提高性能

1.2 RabbitMQ 中的生產者消費者示例

生產者發送消息到broker server(RabbitMQ),在Broker 內部,用戶創建Exchange/Queue,通過Binding 規則將兩者聯系在一起,Exchange 分發消息,根據類型/binding 的不同分發策略有區別,消息最后來到Queue 中,等待消費者取走。

JMS 是在2001 年發布的Java 消息服務(Java Message Service)應用程序接口,是一個Java 平台中關於面向消息中間件(MOM,message oriented middleware)的API,用於在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。

二.ZooKeeper 使用場景

ZooKeeper 是一個分布式服務框架,它主要是用來解決分布式應用中經常遇到的一些數據管理問題,如:命名服務、狀態同步、配置中心、集群管理等。

2.1 命名服務

命名服務是分布式系統中比較常見的一類場景。命名服務是分布式系統最基本的公共服務之一。在分布式系統中,被命名的實體通常可以是集群中的機器、提供的服務地址或遠程對象等——這些我們都可以統稱它們為名字(Name),其中較為常見的就是一些分布式服務框架(如RPC、RMI)中的服務地址列表,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源的實體、服務地址和提供者的信息等。

2.2 狀態同步

每個節點除了存儲數據內容和node 節點狀態信息之外,還存儲了已經注冊的APP 的狀態信息,當有些節點或APP 不可用,就將當前狀態同步給其他服務。

2.3 配置中心

現在我們大多數應用都是采用的是分布式開發的應用,搭建到不同的服務器上,我們的配置文件,同一個應用程序的配置文件一樣,還有就是多個程序存在相同的配置,當我們配置文件中有個配置屬性需要改變,我們需要改變每個程序的配置屬性,這樣會很麻煩的去修改配置,那么可用使用ZooKeeper 來實現配置中心,ZooKeeper 采用的是推拉相結合的方式: 客戶端向服務端注冊自己需要關注的節點,一旦該節點的數據發生變更,那么服務端就會向相應的客戶端發送Watcher 事件通知,客戶端接收到這個消息通知后,需要主動到服務端獲取最新的數據。

2.4 集群管理

所謂集群管理,包括集群監控與集群控制兩大塊,前者側重對集群運行時狀態的收集,后者則是對集群進行操作與控制,在日常開發和運維過程中,我們經常會有類似於如下的需求:
希望知道當前集群中究竟有多少機器在工作。
對集群中每台機器的運行時狀態進行數據收集。
對集群中機器進行上下線操作。
ZooKeeper 具有以下兩大特性。
客戶端如果對ZooKeeper 的一個數據節點注冊Watcher 監聽,那么當該數據節點的內容或是其子節點列表發生變更時,ZooKeeper 服務器就會向訂閱的客戶端發送變更通知。
對在ZooKeeper 上創建的臨時節點,一旦客戶端與服務器之間的會話失效,那么該臨時節點也就被自動清除。
Watcher(事件監聽器),是Zookeeper 中的一個很重要的特性。Zookeeper允許用戶在指定節點上注冊一些Watcher,並且在一些特定事件觸發的時候,ZooKeeper 服務端會將事件通知到感興趣的客戶端上去,該機制是Zookeeper實現分布式協調服務的重要特性。

三.kafka

3.1 kafka優勢

kafka 通過O(1)的磁盤數據結構提供消息的持久化,這種結構對於即使數以TB 的消息存儲也能夠保持長時間的穩定性能。

高吞吐量:即使是非常普通的硬件Kafka 也可以支持每秒數百萬的消息。

支持通過Kafka 服務器分區消息。

支持Hadoop 並行數據加載。

O(1)就是最低的時空復雜度了,也就是耗時/耗空間與輸入數據大小無關,無論輸入數據增大多少倍,耗時/耗空間都不變,哈希算法就是典型的O(1)時間復雜度,無論數據規模多大,都可以在一次計算后找到目標

3.2 kafka 角色

Broker:Kafka 集群包含一個或多個服務器,這種服務器被稱為broker。

Topic :每條發布到Kafka 集群的消息都有一個類別,這個類別被稱為topic,(物理上不同topic 的消息分開存儲在不同的文件夾,邏輯上一個topic 的消息雖然保存於一個或多個broker 上但用戶只需指定消息的topic 即可生產或消費數據而不必關心數據存於何處),topic 在邏輯上對record(記錄、日志)進行分組保存,消費者需要訂閱相應的topic 才能消費topic 中的消息。

Partition :是物理上的概念,每個topic 包含一個或多個partition,創建topic 時可指定parition 數量,每個partition 對應於一個文件夾,該文件夾下存儲該partition 的數據和索引文件,為了實現實現數據的高可用,比如將分區0 的數據分散到不同的kafka 節點,每一個分區都有一個broker 作為leader 和一個broker作為Follower。

分區的優勢(分區因子為3):
一:實現存儲空間的橫向擴容,即將多個kafka 服務器的空間結合利用
二:提升性能,多服務器讀寫
三:實現高可用,分區leader 分布在不同的kafka 服務器,比如分區0 的leader為服務器A,則服務器B 和服務器C 為A 的follower,而分區1 的leader 為服務器B,則服務器A 和C 為服務器B 的follower,而分區2 的leader 為C,則服務器A 和B 為C 的follower。

Producer:負責發布消息到Kafka broker。

Consumer:消費消息,每個consumer 屬於一個特定的consuer group(可為每個consumer 指定group name,若不指定group name 則屬於默認的group),使用consumer high level API 時,同一topic 的一條消息只能被同一個consumer group內的一個consumer 消費,但多個consumer group 可同時消費這一消息。

四.微服務與dubbo

Dubbo 架構

調用關系說明
  1. 服務容器負責啟動,加載,運行服務提供者。

  2. 服務提供者在啟動時,向注冊中心注冊自己提供的服務。

  3. 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。

  4. 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。

  5. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。

  6. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。

    Dubbo 架構具有以下幾個特點,分別是連通性、健壯性、伸縮性、以及向未來架構的升級性。
    連通性

  • 注冊中心負責服務地址的注冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小

  • 監控中心負責統計各服務調用次數,調用時間等,統計先在內存匯總后每分鍾一次發送到監控中心服務器,並以報表展示

  • 服務提供者向注冊中心注冊其提供的服務,並匯報調用時間到監控中心,此時間不包含網絡開銷

  • 服務消費者向注冊中心獲取服務提供者地址列表,並根據負載算法直接調用提供者,同時匯報調用時間到監控中心,此時間包含網絡開銷

  • 注冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外

  • 注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者

  • 注冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表

  • 注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者

    健壯性

  • 監控中心宕掉不影響使用,只是丟失部分采樣數據

  • 數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務

  • 注冊中心對等集群,任意一台宕掉后,將自動切換到另一台

  • 注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊

  • 服務提供者無狀態,任意一台宕掉后,不影響使用

  • 服務提供者全部宕掉后,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復

    伸縮性

  • 注冊中心為對等集群,可動態增加機器部署實例,所有客戶端將自動發現新的注冊中心

  • 服務提供者無狀態,可動態增加機器部署實例,注冊中心將推送新的服務提供者信息給消費者

    升級性
    當服務集群規模進一步擴大,帶動IT治理結構進一步升級,需要實現動態部署,進行流動計算,現有分布式服務架構不會帶來阻力。下圖是未來可能的一種架構:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM