更正一下,rabbitMQ的消息的終點是隊列而非交換器,而rocketMQ的終點是topic,因為topic包含隊列。
正是dubbo的出現,才讓越來越多的公司選擇分布式架構。
例如在兩台機器上有兩個服務A、B,如果A要調用B的某個方法,使用http固然可以,但會比較麻煩,而采用RPC(遠程過程調用)就會讓你像調用本地方法一樣簡單,dubbo就是一個輕量級的RPC框架。
講一下RPC原理。
我用調用本地方法的方式調用遠程服務。
client stub接收到調用后將參數和方法等組裝成能在網絡運輸的消息體,並發送到服務端。
然后遠程服務server stub接收到消息體並解碼。
server stub把解碼后的數據交給本地方法進行調用,產生結果后將結果進行返回給server stub。
server stub再將結果進行打包返回給client stub,解碼后最終到達我這里。
分布式是面向服務的即SOA,我們常見的IE瀏覽器和服務端之間的通信是基於http的,而FPC能實現真正意義上的分布式,利用client stub和server stub之間傳輸數據而非http,更快。而且基於FPC的dubbo框架具有服務注冊和服務監聽功能。每一個服務提供者都要在注冊中心注冊自己的服務,而服務消費者則從注冊中心調用服務,監聽是為了監聽服務者和消費者調用的次數。注冊中心和監聽中心都宕機也不影響服務提供者和消費者,它們可以直連。而且消費者可以閱讀自己已經緩存的服務列表來和服務提供者取得聯系,因此若服務提供者全部宕機,那服務消費者就會一直發送連接請求。另外dubbo也提供了負載均衡的功能,就是說一堆集群的服務都注冊時,消費者不會一直消費某一個服務而讓其他服務空閑。
其實dubbo就是這么個東西,有一個注冊中心,所有的集群服務端都可以在這里注冊服務,所有的消費者都來dubbo消費,dubbo根據負載均衡策略來決定讓消費者消費哪個服務,同時監聽功能監聽服務者和消費者調用的次數。這里可以結合zookeeper統一管理集群的配置即每個服務提供者注冊watch事件,看到了znode信息變化就都同步改變。
dubbo的應用場景例如現在服務端是一堆機器的集群,dubbo就可以作為它們的頭,因為它有注冊中心。它能有效管理,因為它有負載均衡策略。zookeeper可作為dubbo的左右手,也可以叫做跑腿的。
消息中間件也叫消息隊列,有kafka、rabbitMQ、rocketMQ等。都是基於消息模型的,即生產者、主題、消費者。
rabbitMQ的主題是交換器,即消息的終點。
有四種類型,決定了是否路由消息到隊列的規則,fanout散開表示不管路由鍵和綁定鍵是否匹配都會將消息路由到所有隊列上。direct則是只將消息路由到路由鍵和綁定鍵完全匹配的隊列上。topic則是將綁定鍵用一個靠點號分隔並且用*代替零個或多個單詞的式子來表示例如sas.*(類似於正則表達式)。
rocketMQ就是把交換器換成了主題,主題里包含多個隊列。且每個隊列只能被一個消費者消費。
每個消費者可以被一個消費者組也就是消費者集群代替,這樣一個掛了其他可以接着上,消息消費過后會產生消費位移,這樣一個消費者組就不會消費到同一個消息。
如果生產者把消息送到topic后,topic只將每條消息發送到一個隊列,那么這叫集群模式,如果發到所有隊列,那叫廣播模式。因為一個消費者組只能消費一個隊列。其實廣播模式和集群模式的選擇在topic和隊列之間就已經確定了。
broker相當於消息隊列服務器,和topic的關系是多對多。broker類似於dubbo即有一個注冊中心。
rocket和rabbit的區別就是前者的主題相當於后者的交換機加上隊列。
服務端接收到一個請求后,將請求參數等寫入 消息中間件,然后返回執行下一次請求(這有點類似js的http異步執行,即當前線程立即返回讓下一個線程執行,而自己則異步執行自己的任務),JDK1.8以后,Future實現了真正的異步(以前是阻塞即等當前線程的任務執行完才返回也叫同步),因此我們將隊列的聲明以及消息的消費放到ExecutorService es=Executors.newFixedThreadPool(7);Future f=es.submit(new CallAble(){...})的...里面,這后面半句話相當於start了線程並且它是異步的即不影響當前線程的結束。f.get()前面有一大段代碼也沒事。
activeMQ雖然支持五種消息類型(鍵值對、流、二進制、對象序列、字符串),它是基於JMS(java API)的,支持兩種訂閱模式(一對一和一對多),但是它的性能最差,不推薦使用。關鍵是它沒有交換機,直接跟隊列搞事。
rabbitMQ具有交換器,producer將消息寫到交換器,會產生一個路由鍵。然后服務端的消息隊列綁定交換器,會產生一個綁定鍵,只有當綁定鍵和路由鍵匹配的時候消息才會路由到隊列,根據綁定鍵的類型決定是否路由消息到隊列里(也就是說根據交換器類型的不同,可能會無視綁定鍵,從而無腦地必定往隊列路由),消息隊列是作為容器的也就是消息到了消息隊列就算完成了,然后消費者可以消費同一個隊列,隊列和交換器不一樣,交換器可以發散一樣同時路由,而隊列是一根線只能按序,因此當有多個消費者時,會一部分被a消費者消費,另一部分被b消費者消費。