在上一節中我們創建了一個日志系統。實現將日志消息廣播給所有的cusumer。
在這片教程中,我們將為日志系統添加一個功能:僅僅訂閱一部分消息。比如:我們可以直接將關鍵的錯誤類型日志消息保存到日志文件中,還可以同時將所有的日志消息打印到控制台。
綁定(binding)
在之前的例子中,我們已經創建了綁定:
channel.queueBind(queueName,EXCHANGE_NAME,"");
一個綁定是建立在一個隊列和一個路由器之間的關系,可以解讀為:該隊列對這個路由器中的消息感興趣。
綁定可以設置另外的參數:路由鍵(routing key)。為了避免和producer中的void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)中的routingKey混淆,我們將這里的key稱為綁定鍵binding key,下面的代碼展示了如何使用綁定鍵來創建一個綁定關系:
channel.queueBind(queueName,EXCHANGE_NAME,"black");
綁定鍵的含義取決於路由器的類型,我們之前用的fanout類型交換機會忽略該值。
直接交換(Direct Exchange)
我們之前的日志系統會將所有消息廣播給所有消費者。現在我們想根據日志的嚴重程度來過濾日志。比如,我們想要一個程序來將error日志寫到磁盤文件中,而不要將warning或info日志寫到磁盤中,以免浪費磁盤空間。
我們之前使用的fanout路由器缺少靈活性,它只是沒頭腦地廣播消息。所以,我們用direct路由器來替換它。direct路由器背后的路由算法很簡單:只有當消息的路由鍵routing key與隊列的綁定鍵binding key完全匹配時,該消息才會進入該隊列。

直接交換機器x與兩個隊列綁定。第一個隊列以綁定鍵orange來綁定,第二個隊列以兩個綁定鍵black和green和交換機綁定。 按照這種設置,路由鍵為orange的消息以發布給交換機后,將會被路由到隊列Q1,路由鍵為black或者green的消息將會路由到隊列Q2。
多重綁定(Multiple bindings)

多個隊列以相同的綁定鍵binding key綁定到同一個Exchange上,是完全可以的。按照這種方式設置的話,直接路由器就會像fanout路由器一樣,將消息廣播給所有符合路由規則的隊列。一個路由鍵為black的消息將會發布到隊列Q1和Q2。
發布消息
我們使用direct來代替fanout,同時我們為日志設置嚴重級別,並將此作為路由鍵。這樣,接受者就可以選擇性的接受日志消息。
首先,聲明一個交換機
channel.exchangeDeclare(EXCHANGE_NAME,“direct”);
然后,發送一個消息
channel.basicPublish(EXCHANGE_NAME,severity,null,message.getBytes());
我們此處只設置一種severity。在info warning error中任選一種。
消息訂閱
String queueName = channel.queueDeclare().getQueue();
for(String severity:argv){
channel.queueBind(queueName,EXCHANGE_NAME,severity);
}
完整代碼如下:
生產者:

消費者:

啟動一個消費者實例(ReceiveLogDirect),將其要監聽的級別改為String[] severity = {"error"},再啟動另一個消費者實例。此時這兩個消費者都開始監聽了,一個監聽所有級別的日志,另一個監聽error日志。然后啟動生產者,將info分別改為warning、error后啟動。
可看到如下輸出:

