RabbitMQ基礎課二:Java 使用

創建連接

  1. Java 客戶端使用 com.rabbitmq.client 作爲頂級包名,關鍵的類和接口,有 Channel,Connection,ConnectionFactory 和 Consumer 等;

  2. 建立連接和創建信道,注意 Channel 是非線程安全的,並且避免調用其 isOpen 方法;

	ConnectionFactory factory = new ConnectionFactory(); 
	factory.setUsername(USERNAME); 
	factory.setPassword(PASSWORD); 
	factory.setVirtualHost(virtualHost) ; 
	factory.setHost(IP ADDRESS); 
	factory.setPort(PORT) ; 
	
	Connection conn = factory.newConnection();
	Channel channel = conn.createChannel();
	
	// 也可以使用url來設置連接信息
	factory.setUri( "amqp://userName:password@ipAddress:portNumber/virtualHost"); 

創建交換器和隊列

  1. 創建交換器和隊列,生產者和消費者都可以創建,如果嘗試創建一個已經存在的交換器或隊列,只要聲明的參數是完全匹配現存的,那麼 RabbitMQ 會成功返回,如果參數不匹配,則會拋出異常;

  2. 如果消費者在某個信道上已經訂閱了某個隊列,是無法在創建新隊列的;

	// 聲明一個交換器,參數有名稱,類型,是否持久化,是否自動刪除,是否內置,其他參數
	Exchange.DeclareOk exchangeDeclare(String exchange, String type, boolean durable, boolean autoDelete, 
		boolean internal, Map<String, Object> arguments) throws IOException ;
	
	// 用於檢測交換器是否存在,存在正常返回,不存在拋出異常
	exchangeDeclarePassive(String name)
 	
 	// 交換器的刪除,ifUnused設置爲true,表示該交換器沒有被使用纔會被刪除,設置爲false,就是無論是否使用,都刪除
 	exchangeDelete(String exchange , boo1ean ifUnused)
 	
 	// 創建一個隊列,參數,隊列名,是否持久化,是否排他,是否自動刪除,其他參數
 	queueDeclare (String queue ,boolean durable ,boolean exclusive ,boolean autoDelete ,
 		Map<String Object> arguments)
 	
 	// 刪除隊列,參數,沒有被使用,爲空
 	queueDe1ete(String queue ,boo1ean ifUnused ,boolean ifEmpty)
 	
 	// 清空隊列內容
 	queuepurge(String queue)
  1. 隊列和交換器之間,交換器和交換器之間,建立綁定關係和解綁;
	Queue.BindOk queueBind(String queue ,String exchange ,String routingKey ,Map<String, Object> arguments)
	Queue.UnbindOk queueUnbind (String queue, String exchange, String routingKey, Map<String, Object> arguments)
	exchangeBind(String destination, String source, String routingKey, Map<String, Object> arguments)
  1. 注意交換器並不佔很多性能,而隊列比較佔資源,通常可以生產者和消費者都嘗試創建隊列,或者通過頁面管理等工具提前創建,第二種方式能更好預估隊列容量,避免代碼造成隊列和交換器創建失敗,或者綁定失敗的情況;

發送消息

  1. 生產者發送消息,命令 basicPublish,
	// 參數:交換器名,路由鍵,mandatory,是配置消息無法路由時,是否返回生產者
	// props 指消息的基本屬性集,包含14個屬性成員,
	// 有 contentType,contentEncoding, headers, deliveryMode, priority 等,body 指發送消息體
	void basicPublish(String exchange ,String routingKey, boolean mandatory, BasicProperties props, byte[] 
		body);
  1. 參數 mandatory,immediate 參考,https://blog.csdn.net/qq_28128035/article/details/104410213;

消費消息

  1. 消費者消費消息,有推 push 和拉 pull 兩種方式,push 是通過命令 Basic.consume,持續訂閱消費,pull 是通過命令Basic.pull,單次拉取消息;

  2. 注意 push 模式,會將信道 Channel 置爲接收模式,一旦隊列中有消息,就會不斷地推送,推送速度會受到 Basic.Qos 的限制,建議一個 Channel 對應一個消費者,對應一個線程;

	// 設置消費者接收消息個數限制
	channel.basicQos(64);
	
	// push模式,autoAck 建議設置爲 false,表示由應用手動 channel.basicAck 來確認
	// cosumerTag 用於區分消費者,建議不同訂閱採用不同值
	String basicConsume(String queue , boolean autoAck, String consumerTag, Consumer callback) 
	
	// callback 代表接收到消息後的操作,通常繼承 DefaultConsumer,重寫其 handleDelivery 方法
	new DefaultConsumer(channel) { 
		@Override 
		public void handleDelivery(String consumerTag, Envelope envelope , AMQP.BasicProperties properties,
			byte[] 	body) throws IOException {
				String routingKey = envelope . getRoutingKey( ); 
				String contentType = properties.getContentType() ; 
				long deliveryTag = envelope.getDeliveryTag() ; 
				// false是指 ??
				channel.basicAck(deliveryTag, false ); 
		}} 
	
	// pull模式,
	GetResponse basicGet(String queue , boolean autoAck) throws IOException;
  1. 隊列中的消息分發,是按照輪詢的方式,發送給訂閱的消費者,每個消費者可以通過 channel.basicQos(int num) ,控制自己接收的消息個數,一旦有超過設置數量的消息未確認,隊列就不會將消息發送給該消費者,直到其未確認消息數,小於設置值;

  2. channel.basicQos(int num) 還可以設置一個參數 global,值爲 true 或 false, true 表示 num 是對該信道上,所有消費者未確認消息的總和限制,false 表示是對該信道上,每一個新消費者的限制,默認值是 false,並且該參數對於 pull 模式,是無效的,推薦使用 false;

關閉連接

  1. connection 和 channel,都需要在使用完成後,進行關閉,釋放資源,命令 channel.close(),conn.close(),還有相關的監視器,如 ShutdownListener;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章