消息中間件基本上是互聯網公司必用的一個中間件,為什么要使用MQ,當然是因為能給我們的系統帶來很多好處。
消息隊列簡單來說是一種先進先出的數據結構,先簡單認識下。
一、
消息中間件主要應用場景主要三個方面是:異步、解耦、削峰
異步
異步比較好理解,很多公司其實本身系統的並發量還是訪問量不一定會很大,但是業務會很復雜,一個動作會牽扯到很多業務,當用戶觸發某個事件后,后面可能有N個步驟,這些步驟如果都需要一個一個串行去走完,那么用戶等待的時間就會非常長,這樣,即使系統的使用人數不多,也是不能接受的。
這個時候我們使用消息中間件去做異步處理就很好理解了,當有一個長鏈條操作時,我們將這個長鏈條進行拆分,使用異步去處理,舉個最常見的例子吧。
用戶下單,我們簡單可想的后續操作就有很多,如扣除優惠券,增加積分,消息提醒等等,這些操作在客戶下單的時候,他不需要馬上得到這些結果,我們完全可以進行異步操作。
當然,有人說,這個不是可以用多線程去操作么?其實這個就引出了下一個應用場景
解耦
在程序設計過程中,有一條原則是大家耳熟能詳的,高內聚、低耦合,如剛剛說的,雖然用多線程,可以進行異步,但是畢竟是一個流程中去調用,這樣系統必定耦合度會比較高,耦合度太高,容錯性就低,如上,其中一個系統出錯,就會導致整個系統出錯,而且如果又要增加業務,那整個系統需要重新發布,而且也需要再進行測試。
消息中間件怎么進行解耦呢?主系統下單完成后,寫入消息,其他的系統只要按照需要進行消費即可,這樣其他系統出錯了也不會影響主業務,也很方便的去增加或減少業務,只要增加消費或去掉消費即可。
削峰
削峰用最常見的秒殺來就很好理解,秒殺會使短時間內使系統面臨巨大流量,而平時系統的服務器硬件不需要配置這么高,那我們其他的服務,特別是數據庫這些,很容易就被打掛了,這個時候我們使用消息,將訪問請求都放到隊列中,讓業務分散到長時間去處理請求,這樣雖然暫時會使得系統變得慢一些,但不會使整個系統直接崩潰。
二、
當然,很多事情都有兩面性,只有好處沒有壞處的事情是很少的,那我們來想想消息會帶來哪些問題。
系統可用性降低
這個很好理解,既然引用了MQ,那就存在MQ宕機的情況,這必然就會造成業務影響,這里就要考慮MQ的高可用。
系統復雜度
添加一個組件,必然會帶來系統的復雜度,當我們引用一個組件,就要想到它可能帶來的問題。加上MQ后,既然是異步調用,那就要考慮消息有沒有被重復消費,消息有可能丟失,還有消息的傳遞順序。
一致性問題
分布式服務本身都會存在這個問題,A系統處理完業務,通過MQ分發送消息,那每個系統處理,都會有自己的狀態,A成功了,B失敗了,這樣必然就有數據一致性問題。
三、
ActiveMQ | RabbitMQ | RocketMQ | Kafka | |
---|---|---|---|---|
開發語言 | java | erlang | java | scala |
單機吞吐量 | 萬級 | 萬級 | 10萬級 | 10萬級 |
時效性 | ms級 | us級 | ms級 | ms級 |
可用性 | 高(主從架構) | 高(主從結構) | 非常高(分布式架構) | 非常高(分布式架構) |
消息可靠性 | 有較低概率丟失數據 | 基本不丟 | 經過參數優化,可以做到0丟失 | 經過參數優化,可以做到0丟失 |
功能支持 | MQ領域的功能極其完備 | 並發性能強,性能很好,延時低 | MQ功能較為完善,分布式,擴展性好 |
ActiveMQ 使用比較少了,RabbitMQ語言不是java,這點很要命, Kafka很好用,一般大數據領域使用的非常多,一般規模的話使用RocketMQ,畢竟阿里出品的,生態方面都比較穩。
四、
理論太多,容易勸退,先跑起來再說。
下載源碼
下載二進制文件即可,需要看源碼再下載源碼:https://rocketmq.apache.org/dowloading/releases/
上傳到服務器,工作之后還是建議買一台自己的服務器,個人服務器還是很便宜的。
unzip rocketmq-all-4.8.0-bin-release.zip
如果沒有安裝解壓工具,則安裝:
yum install -y unzip zip
可以修改下解壓包名稱
mv rocketmq-all-4.8.0-bin-release rocketmq
啟動RocketMq
4.1 啟動NameServer,以下命令都在bin目錄下
# 啟動命令,並且常駐內存,nohup 屬於后台啟動,當前目錄下生成 nohup.out 日志文件,也可以指定日志輸出位置。 $ nohup sh mqnamesrv & # 可以直接啟動項目 $ sh mqnamesrv : # 查看啟動日志,能看到 "The Name Server boot success" 字樣則成功 $ tail -f ~/logs/rocketmqlogs/namesrv.log
如果顯示沒有日志文件目錄,那說明沒有啟動成功,是因為默認的初始化內存8G,內存不足導致的
vi runserver.sh
vi runbroker.sh
找到設置內存的位置,改成256m即可
4.2 啟動 Broker 中間件
# 啟動命令,並且常駐內存,nohup 屬於后台啟動,當前目錄下生成 nohup.out 日志文件,也可以指定日志輸出位置。 nohup sh mqbroker -n localhost:9876 & # 直接啟動 sh mqbroker -n localhost:9876 : # 查看啟動日志 tail -f ~/logs/rocketmqlogs/broker.log
4.3 測試發送消息
打開兩個tab進行命令執行,可以更加直觀的查看
測試生產消息
export NAMESRV_ADDR=localhost:9876 sh tools.sh org.apache.rocketmq.example.quickstart.Producer
結果如下:
測試消費者
export NAMESRV_ADDR=localhost:9876 sh tools.sh org.apache.rocketmq.example.quickstart.Consumer
結果:
4.4 關閉mq
與啟動順序相反進行關閉,先關閉 broker、在關閉 nameserv
sh mqshutdown broker
sh mqshutdown namesrv
以上就是啟動mq的流程,其實還是挺簡單的,下面再介紹下幾個概念,后面再進行下深入學習。
五、
名字服務(Name Server):名稱服務充當路由消息的提供者。生產者或消費者能夠通過名字服務查找各主題相應的Broker IP列表。多個Namesrv實例組成集群,但相互獨立,沒有信息交換。
代理服務器(Broker Server):消息中轉角色,負責存儲消息、轉發消息。代理服務器在RocketMQ系統中負責接收從生產者發送來的消息並存儲、同時為消費者的拉取請求作准備。代理服務器也存儲消息相關的元數據,包括消費者組、消費進度偏移和主題和隊列消息等。
消息生產者(Producer):負責生產消息,一般由業務系統負責生產消息。一個消息生產者會把業務應用系統里產生的消息發送到broker服務器。RocketMQ提供多種發送方式,同步發送、異步發送、順序發送、單向發送。同步和異步方式均需要Broker返回確認信息,單向發送不需要。
消息消費者(Consumer):負責消費消息,一般是后台系統負責異步消費。一個消息消費者會從Broker服務器拉取消息、並將其提供給應用程序。從用戶應用的角度而言提供了兩種消費形式:拉取式消費、推動式消費。
主題(Topic):表示一類消息的集合,每個主題包含若干條消息,每條消息只能屬於一個主題,是RocketMQ進行消息訂閱的基本單位。