在發布和訂閱模式中,我們構建了乙個簡單的日誌系統。我們能夠向多個接收者廣播日誌訊息。
在路由模式,我們將向其新增乙個特性—我們將只訂閱所有訊息中的一部分。例如,我們只接收關鍵錯誤訊息並儲存到日誌檔案(以節省磁碟空間),同時仍然能夠在控制台上列印所有日誌訊息。
在發布和訂閱模式中,我們已經建立了佇列與交換機的繫結。使用下面這樣的**:
ch.queuebind(queuename, "logs", "");
繫結是交換機和佇列之間的關係。這可以簡單地理解為:佇列對來自此交換的訊息感興趣。
繫結可以使用額外的routingkey引數。為了避免與basic_publish引數混淆,我們將其稱為bindingkey。這是我們如何建立乙個鍵繫結:
ch.queuebind(queuename, exchange_name, "black");
bindingkey的含義取決於交換機型別。我們前面使用的fanout交換機完全忽略它。
上一節中的日誌系統向所有消費者廣播所有訊息。我們希望擴充套件它,允許根據訊息的嚴重性過濾訊息。例如,我們希望將日誌訊息寫入磁碟的程式只接收關鍵error,而不是在warning或info日誌訊息上浪費磁碟空間。
前面我們使用的是fanout交換機,這並沒有給我們太多的靈活性——它只能進行簡單的廣播。
我們將用直連交換機(direct exchange)代替。它背後的路由演算法很簡單——訊息傳遞到bindingkey與routingkey完全匹配的佇列。為了說明這一點,請考慮以下設定
其中我們可以看到直連交換機x
,它繫結了兩個佇列。第乙個佇列用繫結鍵orange
繫結,第二個佇列有兩個繫結,乙個繫結black
,另乙個繫結鍵green
。
這樣設定,使用路由鍵orange
發布到交換器的訊息將被路由到佇列q1。帶有black
或green
路由鍵的訊息將轉到q2
。而所有其他訊息都將被丟棄。
使用相同的bindingkey繫結多個佇列是完全允許的。如圖所示,可以使用binding key black將x與q1和q2繫結。在這種情況下,直連交換機的行為類似於fanout,並將訊息廣播給所有匹配的佇列。一條路由鍵為black的訊息將同時傳送到q1和q2。
我們將在日誌系統中使用這個模型。我們把訊息傳送到乙個direct交換機,而不是fanout。我們將提供日誌級別作為routingkey。這樣,接收程式將能夠選擇它希望接收的級別。讓我們首先來看發出日誌。
和前面一樣,我們首先需要建立乙個exchange:
//引數1: 交換機名
//引數2: 交換機型別
ch.exchangedeclare("direct_logs", builtinexchangetype.direct);
接著來看傳送訊息的**
//引數1: 交換機名
//引數2: routingkey, 路由鍵,這裡我們用日誌級別,如"error","info","warning"
//引數3: 其他配置屬性
//引數4: 發布的訊息資料
ch.basicpublish("direct_logs", "error", null, message.getbytes());
接收訊息的工作原理與前面章節一樣,但有乙個例外——我們將為感興趣的每個日誌級別建立乙個新的繫結, 示例**如下:
ch.queuebind(queuename, "logs", "info");
ch.queuebind(queuename, "logs", "warning");
package rabbitmq.routing;
import j**a.util.random;
import j**a.util.scanner;
import com.rabbitmq.client.builtinexchangetype;
import com.rabbitmq.client.channel;
import com.rabbitmq.client.connection;
import com.rabbitmq.client.connectionfactory;
public class test1 ;
connectionfactory f = new connectionfactory();
f.sethost("192.168.64.140");
f.setport(5672);
f.setusername("admin");
f.setpassword("admin");
connection c = f.newconnection();
channel ch = c.createchannel();
//引數1: 交換機名
//引數2: 交換機型別
ch.exchangedeclare("direct_logs", builtinexchangetype.direct);
while (true)
//隨機產生日誌級別
string level = a[new random().nextint(a.length)];
//引數1: 交換機名
//引數2: routingkey, 路由鍵,這裡我們用日誌級別,如"error","info","warning"
//引數3: 其他配置屬性
//引數4: 發布的訊息資料
ch.basicpublish("direct_logs", level, null, msg.getbytes());
system.out.println("訊息已傳送: "+level+" - "+msg);
}c.close();
}}
package rabbitmq.routing;
import j**a.io.ioexception;
import j**a.util.scanner;
import com.rabbitmq.client.builtinexchangetype;
import com.rabbitmq.client.cancelcallback;
import com.rabbitmq.client.channel;
import com.rabbitmq.client.connection;
import com.rabbitmq.client.connectionfactory;
import com.rabbitmq.client.delivercallback;
import com.rabbitmq.client.delivery;
public class test2
system.out.println("等待接收資料");
//收到訊息後用來處理訊息的**物件
delivercallback callback = new delivercallback()
};//消費者取消時的**物件
cancelcallback cancel = new cancelcallback()
};ch.basicconsume(queuename, true, callback, cancel);
}}
單一職責原則(設計模式六中)
定義 不要存在多於乙個導致類變更的原因。通俗的說,即乙個類只負責一項職責。問題由來 類t負責兩個不同的職責 職責p1,職責p2。當由於職責p1需求發生改變而需要修改類t時,有可能會導致原本執行正常的職責p2功能發生故障。解決方案 遵循單一職責原則。分別建立兩個類t1 t2,使t1完成職責p1功能,t...
六 中斷機制
中斷通常分為同步中斷和非同步中斷 同步中斷 是當指令執行時由cpu控制單元產生,之所以稱之為同步,是因為只有在一條指令終止執行後cpu才會發出中斷 非同步中斷 是由其它硬體裝置依照cpu時鐘訊號隨機產生。通常把同步中斷稱之為異常,把非同步中斷稱之為中斷 非同步中斷可能為以下兩種 可遮蔽中斷 i o裝...
RabbitMQ工作模式
rabbitmq工作模式有六種 工作佇列模式,發布訂閱模式,路由模式,萬用字元模式,header模式和rpc模式。1.工作佇列模式 2.發布訂閱模式 交換機型別為funout。3.路由模式 交換機型別為direct。路由模式和發布訂閱模式區別 1 發布訂閱模式不需要繫結routingkey,訊息傳送...