1. RabbitMQ combat skills
1.1. Introduction
Due to the project, we will be dealing with RabbitMQ more, so let’s take a good look at RabbitMQ application skills and try to avoid future pit mining
Summary of 1.2.
RabbitMQ has several important concepts: virtual hosts, switches, queues and bindings
- Virtual host: A virtual host holds a set of switches, queues, and bindings that we can control from the granularity of the virtual host level
- Switch: Exchange forwards messages. It does not store messages. If there is no Queue bound to Exchange, it simply discards the data sent by the producer. Another important concept associated with the switch is the routing key, which determines which queue messages are forwarded to
- Binding: Binds switches to queues. It is a many-to-many relationship, that is, multiple switches can be bound to the same queue, or one switch can be bound to multiple queues
1.3. The switch
Switches have four types of modes: Direct, Topic, Headers, and Fanout
1.3.1. Direct Exchage
The Direct mode uses the default switch of RabbitMQ. It is the simplest mode and is suitable for simple scenarios
As shown in the following figure, in Direct mode, we need to create different queues. By default, the switch uses the Routing key value to determine which queue to forward to
1.3.2. The Topic Exchange
Topic patterns are matched primarily by wildcard characters, which are similar to fuzzy matching, and when matched with routing keys the switch can forward messages to a specific queue
- The routing key is a string consisting of a period (.) (
.
), for examplea.b.c
- (
*
) represents a word for a designated position, (#
) stands for zero or more words, such asa.*.b.#
B can be followed by n words, e.ga.x.b.c.d.e
The difference between Topic mode and Direct mode is that the switch needs to be specified by itself. Routing keys support fuzzy matching, for example:
rabbitTemplate.convertAndSend("topicExchange","a.x.b.d", " hello world!" );Copy the code
1.3.3. Headers Exchage
Headers also matches by rule, but not by routing key. Headers has a custom matching rule that sets the matching key value in the Headers attribute of a message. When one or all of these key pairs match, the message is sent to the corresponding queue
1.3.4. The Fanout Exchange
Fanout is the well-known broadcast mode, which does not require a routing key and sends messages to all queues bound to it, even if routing keys are configured, it is ignored
1.4. Complications
- First of all, in the Direct mode, the case of one producer and one consumer corresponds to one sender and one queue A to receive. There is no doubt that what is sent receives what
- In Direct mode, when a producer sends a message, multiple consumers are opened, i.e., multiple queues are opened. In this case, the message is evenly distributed by multiple consumers without repeated consumption (if ack is normal).
- In Topic mode, a switch is bound to two queues and the routing keys overlap, as shown in the following code
topic.message
Send messages, queuequeueMessage
andqueueMessages
All receive the same message, which means,The Topic pattern can be implemented in a form similar to the broadcast patternAnd even more flexible, whether it can forward messages is determined by routing keys. - Compared with Fanout mode, if we want to group the consumer queue, we need to specify a different routing key; In Fanout mode, different switch and queue bindings need to be specified
@Configuration public class TopicRabbitConfig { final static String message = "topic.message"; final static String messages = "topic.messages"; @Bean public Queue queueMessage() { return new Queue(TopicRabbitConfig.message); } @Bean public Queue queueMessages() { return new Queue(TopicRabbitConfig.messages); } @Bean TopicExchange exchange() { return new TopicExchange("exchange"); } @Bean Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) { return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message"); } @Bean Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) { return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#"); }}Copy the code
1.5. Springboot configuration
Our common configuration is as follows
spring.rabbitmq.addresses=localhost:5672 spring.rabbitmq.username=user spring.rabbitmq.password=123456 Spring. The rabbitmq. Virtual - host = / spring. The rabbitmq. Connection timeout = 1000 # # set up to monitor restrictions: Maximum 10, The default 5 spring. The rabbitmq. Listener. Simple. Concurrency = 5 spring. The rabbitmq. Listener. Simple. Max - concurrency = 10 spring.rabbitmq.publisher-confirms=true spring.rabbitmq.publisher-returns=true spring.rabbitmq.template.mandatory=true spring.rabbitmq.listener.simple.acknowledge-mode=manualCopy the code
The last four configurations need to be explained:
spring.rabbitmq.publisher-confirms
If this parameter is set to true, the MQ broker receives the message after the producer message is sent. Sending an acknowledgement acknowledgement confirms the receipt. If this parameter is not set to true, the message may be lostspring.rabbitmq.publisher-returns
True: if the message cannot reach the MQ Broker, the listener will be used to process the unreachable message. This can occur if the routing key is not configured properly or IF MQ is downspring.rabbitmq.template.mandatory
When the above two are true, this must be true, otherwise the above two will not workspring.rabbitmq.listener.simple.acknowledge-mode
This ismanual
The actual production should be set to manual to ensure that your business is completed. Pay attention to the idempotency of business and can be called repeatedly. The manual confirmation code is shown in the following example
@Component public class RabbitReceiver { @RabbitListener(bindings = @QueueBinding( value = @Queue(value = "queue-1", durable="true"), exchange = @Exchange(value = "exchange-1", durable="true", type= "topic", ignoreDeclarationExceptions = "true"), key = "springboot.*" ) ) @RabbitHandler public void onMessage(Message message, Channel channel) throws Exception { System.err.println("--------------------------------------"); System.err.println(" Payload: "+ message.getpayload ()); Long deliveryTag = (Long)message.getHeaders().get(AmqpHeaders.DELIVERY_TAG); BasicAck (deliveryTag, false); }}Copy the code
1.6. Queue properties
- Queue: indicates the name of a queue
- Durable: The value of true indicates that data in queues is persisted to disks, preventing data loss during mq downtime and restart
- Exclusive: Only one current connection is allowed to access the queue. New connections are not allowed to enter the queue. Otherwise, an error is reported
- AutoDelete: If the value is true, the Connection is automatically deleted. If no Connection is connected to the queue, the Connection is automatically deleted
- argumentsThis parameter is used to add some extra parameters, as shown in the following image
- Such as adding
x-message-ttl
If the value is 5000, the message will expire if it is not processed for more than 5 seconds. x-expires
Setting 120000 means that the queue will be deleted if it is not consumed within 2 minutes;x-max-length
.x-max-length-bytes
Represents the maximum length and number of bytes of data to transmitx-dead-letter-exchange
.x-dead-letter-routing-key
Represents dead letter switches and dead letter routes in queue attributes that need to expire or fail processing. These data will be forwarded to dead letter queues for storage. Create a normal switch and queue bindingx-dead-letter-exchange
The routing key must match the routing key of the dead letter queuex-max-priority
“Indicates the priority. The value ranges from 0 to 255This priority makes sense when messages pile up, the higher the number, the higher the priorityx-queue-mode
As for thelazy
The lazy queue mode stores messages generated by producers directly to disk compared to the default mode. This of course increases THE I/O overhead, but it is suitable for situations where large amounts of messages are piled up. When a large number of messages accumulate and the memory is insufficient, messages are dumped to disks. This process is time-consuming and new messages cannot be received during the process. If you want to convert a normal queue to a lazy queue, you need to delete the original queue and create another lazy queue binding.
- Such as adding
! [](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/10/29/16e15a7f22c92c58~tplv-t2oaga2asx-image.imag e)Copy the code
1.7. Switch Properties
- Exchange: indicates the switch name
- Type: indicates the switch type
- Durable: Persistent, same queue
- AutoDelete: indicates whether to automatically delete the queue
- Internal: If the value is true, the exchange cannot be used by the client to push messages. The exchange is only used for binding between exchanges.
- Arguments: Additional arguments, currently only one
alternate-exchange
, indicates that when the producer sends messages to the switch but cannot route to the queue of the switch, the producer attempts to route to the switch specified by this parameter. If the routing key matches, the producer routes to the switchalternate-exchange
The specified queue, equivalent to forwarding, matches the last parameterinternal
If you do not want the local switch to function as a routing queue, you can set this parameterinternal
If true, all messages are forwarded toalternate-exchange
A specified switch by which to route a specified queue,- The diagram below:
exchange0
Set upalternate-exchange
Switches forexchange1
, the producer sends data toexchange0
The key route fortest1
In theexchange0
If the route cannot be routed, it is forwarded toexchange1
Check whether the route matches and send the route to the queuequeue1
- The diagram below:
! [](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/10/29/16e15a7f4c0a2b45~tplv-t2oaga2asx-image.imag e)Copy the code
1.8. Disks and Memory
In the RabbitMQ admin interface, when clustered, you can see that the Info field in the Nodes may be disc or RAM, indicating disk storage or memory storage. In fact, for clustered deployment we need at least one disk store, which means that metadata such as switches, queues, bindings and users can be persisted to disk. RabbitMQ can be restored to its original state after a single restart. Memory storage also has its advantages, that is, it is more efficient and faster
1.9. Error reporting cases
- When the following error is reported, you must have an exclusive queue, that is, set
exclusive
Attribute, because different channels created for the same connection can access the same queue, the resource is locked because of this exclusive attribute, which is the following error. - So that tells us that if you set the queue to
exclusive
Property, then do not create a new connection to access the same queue
ESOURCE_LOCKED - cannot obtain exclusive access to locked queue xxxxxxCopy the code
Welcome to pay attention to the public number, learning and progress together