? RABBITMQ is a message queue based on AMQ protocol, this paper mainly records the basic content of RABBITMQ and the use of spring-boot-starter-amqp
operation RABBITMQ.
Several important concepts in the 1,RABBITMQ
A) virtual host (Vhost)
? Virtual Host: A virtual host holds a set of switches, queues, and bindings. The role of the virtual host is to control permissions, RABBITMQ default has a virtual host "/". You can use the rabbitmqctl add_vhost
command to add a virtual host, and then use the rabbitmqctl set_permissions
command to set permissions for the specified user under the specified virtual host to achieve the purpose of permission control.
b) message channels (channel)
消息通道: 在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。
c) switch (Exchange)
? Switch: The functionality of Exchange is used for message distribution, which is responsible for receiving messages and forwarding them to the queue with which Exchange does not store messages, and if an exchange does not have a binding on any queue, then when it discards the message that the producer sends over, If Exchange cannot find a queue after the ACK mechanism is enabled, an error is returned. One exchange can be bound to more than one queue.
There are four types of switches:
Routing mode (Direct):
The behavior of the direct type is "match first, then deliver". That is, when the binding is set to a routing_key, the routing_key of the message matches, the switch is delivered to the bound queue. Direct is the default switch type for RABBITMQ.
Wildcard mode (TOPIC):
Similar to the route pattern, but Routing_key supports fuzzy matching and forwards messages by rules (most flexible). The symbol "#" matches one or more words, and the symbol "*" matches no more than a few words.
Publish subscription mode (Fanout):
? forwards the message to all bound queues, ignoring routing_key.
Headers:
? Sets the switch for the header attribute parameter type. Headers is the type of a custom matching rule, ignoring routing_key, compared to direct and topic fixed use of Routing_key. When a queue is bound to a switch, a set of key-value pairs is set, and the message includes a set of key-value pairs (the headers attribute) that are delivered to the corresponding queue when the pair of key-value pairs, or all of them, match.
? Specifies a set of key-value pairs when a queue is bound to exchange, and when a message is sent to RABBITMQ, the headers of the message is taken to match the key-value pairs specified by the Exchange binding. If an exact match is reached, the message is routed to that queue, otherwise it is not routed to that queue. The Headers property is a key-value pair, which can be hashtable, and the value of a key-value pair can be any type.
The following two types of matching rule x-match are available:
x-match = all :表示所有的键值对都匹配才能接受到消息x-match = any :表示只要有键值对匹配就能接受到消息
2, using
spring-boot-starter-amqp
Operation RABBITMQ
First add dependent dependencies:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
application.properties
Configure the RABBITMQ related configuration in:
spring.rabbitmq.host=localhostspring.rabbitmq.port=5672spring.rabbitmq.username=cordspring.rabbitmq.password=123456spring.rabbitmq.publisher-confirms=truespring.rabbitmq.virtual-host=/
Define the RABBITMQ configuration class:
Rabbitmqconfig.java
@Configurationpublic class Rabbitmqconfig {private static final String Topicexchangename = "Topic-exchange"; private static final String Fanoutexchange = "Fanout-exchange"; private static final String Headersexchange = "Headers-exchange"; private static final String queuename = "cord"; The claim queue @Bean public queue queue () {//queue (String name, Boolean durable, Boolean exclusive, Boolean Autodele TE) return new Queue ("cord", false, True, true); }//Declare topic switch @Bean topicexchange topicexchange () {return new Topicexchange (Topicexchangename); }//Bind the queue to the topic switch and specify the routing key @Bean binding topicbinding (Queue queue, Topicexchange Topicexchange) {return Bindingbuilder.bind (queue) to (Topicexchange). with ("org.cord.#"); }//Declare fanout switch @Bean fanoutexchange fanoutexchange () {return new Fanoutexchange (Fanoutexchange); }//Bind the queue to the fanout switch @Bean binding fanoutbinding (Queue queue, Fanoutexchange FanoUtexchange) {return Bindingbuilder.bind (queue). to (Fanoutexchange); }//Declare headers switch @Bean headersexchange headersexchange () {return new Headersexchange (Headersexchange); }//Bind the queue to the headers switch @Bean binding headersbinding (Queue queue, Headersexchange headersexchange) {map& Lt String, object> map = new hashmap<> (); Map.put ("First", "A"); Map.put ("Fourth", "D"); The Whereany represents a partial match, and the Whereall represents all matches//return Bindingbuilder.bind (Queue). to (Headersexchange). Whereall (map). Match (); return Bindingbuilder.bind (Queue). to (Headersexchange). Whereany (map). Match (); }}
Define the producer:
Producer.java
@Componentpublic class Producer { @Autowired private AmqpTemplate template; @Autowired private AmqpAdmin admin; /** * @param routingKey 路由关键字 * @param msg 消息体 */ public void sendDirectMsg(String routingKey, String msg) { template.convertAndSend(routingKey, msg); } /** * @param routingKey 路由关键字 * @param msg 消息体 * @param exchange 交换机 */ public void sendExchangeMsg(String exchange, String routingKey, String msg) { template.convertAndSend(exchange, routingKey, msg); } /** * @param map 消息headers属性 * @param exchange 交换机 * @param msg 消息体 */ public void sendHeadersMsg(String exchange, String msg, Map<String, Object> map) { template.convertAndSend(exchange, null, msg, message -> { message.getMessageProperties().getHeaders().putAll(map); return message; }); }}
Define consumer:
Consumer.class
@Componentpublic class Consumer { @RabbitListener(queues = "cord") //@RabbitListener(queues = "cord", containerFactory="myFactory") public void processMessage(String msg) { System.out.format("Receiving Message: -----[%s]----- \n.", msg); }}
Test Case:
RabbitmqTest.java
@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = CordApplication.class)public class RabbitmqTest { @Autowired private Producer producer; //Direct @Test public void sendDirectMsg() { producer.sendDirectMsg("cord", String.valueOf(System.currentTimeMillis())); } //Topic @Test public void sendtopicMsg() { producer.sendExchangeMsg("topic-exchange","org.cord.test", "hello world"); } //Fanout @Test public void sendFanoutMsg() { producer.sendExchangeMsg("fanout-exchange", "abcdefg", String.valueOf(System.currentTimeMillis())); } //Headers @Test public void sendHeadersMsg() { Map<String, Object> map = new HashMap<>(); map.put("First","A"); producer.sendHeadersMsg("headers-exchange", "hello word", map); }}
https://spring.io/guides/gs/messaging-rabbitmq/
53940754
Https://stackoverflow.com/questions/19240290/how-do-i-implement-headers-exchange-in-rabbitmq-using-java
78410727
Https://www.cnblogs.com/jfl-xx/p/7324285.html
RABBIMQ Foundation and SPRING-BOOT-STARTER-AMQP use