AMPQ

歷史

今天聊聊消息隊列
Advanced Message Queuing Protocol (AMQP)
AMQP:前進消息隊列協議
歷史:
消息隊列來源已久,80年代最早在金融交易中,高盛等公司采用Teknekron公司的產品,當時的Message queuing軟件叫做:the information bus(TIB)。
 TIB被電信和通訊公司采用,路透社收購了Teknekron公司。之后,IBM開發了MQSeries,微軟開發了Microsoft Message Queue(MSMQ)。
這些商業MQ供應商的問題是廠商鎖定,價格高昂。2001年,Java Message queuing試圖解決鎖定和交互性的問題,但對應用來說反而更加麻煩了。
于是2004年,摩根大通和iMatrix開始著手Advanced Message Queuing Protocol (AMQP)開放標準的開發。
2006年,AMQP規范發布。2007年,Rabbit技術公司基于AMQP標準開發的RabbitMQ 1.0 發布。后來又被spring收購
AMPQ是使用Erlang開發的,Erlang這哥們主要用來搞游戲與電信方面的東西,ok,下面說說AMPQ又什么用?

應用

RabbitMQ Server:維持roducer到Consumer的路線,保證數據能夠按照指定的方式進行傳輸。但是這個保證也不是100%的保證

Client A & B:數據的發送方,一個Message有兩個部分:payload(有效載荷)和label(標簽),payload顧名思義就是傳輸的數據。label是exchange的名字或者說是一個tag,
它描述了payload,而且RabbitMQ也是通過這個label來決定把這個Message發給哪個Consumer。AMQP僅僅描述了label,而RabbitMQ決定了如何使用這個label的規則。

Client 1,2,3:數據的接收方

Exchanges are where producers publish their messages.

 Queuesare where the messages end up and are received by consumers

Bindings are how the messages get routed from the exchange to particular queues.

 還有幾個概念是上述圖中沒有標明的,那就是Connection(連接),Channel(通道,頻道)。

   Connection: 就是一個TCP的連接。Producer和Consumer都是通過TCP連接到RabbitMQ Server的。以后我們可以看到,程序的起始處就是建立這個TCP連接。
   Channels: 虛擬連接。它建立在上述的TCP連接中。數據流動都是在Channel中進行的。也就是說,一般情況是程序起始建立TCP連接,第二步就是建立這個Channel。
建立和關閉TCP連接是有代價的,頻繁的建立關閉TCP連接對于系統的性能有很大的影響,而且TCP的連接數也有限制,這也限制了系統處理高并發的能力

一些說明

  默認情況下,如果Message 已經被某個Consumer正確的接收到了,那么該Message就會被從queue中移除。當然也可以讓同一個Message發送到很多的Consumer。
    如果一個queue沒被任何的Consumer Subscribe(訂閱),那么,如果這個queue有數據到達,那么這個數據會被cache,不會被丟棄。當有Consumer時,這個數據會被立即發送到這個Consumer,這個數據被Consumer正確收到時,這個數據就被從queue中刪除。
     那么什么是正確收到呢?通過ack。每個Message都要被acknowledged(確認,ack)。我們可以顯示的在程序中去ack,也可以自動的ack。如果有數據沒有被ack,那么:
     RabbitMQ Server會把這個信息發送到下一個Consumer。
    如果這個app有bug,忘記了ack,那么RabbitMQ Server不會再發送數據給它,因為Server認為這個Consumer處理能力有限。
   而且ack的機制可以起到限流的作用(Benefitto throttling):在Consumer處理完成數據后發送ack,甚至在額外的延時后發送ack,將有效的balance Consumer的load。
   當然對于實際的例子,比如我們可能會對某些數據進行merge,比如merge 4s內的數據,然后sleep 4s后再獲取數據。特別是在監聽系統的state,我們不希望所有的state實時的傳遞上去,而是希望有一定的延時。這樣可以減少某些IO,而且終端用戶也不會感覺到。
4.2 Reject a message
   有兩種方式,第一種的Reject可以讓RabbitMQ Server將該Message 發送到下一個Consumer。第二種是從queue中立即刪除該Message。
4.3  Creating a queue
      Consumer和Procuder都可以通過 queue.declare 創建queue。對于某個Channel來說,Consumer不能declare一個queue,卻訂閱其他的queue。當然也可以創建私有的queue。
這樣只有app本身才可以使用這個queue。queue也可以自動刪除,被標為auto-delete的queue在最后一個Consumer unsubscribe后就會被自動刪除。那么如果是創建一個已經存在的queue呢?
那么不會有任何的影響。需要注意的是沒有任何的影響,也就是說第二次創建如果參數和第一次不一樣,那么該操作雖然成功,但是queue的屬性并不會被修改。
    那么誰應該負責創建這個queue呢?是Consumer,還是Producer?
如果queue不存在,當然Consumer不會得到任何的Message。但是如果queue不存在,那么Producer Publish的Message會被丟棄。所以,還是為了數據不丟失,Consumer和Producer都try to create the queue!反正不管怎么樣,這個接口都不會出問題。
   queue對load balance的處理是完美的。對于多個Consumer來說,RabbitMQ 使用循環的方式(round-robin)的方式均衡的發送給不同的Consumer。
4.4 Exchanges   
    從架構圖可以看出,Procuder Publish的Message進入了Exchange。接著通過“routing keys”, RabbitMQ會找到應該把這個Message放到哪個queue里。queue也是通過這個routing keys來做的綁定。
     有三種類型的Exchanges:direct, fanout,topic。 每個實現了不同的路由算法(routing algorithm)。
·        Direct exchange: 如果 routing key 匹配, 那么Message就會被傳遞到相應的queue中。其實在queue創建時,它會自動的以queue的名字作為routing key來綁定那個exchange。
·        Fanout exchange: 會向響應的queue廣播。
·        Topic exchange: 對key進行模式匹配,比如ab*可以傳遞到所有ab*的queue。
4.5 Virtual hosts
   每個virtual host本質上都是一個RabbitMQ Server,擁有它自己的queue,exchagne,和bings rule等等。這保證了你可以在多個不同的application中使用RabbitMQ。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容