1. 程式人生 > >RabbitMQ學習之四:釋出/訂閱(direct方式)

RabbitMQ學習之四:釋出/訂閱(direct方式)

這篇文章主要學習下exchange型別的第二種型別:direct

上一篇文章中,主要學習了RabbitMQ exchange的fanout(廣播方式),即producer傳送的訊息會被所有的消費者接收處理,有木有”強買強賣”的感覺呢(我不要你也塞給我,還要花費我的精力).在這篇中,我們將來一個”私人定製版”的訂閱.

其實這種模式沒有特別之處,主要是理解下面這個概念就行.

bindings(繫結)和routingKey(路由鍵)
關於bindings,官網有一段話:
A binding is a relationship between an exchange and a queue. This can be simply read as: the queue is interested in messages from this exchange.
翻譯一下: binding 是exchange(轉化器)和queue(佇列)關係的一種描述,可以簡單的被理解為:該佇列對這個exchange上的訊息感興趣.

在定義一段關係時,bindings可以帶一個routingKey(String型別)的引數,如下:

channel.queueBind(queueName, EXCHANGE_NAME, "hello");

表示該佇列只對routingKey為hello的訊息感興趣,而此時的routingKey從何而來呢,別忘了,我們還有一個producer呢,它不正是用來發布訊息的嗎?

channel.basicPublish(EXCHANGE_NAME, "hello", null, msg.getBytes());

上面這段程式碼的意思是我要發訊息給exchange,並且它的routingKey為hello.其實說白了,就是說: 發訊息給exchange時可以指定routingKey,exchange和佇列之間可以定義binding,接收者只處理binding和routingKey相同的訊息

.

這章的程式碼和上一章的基本不變,就不在這裡列出來了.

首先請注意,一旦建立了exchange, RabbitMQ是不允許對其改變的,不然會報錯(如圖:之前是有一個exchange_fanout的exchange了)
exchange概況

// 報錯資訊
com.rabbitmq.client.ShutdownSignalException: :channel error; reason: {#method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'type' for exchange 'exchange_fanout'
in vhost '/': received 'direct' but current is 'fanout', class-id=40, method-id=10), null, ""}

變動程式碼:

// 改變exchange名稱,上一章是"exchange_fanout",不能同名
private final static String EXCHANGE_NAME = "exchange_direct";
// 定義該exchange的型別為 direct
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 傳送訊息給有routingkey為hello的exchange
channel.basicPublish(EXCHANGE_NAME, "hello", null, msg.getBytes());

消費者變動:

private final static String EXCHANGE_NAME = "exchange_direct";

channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 確定exchange和佇列的binding: hello
channel.queueBind(queueName, EXCHANGE_NAME, "hello");

輸出結果如圖:
生產者

消費者3676

現在稍微變動下消費者的bindings:

// 把bindings變為"world"
channel.queueBind(queueName, EXCHANGE_NAME, "world");

輸出結果如下(之前的消費者執行緒沒有關閉):
生產者

消費者3676:
消費者3676

消費者6408:
消費者6408

從上面的輸出結果可以看到,bindings為hello的接到了訊息,而為world的卻依舊在等待…direct方式的實驗就到此結束啦,下面還會學習下topic的,敬請期待.