## 回顧
在之前的教程中,我們構建了一個簡單的日志系統 我們能夠將日志消息廣播給許多接收者。
## 本教程
添加一個功能 - 我們將只能訂閱一部分消息。例如,我們只能將重要的錯誤消息導向日志文件(以節省磁盤空間),同時仍然能夠在控制臺上打印所有日志消息。
#### 綁定
前面的例子,我們已經完成了綁定。
`channel.queueBind(queueName,EXCHANGE_NAME,"");`//ReceiveLogs
綁定是交換和隊列之間的關系。這可以簡單地理解為:**隊列對來自這個交換的消息感興趣。**
綁定可以采用額外的routingKey參數。為了避免混淆basic_publish參數,我們將其稱為 綁定鍵。這是我們如何創建一個關鍵的綁定:(綁定鍵的含義取決于交換類型。我們之前使用的 粉絲交換,簡單地忽略了它的價值。)
```
channel.queueBind(queueName,EXCHANGE_NAME,"black");
```
## 直接交換
我們之前教程的日志記錄系統將所有消息廣播給所有消費者。我們希望擴展這個功能,以便根據消息的嚴重性來過濾消息。例如,我們可能需要一個將日志消息寫入磁盤的程序,以僅接收嚴重錯誤,而不會在警告或信息日志消息中浪費磁盤空間。
原來的fanout交換,這并沒有給我們太大的靈活性 - 它只能夠無意識地播放。
我們將使用直接交換。直接交換背后的路由算法很簡單 - 消息進入綁定密鑰與消息的路由密鑰完全匹配的隊列 。
#### 圖解

**第一個隊列用綁定鍵橙色綁定,第二個隊列有兩個綁定,一個綁定鍵為黑色,另一個為綠色。通過路由鍵橙色發布到交換機的消息 將被路由到隊列Q1。帶有黑色 或綠色的路由鍵的消息將進入Q2。所有其他消息將被丟棄。**
## 多個綁定

**綁定多個隊列和綁定鍵是完全合法的。在這種情況下,直接交換就像扇出一樣,將消息
廣播到所有的匹配隊列。路由密鑰為黑色的消息將傳送到 Q1和Q2。**
## 發射日志
我們將把這個模型用于我們的日志系統。我們將消息發送到直接交流。我們將提供日志嚴重性作為路由鍵。

**先創建一個交換**
```
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
```
**準備發送一條消息**
severity為綁定的鍵
```
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
```
### 訂閱
接收郵件的方式與上一個教程中的一樣,除了一個例外 - 我們將為每個我們感興趣的嚴重級別創建一個新的綁定。
```
String queueName = channel.queueDeclare().getQueue();
for(String severity : argv){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
```
## 最后的代碼
**EmitLogDirect.java**
```
public class EmitLogDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String message = "Direct";
String severity = "black";
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
System.out.println(" [x] Sent '" + severity + "':'" + message + "'");
channel.close();
connection.close();
}
}
```
**ReceiveLogsDirect.java**
```
public class ReceiveLogsDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, EXCHANGE_NAME, "black");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws UnsupportedEncodingException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}
````