Entering RabbitMQ (1)
preface
RabbitMq as the current mainstream MQ(Message Queue) more fire one, many beginners will not use MQ or do some specific business in MQ. This article is good enough to let xiao Bai understand how MQ is used.
The installation
The environment
- SpringBoot 2.3.1. RELEASE
- Rabbit MQ
The installation start
Here I directly use Docker installation is more convenient
docker pull rabbitmq
docker run -d --name rabbit -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 -p 15672:15672 -p 5672:5672 rabbitmq
Copy the code
You need to enter the container once to access the RabbitMQ background
docker exec -it rabbitmq_id /bin/bash
rabbitmq-plugins enable rabbitmq_management
exit
Copy the code
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
</dependency>Or (I'll use the second because I'm too lazy to write @value)<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
Copy the code
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=root
spring.rabbitmq.password=123456
Copy the code
/ * * *@author Kakki
* @version 1.0
* @createThe 2021-06-18 now * /
@Configuration
@AutoConfigureAfter
public class RabbitMqConfig {
@Autowired
private RabbitProperties rabbitProperties;
@Bean
public CachingConnectionFactory cachingConnectionFactory(a) {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost(rabbitProperties.getHost());
connectionFactory.setPort(rabbitProperties.getPort());
connectionFactory.setUsername(rabbitProperties.getUsername());
connectionFactory.setPassword(rabbitProperties.getPassword());
connectionFactory.setAutomaticRecoveryEnabled(true);
connectionFactory.setTopologyRecoveryEnabled(true);
return newCachingConnectionFactory(connectionFactory); }}@AutoConfigureAfter(RabbitMqConfig.class)
@Configuration
public class QueueAutoConfig implements InitializingBean {
@Autowired
private AmqpAdmin amqpAdmin;
@Override
public void afterPropertiesSet(a) throws Exception {
Arrays.stream(QueueInfo.values()).forEach(v->{
Queue queue = new Queue(v.getQueue());
amqpAdmin.declareQueue(queue);
CustomExchange exchange = newCustomExchange(v.getExchange(), v.getExchangeType()); amqpAdmin.declareExchange(exchange); Binding binding = BindingBuilder.bind(queue).to(exchange).with(v.getRoutingKey()).noargs(); amqpAdmin.declareBinding(binding); }); }}@AllArgsConstructor
@Getter
public enum QueueInfo {
FIRST(
"FIRST_QUEUE"."FIRST_EXCHANGE"."FIRST_ROUTING_KEY"."fanout"
);
private final String queue;
private final String exchange;
private final String routingKey;
private final String exchangeType;
}
Copy the code
How do you send and receive messages
Send a message
/** * unit tests */
@Test
public void sendMq(a) {
String s = "Hello Kakki";
rabbitTemplate.convertAndSend(QueueInfo.FIRST.getQueue(), s);
while(true);
}
Copy the code
Receive a message
/ * * *@author Kakki
* @version 1.0
* @createThe 2021-06-18 "* /
@Component
@Slf4j
public class MqCustomer {
@RabbitListener(queues = {"FIRST_QUEUE"})
public void handler(Message message) { // Message can also be received directly using String
log.info("[News comes]:{}".newString(message.getBody(), StandardCharsets.UTF_8)); }}Copy the code
Look at the parameters when you use them
- We’re using the convertAndSend() method, which takes a lot of arguments, and you can see that if our argument is a RoutingKey we can send it directly to the listening queue. Why? The argument above is a routingKey. We’ll talk about that later.
Use different switch types to send messages
/** * unit tests */
@Test
public void sendMq(a) {
rabbitTemplate.convertAndSend(QueueInfo.FANOUT.getExchange(), StringUtils.EMPTY, "No fanout routingKey");
rabbitTemplate.convertAndSend(QueueInfo.FANOUT.getExchange(), QueueInfo.FANOUT.getRoutingKey(), "No fanout routingKey");
rabbitTemplate.convertAndSend(QueueInfo.DIRECT.getExchange(), QueueInfo.DIRECT.getRoutingKey(), "DIRECT routingKey");
rabbitTemplate.convertAndSend(QueueInfo.TOPIC1.getExchange(), QueueInfo.TOPIC1.getRoutingKey(), String.format("TOPIC1 routingKey % s", QueueInfo.TOPIC1.getRoutingKey()));
rabbitTemplate.convertAndSend(QueueInfo.TOPIC2.getExchange(), QueueInfo.TOPIC2.getRoutingKey(), String.format("TOPIC2 routingKey % s", QueueInfo.TOPIC2.getRoutingKey()));
rabbitTemplate.convertAndSend(QueueInfo.TOPIC3.getExchange(), QueueInfo.TOPIC3.getRoutingKey(), String.format("TOPIC3 routingKey % s", QueueInfo.TOPIC3.getRoutingKey()));
rabbitTemplate.convertAndSend(QueueInfo.TOPIC4.getExchange(), QueueInfo.TOPIC4.getRoutingKey(), String.format("TOPIC4 routingKey % s", QueueInfo.TOPIC4.getRoutingKey()));
rabbitTemplate.convertAndSend(QueueInfo.HEADERS.getExchange(), QueueInfo.HEADERS.getRoutingKey(), String.format("HEADERS have routingKey % s", QueueInfo.HEADERS.getRoutingKey()));
while (true);
}
/ * * *@author Kakki
* @version 1.0
* @createThe 2021-06-18 "* /
@Component
@Slf4j
public class MqCustomer {
@RabbitListener(queues = {"FANOUT_QUEUE"})
public void handlerF(Message message) {
log.info("[News comes]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
}
@RabbitListener(queues = {"DIRECT_QUEUE"})
public void handlerD(Message message) {
log.info("[News comes]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
}
@RabbitListener(queues = {"TOPIC_QUEUE"})
public void handlerT(Message message) {
log.info("[News comes]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
}
@RabbitListener(queues = {"HEADERS_QUEUE"})
public void handlerH(Message message) {
log.info("[News comes]:{}".newString(message.getBody(), StandardCharsets.UTF_8)); }}Copy the code
The 16:48:14 2021-06-30. 16460-638 the INFO [ntContainer# 0-1] com. Example. Demo. Config. MqCustomer: [news] : DIRECT routingKey 16:48:14 2021-06-30. 16460-638 the INFO] [ntContainer# 1-1 com. Example. Demo. Config. MqCustomer: [news] : the fanout routingKey 16:48:14 2021-06-30. 16460-638 the INFO] [ntContainer# 3-1 com. Example. Demo. Config. MqCustomer: HEADERS has routingKeyHEADERS_ROUTING_KEY 2021-06-30 16:48:14.638 INFO 16460 -- [ntContainer#2-1] com.example.demo.config.MqCustomer : [message comes]:TOPIC1 has routingKeyTOPIC_ROUTING_KEY.# 2021-06-30 16:48:14.638 INFO 16460 -- [ntContainer#1-1] com.example.demo.config.MqCustomer : [news] : the fanout routingKey 16:48:14. 2021-06-30 638 INFO 16460-2-1] [ntContainer# com. Example. Demo. Config. MqCustomer: [message is coming]:TOPIC2 has routingkeytopic_routing_key.aaab 2021-06-30 16:48:14.639 INFO 16460 -- [ntContainer#2-1] com.example.demo.config.MqCustomer : [message is coming]:TOPIC3 has routingkeytopic_routing_key.aaac.aaak 2021-06-30 16:48:14.639 INFO 16460 -- [ntContainer#2-1] Com. Example. Demo. Config. MqCustomer: [news] : there are routingKeyNO_KEY TOPIC4Copy the code
- Therefore, messages sent to different types of switches may have different effects. How to configure these types of switches or how to select switches depends on the service scenario.
- I have a mistake here, that is, when sending the Fanout switch, the type of fanout switch is not actually used to send, so why does it still arrive? I’ll leave you to think about that. We’ll talk more about that in the next chapter.
summary
In the case of MQ, of course, it is for business decoupling and peak shaving in high concurrency scenarios. There are many unexpected uses for being skilled with MQ. Of course this article is for beginners. Of course not. I would like to write down all I know, but I am afraid it will be too long and people will not like it (in fact, it is lazy), so I will say it in the next content about MQ!