The producer establishes a TCP connection and multiplexes the TCP connection to establish a channel. The channel is connected to the switch, and the switch binds queues according to different routing keys. Each message is bound to a routing key. After the message reaches the switch, the switch distributes the message according to the routing key and the routing key bound to the queue and sends the message to different queues.

1. The practical advantages of RabbitMQ

Overall, there are three real benefits

  • The application of decoupling

For example, here is a business scenario: If you buy an item online and you pay for it, the stock goes down by one. In a traditional software architecture, you have to pay first and then reduce the stock. The two operations have to be in the same transaction, atomicity. We need to send messages to respective queues for message processing, and there is no correlation between payment and inventory operations, thus decoupling the payment system and inventory system.

  • Traffic peak clipping

RabbitMQ can use buffered queues to reduce the burden of concurrent access when traffic increases rapidly. The most common service scenarios are seckill and check-in systems.

  1. Upstream queue buffering, speed limiting send
  2. Downstream queue buffering, speed limit execution

Of course, the common scenario is to adopt the second way, which does not affect the response speed and use experience of customers.

We know that RabbitMQ messages are sent to the corresponding queue through channels, and that the consumer listens to the queue and has time to process the messages. If a certain number of messages are unacknowledged in the queue, no new messages are consumed

RabbitMQ provides a channel.basicQos method to limit the maximum number of unacknowledged messages that can be held by a consumer on a channel. If autoAck is true, the default message consumer automatically acknowledges the message, which may not have been processed. If autoAck is false, the consumer needs to manually acknowledge the message

Combined with the above, rabbitMQ can be used to speed up the downstream of the service for peak peaking purposes

  • Asynchronous processing

Many business scenarios require issuing an instruction that does not require immediate execution, may have different requirements for when to execute it, or simply execute it, and RabbitMQ objects provide different solutions. The user sends and sends messages stored in RabbitMQ. It can be passed to the consumer by rabbitMQ for consumption, or it can be queued to a dead letter for delayed queuing, allowing messages to be consumed on a regular basis, etc.

RabbitMQ also has many other advantages, such as the ease of setting up a clustered environment, the ability to customize the routing and messaging rules, and the ability to distribute and buffer messages

2. What transport is the message based on, and what are the advantages of doing so?

RabbitMQ uses channels to transfer data, excluding TCP connections, which are expensive to create and destroy and are limited by system resources, resulting in performance bottlenecks.

Consumer links RabbitMQ is a TCP link, and once a link has been created, a Channel is created based on the link. Each thread holds a Channel, which multiplexes TCP links, reducing the cost of creating and destroying links and improving performance

3. How do I ensure that messages are correctly sent to RabbitMQ

The sender may fail to send a message to RabbitMQ. The reasons for the failure are as follows:

  • A switch cannot be matched to a queue based on its type and routing key (MANDATORY)
  • When all queues matching routing keys have no consumers (delayed queues and dead letter queues)

In these cases, RabbitMQ provides sender confirmation to report that a message is correctly sent to the RabbitMQ service

Sender confirmation means that the message producer sets the channel to Confirm mode. Once the channel is in Confirm mode, all messages posted on the channel will be assigned a unique ID and RabbitMQ will send an acknowledgement to the producer once the message is delivered to RabbitMQ Service China.

The extensibility increases as the sender confirms that the pattern is asynchronous and does not affect the producer’s ability to continue sending messages

There is another way around this: if the sender feels that asynchronous validation is becoming too complex for the code, it can be done without mandatory

In addition, the sender confirms that there is a transaction mechanism, which can be set as follows:

  • Channel. txSelect: Sets the current channel to transaction mode
  • Channel. txCommit: Commits the current transaction
  • Channel.txrollback: Transaction rollback is similar to database transactions and does solve the problem of sending messages to RabbitMQ to confirm whether they are sent or not, but transactions are performance-expensive so they are not recommended

4. How do I ensure that message recipients consume messages

The consumer listens to the queue, gets the data stored in the queue from the Channel, and consumes it – the consumer subscribs to the queue. With autoAck false RabbitMQ will wait for an acknowledgement from the consumer before removing the message from memory (or disk).

To ensure that the consumer consumes the message, simply set the autoAck parameter to false, which ensures that RabbitMQ will wait for the message to complete before deleting it. However, this feature creates a new problem. If the consumer fails to process the message without a manual acknowledgement, RabbitMQ will not delete the message from memory or disk, causing it to block in the queue and subsequent messages to become unconsumed.

For these problems, we can use RabbitMQ’s compensation mechanism and dead-letter queue to save messages that fail to consume.

RabbitMQ provides configuration parameters to enable the consumer retry mechanism, as well as the maximum number of retries and retry interval. RabbitMQ will discard a message if it fails to consume a certain number of retries. This can be done manually. The message is persisted to the database or log file by the consumers of the dead-letter queue. We set the retry times to 3 and the interval to 5s.

The realization of the business layer consumers can also manually, if the same message consumption for many times, you can manually refused to the message, and then the message automatically enters the dead-letter queue, so that the dead-letter queue based on the rabbitMQ feature to automatically realize the preservation of the news, advantage is the rabbitMQ encapsulate frame does not need additional code, performance guarantee, The downside is that the job is left to the consumer to implement manually. Specific still have to see the demand of actual business.

5. How to avoid repeated consumption and delivery of messages

During message production, MQ internally generates an inner-msG-ID for each message sent by the producer as a basis for de-duplication and idempotent (message delivery failure and retransmission) to prevent duplicate messages from entering the queue. In message consumption, there must be a bizId (globally unique for the same business, such as payment ID, order ID, post ID, etc.) in the message body as the basis for deduplication and idempotent, so as to avoid repeated consumption of the same message

6. How do I distribute messages? ★★★★★

In my opinion, message distribution and message routing belong to the same problem. The producer sends the message to Exchange, and then Exchange routes the message to one or more queues. If the route fails, the message is sent back to the producer according to the sender confirmation mechanism, or directly discarded. The consumer subscribes to the message on the queue, and this is the entire process through which the message flows

  • Producers link to RabbitMQ, establish a Connection, and start a Channel based on that Connection
  • The producer declares an Exchange and sets the attributes (Exchange type Fanout, Direct, topic and HEADERS, persistent or not)
  • The producer declares a Queue and sets its properties (persistent or not)
  • When a producer sends a message to an Exchange, it typically specifies a RoutingKey that specifies the routing rules for the message, and the RoutingKey needs to be combined with the Exchange type and the BindingKey to take effect
  • The corresponding Exchange searches for the matching queue according to the routing key of the received message. If the message matches, the Exchange sends the message to the queue. If the Exchange fails to find the confirmation mode according to the sender, whether to return the message to the sender or discard it
  • The consumer connects to RabbitMQ, establishes a Connection, and opens a Channel based on that Connection
  • The consumer subscribes to the queue and decides whether to manually acknowledge the message based on whether the autoAck is false
  • The RabbitMQ service receives an acknowledgement message and deletes the message from the queue

7. How to ensure that messages are not lost

There are three cases of message loss:

  • Producers send messages to RabbitMQ that can be lost if there is no corresponding Exchange, or if the Exchange does not match the queue, or if the queue does not have any consumers

For failed messages, we can use the producer acknowledgement mechanism to send the failed message back to the producer, or we can use the backup switch to process the failed message

RabbitMQ sends confirmation messages in three modes: common confirmation, batch confirmation, and asynchronous listening confirmation. Spring integrates RabbitMQ with only asynchronous listening confirmation mode.

[Note] Asynchronous monitoring mode, can realize sending messages while confirming, does not affect the main thread task execution.

  • Messages are lost when the rabbitMQ service restarts, stops, or breaks down

RabbitMQ persistence consists of three parts: Exchange persistence, Queue persistence and Message persistence

To persist messages, we must persist queues, because messages are stored on queues. If the Queue is not persisted, even if messages are persisted, restarting the service will cause Message loss because there is no carrier to store them

Note that RabbitMQ performance can be severely affected by persisting all messages, but the overall throughput of the system can be improved by not persisting messages that are less reliable

Spring integration enables switch, queue, and message persistence by default, so you can ensure that messages are not lost to RabbitMQ without changing any Settings. But just in case.

  • If the consumer sets autoAck to true, it may break down before the consumer has a chance to consume, which is actually a disguised message loss

This requires us to set autoAck to true when consuming the message, and pay attention to solve the consumption exception. For details, please refer to interview question 4

1. What are the benefits of RabbitMQ?

1. Decoupling: System A directly calls the code of system B and system C in the code. If system D is connected in the future, system A also needs to modify the code, which is too troublesome! 2. Asynchronism: Messages are written to message queues. Non-essential service logic is run asynchronously to speed up response 3. Peak clipping, when a large number of concurrent requests are directed to the database, causing database connection exceptions

2. What is a broker in RabbitMQ? What is a cluster?

A broker is a logical grouping of one or more Erlang nodes running RabbitMQ applications. Clusters are built on top of brokers, with additional constraints on sharing metadata between nodes.

3. Are channels, exchanges and queues logical concepts or are they process entities? What do they do?

Queue has its own Erlang process; Lookup tables implemented internally as exchange to hold bindings; A channel is the entity that does the actual routing, which is responsible for Posting messages to the queue according to the Routing_key. According to the description of THE AMQP protocol, a channel is a virtual connection over a real TCP connection. All AMQP commands are sent through a channel, and each channel has a unique ID. A channel can only be used by a single operating system thread, so messages delivered to a particular channel are sequential. However, multiple channels are allowed on a single operating system thread.

4. What is vhost? What does it do?

A vhost is a virtual broker, that is, a mini-RabbitMQ server. They all have their own queue, exchange, binding, etc., but most importantly, they have their own permission system, which can control users in the vhost range. Of course, from RabbitMQ’s global perspective, vhosts can be used as a means of isolating different permissions (a typical example is that different applications can run on different vhosts).

5. What transport is the message based on?

The creation and destruction of TCP connections is expensive and the number of concurrent connections is limited by system resources, resulting in performance bottlenecks. RabbitMQ uses channels to transmit data. A channel is a virtual connection established within a real TCP connection, and there is no limit on the number of channels on each TCP connection.

6. How are messages distributed?

If at least one consumer subscribes to the queue, the message is sent to the consumer in a round-robin fashion. Each message is distributed to only one subscribing consumer (provided the consumer can process the message and confirm it properly).

7. How to route messages?

Conceptually, a message route must have three parts: a switch, a route, and a binding. The producer publishes the message to the exchange; Bindings determine how messages are routed from routers to specific queues; The message eventually reaches the queue and is received by the consumer.

When a message is published to the exchange, it will have a routing key, which is set when the message is created. Queues can be bound to switches through queue routing keys. When the message arrives at the exchange, RabbitMQ matches the routing key of the message with the routing key of the queue (different routing rules apply to different switches). If a queue can be matched, the message is delivered to the corresponding queue. If no queue is matched, the message goes into a “black hole”.

Commonly used switches are divided into the following three types:

  • Direct: If the routing keys match exactly, the message is delivered to the corresponding queue
  • Fanout: If the switch receives a message, it broadcasts it to all bound queues
  • Topic: Enables messages from different sources to reach the same queue. When using topic switches, you can use wildcards. For example, “*” matches any text at a particular location, “. The routing key is divided into several parts, “#” matches all rules, etc. Note that messages sent to the topic exchange cannot be arbitrarily set to a selection key (routing_key) and must consist of a series of identifiers separated by “.”.

8. What is metadata? What are the types of metadata? What does it include? What metadata is associated with clusters? How is metadata stored? How is metadata distributed in a cluster?

In non-cluster mode, Metadata is mainly divided into Queue metadata (Queue name and attributes), Exchange metadata (Exchange name, type and attributes), Binding metadata (lookup table for storing routing relationships), and Vhost metadata (Vhost) Namespace constraints and security property Settings for the first three in scope). In cluster mode, node location information and node relationship information in the cluster are also included. Depending on the type of Erlang node, the metadata is stored only in RAM or on both RAM and disk. Metadata is distributed across nodes in a cluster.

9. What is the difference between declaring a queue, exchange, and binding on a cluster of nodes?

A: When you Declare a queue on a single node, you get queue.declare -ok whenever the metadata on that node changes. Declaring a queue on a cluster requires all nodes in the cluster to update their metadata successfully before queue.Declare-ok. In addition, if the node type is RAM node, the changed data is only stored in the memory. If the node type is Disk node, the changed data is stored on the disk.

Dead letter queue & Dead letter exchange: The full name of DLX is dead-letter Exchange (DEAD-letter Exchange). When a message becomes a dead-letter, if the queue in which the message resides has the x-dead-letter Exchange parameter, It is then sent to the exchange corresponding to the x-dead-letter-exchange value. This exchange is called a dead letter exchange, and the queue bound to this dead letter exchange is a dead letter queue.

10. How do I ensure that messages are sent to RabbitMQ correctly?

RabbitMQ uses sender confirmation mode to ensure that messages are correctly sent to RabbitMQ. Sender confirmation mode: If you set the channel to Confirm mode, all messages posted on the channel will be assigned a unique ID. Once a message has been posted to the destination queue or written to disk (persistable messages), the channel sends an acknowledgement to the producer (containing the unique ID of the message). If RabbitMQ has an internal error that causes the message to be lost, an NACK (not acknowledged) message will be sent. The sender confirmation pattern is asynchronous, and producer applications can continue sending messages while waiting for confirmation. When the acknowledgement message arrives at the producer application, the producer application’s callback method is triggered to process the acknowledgement message.

11. How do I ensure that message recipients consume messages?

Recipient message acknowledgement mechanism: Each message received by the consumer must be acknowledged (message receipt and message acknowledgement are two different operations). RabbitMQ can safely remove a message from the queue only if the consumer confirms it. The timeout mechanism is not used and RabbitMQ only confirms that the Consumer needs to resend the message if the connection is broken. That is, RabbitMQ gives the Consumer enough time to process the message as long as the connection is not broken.

Here are some special cases:

  • If a consumer receives a message and disconnects or unsubscribes before confirming it, RabbitMQ will assume that the message has not been distributed and redistribute it to the next consumer that subscribes. (There may be a hidden problem of repeated message consumption, which needs to be deleted according to bizId)
  • If a consumer receives a message without an acknowledgement and the connection is not broken, RabbitMQ considers the consumer to be busy and will not distribute any more messages to the consumer.

12. How to avoid repeated message delivery or consumption?

During message production, MQ internally generates an inner-msG-ID for each message sent by the producer as a basis for de-duplication and idempotent (message delivery failure and retransmission) to prevent duplicate messages from entering the queue. In message consumption, there must be a bizId (globally unique for the same business, such as payment ID, order ID, post ID, etc.) in the message body as the basis for deduplication and idempotent, so as to avoid repeated consumption of the same message.

This question can be answered in business scenarios as follows:

1. For example, if you get the message and do an INSERT into the database. That would be easy. Give the message a unique primary key, so that even if repeated consumption occurs, primary key collisions will occur, avoiding dirty data in the database.

2. For example, if you get the message and do the redis set operation, it is easy to solve, because the result is the same no matter how many times you set it, the set operation is originally idempotent operation.

3. If all else fails, go big. Have a third-party medium available to keep track of your purchases. In the case of Redis, a message is assigned a global ID, and as long as the message has been consumed, < ID,message> is written to Redis in k-V form. Before the consumer begins to consume, go to Redis to check whether there is any consumption record.

13. How to solve the data loss problem?

1. The producer loses data

What if producer messages are not delivered to MQ? From the point of view of the producer losing data, RabbitMQ provides transaction and confirm modes to ensure that the producer does not lose messages.

The transaction mechanism means that before sending a message, the transaction (channel.txselect ()) is opened, the message is sent, and the transaction is rolled back(channel.txRollback()) if any exception occurs. The transaction is committed if it succeeds (channel.txcommit ()).

The disadvantage, however, is that throughput is reduced. Therefore, according to the experience of bloggers, confirm mode is mostly used in production. Once a channel enters Confirm mode, all messages posted on it will be assigned a unique ID(starting at 1). Once the message has been posted to all matching queues, rabbitMQ will send an Ack to the producer (containing the unique ID of the message). This lets the producer know that the message has arrived on the destination queue correctly. If rabiitMQ fails to process the message, a Nack message will be sent to you and you can retry.

2. Data is lost in the message queue

When the message queue loses data, the configuration of persistent disks is generally enabled. This persistence configuration can be used in conjunction with the Confirm mechanism, where you can send an Ack signal to the producer after the message persists to the disk. This way, if rabbitMQ dies before the message persists to disk, the producer does not receive the Ack signal and will automatically resend it.

So how do you persist, by the way, it’s really easy, just the next two steps

(1) If the durable identifier of queue is set to true, it indicates that the queue is durable

② Set deliveryMode=2 when sending messages

This allows rabbitMQ to hang up and recover data upon restart. Before the message is persisted to the hard disk, the service may die. In this case, you can introduce a mirrored-queue. However, there is no guarantee that the message will not be lost (the whole cluster will hang up).

3. Consumers lose data

Enabling manual confirmation mode solves this problem

① In automatic confirmation mode, the consumer hangs up and the message waiting for ack returns to the queue. The consumer throws an exception, and the message is resent until it is successfully processed. Messages are not lost, and even if the service fails, unprocessed messages are requeued, but exceptions keep messages retried.

(2) Manual confirmation mode, if the consumer has no time to deal with the death, there is no response ACK will repeatedly send a message to other consumers; If the listener handles an exception and does not catch the exception, it keeps receiving the message repeatedly, and then keeps throwing the exception. If an exception is caught but not ack in finally, the message will always be sent repeatedly (retry mechanism).

No acknowledgement mechanism is used, as soon as the message is sent, it will be removed from the queue immediately. No matter the client is abnormal or disconnected, it will be removed as soon as the message is sent, and will not be resent.

14. Use of dead letter queue and delay queue?

Dead letter message:

The message was rejected (basic. Reject or basic. Nack) and the Requeue parameter was set to false. The message expired and the queue reached its maximum length

Expired message:

There are two ways to set the expiration time for rabbitMQ messages, either by setting the queue so that all messages in the queue have the same expiration time, or by setting the message itself so that each message has a different expiration time. If both methods are used, use the value with the lower expiration time. When a message reaches its expiration date and has not been consumed, it becomes a dead-letter message.

** Queue Settings: ** Use the X-message-TTL parameter in milliseconds for queue declarations

** Single message Settings: ** is the value of the expiration parameter for message attributes, in milliseconds

Delay queues: RabbitMQ does not have delay queues, but we can simulate them by setting messages to expire and dead letter queues. The consumer listens to the queue bound to the dead-letter exchange, not to the queue where the message is sent.


With the above basic knowledge, we accomplish the following requirements:

Requirement: the user creates an order in the system, and if the user does not make payment after the time, the order will be automatically cancelled.

Analysis:

3. The expiration message is realized by setting x-message-TTL parameter in the queue; 4. The dead letter queue is realized by setting x-message-TTL parameter in the queue. Set the x-dead-letter-exchange parameter to the queue and declare another queue bound to the x-dead-letter-exchange corresponding exchange.

    ConnectionFactory factory = new ConnectionFactory(); 
    factory.setHost("127.0.0.1"); 
    factory.setPort(AMQP.PROTOCOL.PORT); 
    factory.setUsername("guest"); 
    factory.setPassword("guest"); 
    Connection connection = factory.newConnection(); 
    Channel channel = connection.createChannel();
     
    // Declare a switch and queue to receive deleted messages
    String EXCHANGE_DEAD_NAME = "exchange.dead"; 
    String QUEUE_DEAD_NAME = "queue_dead"; 
    channel.exchangeDeclare(EXCHANGE_DEAD_NAME, BuiltinExchangeType.DIRECT); 
    channel.queueDeclare(QUEUE_DEAD_NAME, false.false.false.null); 
    channel.queueBind(QUEUE_DEAD_NAME, EXCHANGE_DEAD_NAME, "routingkey.dead"); 
     
    String EXCHANGE_NAME = "exchange.fanout"; 
    String QUEUE_NAME = "queue_name"; 
    channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT); 
    Map<String, Object> arguments = new HashMap<String, Object>(); 
    // Set the expiration time uniformly for all messages in the queue
    arguments.put("x-message-ttl".30000); 
    // Set the number of milliseconds after no consumer has accessed the queue to delete the queue
    arguments.put("x-expires".20000); 
    // Set the last N messages in the queue. If the number of messages exceeds N, the previous messages are removed from the queue
    arguments.put("x-max-length".4); 
    // Sets the maximum space for the contents of the queue, beyond which previous messages will be deleted
    arguments.put("x-max-length-bytes".1024); 
    // Push the deleted message to the specified switch. Generally, x-dead-letter-exchange and x-dead-letter-routing-key need to be set at the same time
    arguments.put("x-dead-letter-exchange"."exchange.dead"); 
    // Push the deleted message to the routing key corresponding to the specified switch
    arguments.put("x-dead-letter-routing-key"."routingkey.dead"); 
    // Set the priority of the message. The message with the highest priority is consumed first
    arguments.put("x-max-priority".10); 
    channel.queueDeclare(QUEUE_NAME, false.false.false, arguments); 
    channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ""); 
    String message = "Hello RabbitMQ: "; 
     
    for(int i = 1; i <= 5; i++) { 
    	// expiration: Sets the expiration time of a single message
    	AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties().builder()
    			.priority(i).expiration( i * 1000 + ""); 
    	channel.basicPublish(EXCHANGE_NAME, "", properties.build(), (message + i).getBytes("UTF-8")); 
    } 
    channel.close(); 
    connection.close();
Copy the code

15. What are the disadvantages of using message queues?

1. Reduced system availability: You can imagine that as long as other systems are running well, your system is fine. Now you have to add a message queue, the message queue is down, your system is not ha ha. As a result, system availability decreases

2. Increased system complexity: there are many issues to consider, such as consistency, how to ensure that messages are not re-consumed, and how to ensure that messages are transmitted reliably. As a result, there are more things to consider and system complexity increases.

16. Functions and usage scenarios of message queues

Asynchronous: batch data asynchronous processing (batch file upload) peak clipping: high load task load balancing (e-commerce flash purchase) Decoupling: serial task parallelization (return process decoupling) Broadcast: one-to-many communication based on Pub/Sub

17. How are messages distributed when multiple consumers listen to a queue?

  • Polling: The default policy where consumers take turns and receive messages equally
  • Fair distribution: Distribute messages according to consumers’ ability to send more messages to idle consumers

When a consumer has x messages that do not respond to ACK, no more messages are sent to the consumer

channel.basicQos(int x)
Copy the code

18. Where do messages that cannot be routed go?

If no configuration is required, messages that cannot be routed (with an incorrect Routing key) are discarded. Solution: Set mandatory to true and send the message back with ReturnListener

When declaring a switch, specify the switch to be backed up

 Map<String,Object> arguments = new HashMap<String,Object>();
	arguments.put("alternate-exchange"."Backup Switch Name");
Copy the code

19. When does news become dead faith?

  • The message was rejected and re-enqueued was not set
  • Message expiration
  • Messages pile up and the queue reaches its maximum length, and the first queued messages become the DL

20. How does RabbitMQ implement delayed queuing?

Use TTL (queue message alive time or message alive time), plus dead-letter switch

 // Set the property, the message expires in 10 seconds
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
		.expiration("10000") // TTL

 // Specifies the queued dead letter switch
Map<String,Object> arguments = new HashMap<String,Object>();
arguments.put("x-dead-letter-exchange"."DLX_EXCHANGE");
Copy the code

21. How to ensure the reliable delivery of messages

Sender confirmation mode: If you set the channel to Confirm mode, all messages posted on the channel will be assigned a unique ID. Once a message has been posted to the destination queue or written to disk (persistable messages), the channel sends an acknowledgement to the producer (containing the unique ID of the message). If RabbitMQ has an internal error that causes the message to be lost, an NACK (not acknowledged) message will be sent. The sender confirmation pattern is asynchronous, and producer applications can continue sending messages while waiting for confirmation. When the acknowledgement message arrives at the producer application, the producer application’s callback method is triggered to process the acknowledgement message.

Recipient acknowledgement mechanism Recipient message acknowledgement mechanism: Each message received by a consumer must be acknowledged (message receipt and message acknowledgement are two different operations). RabbitMQ can safely remove a message from the queue only if the consumer confirms it. The timeout mechanism is not used and RabbitMQ only confirms that the Consumer needs to resend the message if the connection is broken. That is, RabbitMQ gives the Consumer enough time to process the message as long as the connection is not broken. Ensure final consistency of data; The special cases are listed below: If a consumer receives a message and disconnects or unsubscribes before confirmation, RabbitMQ will assume that the message has not been distributed and redistribute it to the next consumer that subscribes. If a consumer receives a message without confirmation and the connection is not broken, RabbitMQ considers the consumer to be busy and will not send more messages to the consumer.

22. Message idempotency

Producer side: You can generate an msgID for each message to control message duplication

 AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
	porperties.messageId(String.valueOF(UUID.randomUUID()))
Copy the code

On the consumer side: the message body must carry a business ID, such as a bank serial number, according to which consumers can de-weight to avoid repeated consumption

23. How are messages prioritized for consumption

/ / producer
 Map<String, Object> argss = new HashMap<String, Object>();
        argss.put("x-max-priority".10);

/ / consumer
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                .priority(5) // The priority, which defaults to 5, is used with the x-max-priority attribute of the queue
Copy the code

24. How to ensure the order of messages

The order can only be guaranteed if there is only one consumer in a queue, otherwise it can only be achieved with a global ID (each message has an msgId, and associated messages have a parentMsgId). You can realize that the previous message is not consumed and the next message is not processed at the consumer end. You can also implement on the production side that the next message is not published until the previous message is processed.)

25. Cluster mode and cluster node type for RabbitMQ

** Common mode: ** The default mode is two nodes (rabbit01, rabbit02). For a Queue, the message entity exists on only one node, Rabbit01 (or rabbit02). Rabbit01 and Rabbit02 have the same metadata, namely the Queue structure. When A message enters the Rabbit01 Queue and the consumer consumes it from Rabbit02, RabbitMQ will temporarily transfer the message between Rabbit01 and Rabbit02, fetching the message from A and sending it to the consumer through B. So the consumer should try to connect to each node and fetch messages from it. That is, physical queues are created on multiple nodes for the same logical Queue. Otherwise, both consumer and rabbit02 will always exit to Rabbit01, causing a bottleneck. When Rabbit01 fails, Rabbit02 cannot fetch unconsumed message entities from Rabbit01. If message persistence is made, it will wait until Rabbit01 is restored before it can be consumed. Without message persistence, message loss occurs.

** Mirror mode: * * need to queue queue to make image, existence and multiple nodes to RabibitMQ HA scheme, the model to solve the problems in normal mode, its essence and normal mode difference, experience the initiative in mirror synchronization between nodes, rather than on the client side you get your data and temporary pull side effects resulting from the model are obviously, In addition to reducing system performance, if the number of mirrored queues is too large and a large number of messages enter, the network bandwidth of the cluster will be greatly consumed by the synchronous communication. Therefore, it is suitable for scenarios requiring high reliability

The nodes are divided into memory nodes (which store state to memory, but persist queues and messages to disk) and disk nodes (which store state to memory and disk). At least one disk node is required in a cluster

26. How to automatically delete messages that have not been consumed for a long time

// Set the message expiration time through the queue attribute
        Map<String, Object> argss = new HashMap<String, Object>();
        argss.put("x-message-ttl".6000);

 // Set expiration time for each message
        AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                .expiration("10000") // TTL
Copy the code

27. What transport is the message based on

RabbitMQ uses channels to transmit data. A channel is a virtual connection established within a real TCP connection, and there is no limit on the number of channels on each TCP connection

28. How do I ensure that messages are not lost

Message persistence RabbitMQ ensures that persistent messages can be recovered from a server restart by writing them to a persistent log file on disk. When a persistent message is posted to the persistent exchange, Rabbit does not send a response until the message is committed to the log file. Once a consumer consumes a persistent message from the persistent queue, RabbitMQ marks it in the persistence log as waiting for garbage collection. If RabbitMQ restarts persistent messages before they are consumed, Rabbit automatically reconstructs the exchange and queues (and bindings) and republishes the messages from the persistence log file to the appropriate queues.

A subscription model

In the subscription model, there are four roles:

  • P: The producer, that is, the program that sends the message, but instead of sending it to the queue, it sends it to X (the switch)
  • C: The consumer, the recipient of the news, will wait for the news to come.
  • Queue: Message Queue, receiving and caching messages.
  • Exchange: the X in the figure. On the one hand, receive messages sent by producers. On the other hand, know how to process messages, such as delivering them to a particular queue, delivering them to all queues, or throwing them away. Exactly how to do this depends on the type of Exchange. There are three common types of Exchange:
    • Fanout: Broadcast messages to all queues bound to the switch
    • Direct: directs the message to the queue matching the specified routing key
    • Topic: a wildcard that sends a message to a queue that matches the routing pattern

Exchange (a switch) only forwards messages and does not store them, so if there are no queues bound to Exchange, or no queues that conform to routing rules, messages can be lost!

Routing Features:

  • The binding of the queue to the switch cannot be arbitrary, but must be specifiedRoutingKey(Route Key)
  • The sender of a message must also specify the message when sending a message to ExchangeRoutingKey.
  • Exchange no longer delivers messages to each bound queue, but to each bound queueRoutingKeyTo make a judgment, only queueRoutingkeyWith the message ofRouting keyThe message is received only when it is exactly the same

Topics wildcard pattern:

Topic types, in contrast to Direct, can route messages to different queues based on a RoutingKey. Except that the Topic Exchange type can make queues use wildcards when binding routingKeys!

A Routingkey is typically made up of one or more words, with “between” words. Split, for example, item.insert

Wildcard rules:

# : Matches one or more words

* : matches exactly 1 word

Topic mode can realize Publish/Subscribe mode and Routing mode function; However, wildcard characters can be used in routing key configuration for Topic, which is more flexible.

Producers:

// Create a connection
Connection connection = ConnectionUtil.getConnection();

// Create channel
Channel channel = connection.createChannel();

Parameter 1: switch name parameter 2: switch type, fanout, topic, topic, headers */
channel.exchangeDeclare(TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);


// Send a message
String message = "New goods. Topic mode; Routing key is item.insert" ;
channel.basicPublish(TOPIC_EXCHAGE, "item.insert".null, message.getBytes());
System.out.println("Message sent:" + message);

// Send a message
message = "Modified the product. Topic mode; Routing keys for the item. The update" ;
channel.basicPublish(TOPIC_EXCHAGE, "item.update".null, message.getBytes());
System.out.println("Message sent:" + message);

// Send a message
message = "Deleted the item. Topic mode; Routing keys for the item. Delete" ;
channel.basicPublish(TOPIC_EXCHAGE, "item.delete".null, message.getBytes());
System.out.println("Message sent:" + message);

// Close the resource
channel.close();
connection.close();
Copy the code

Consumer:

Connection connection = ConnectionUtil.getConnection();

// Create channel
Channel channel = connection.createChannel();

// Declare a switch
channel.exchangeDeclare(Producer.TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);

// Declare (create) a queue
/** * Parameter 1: queue name * Parameter 2: Define persistent queue * Parameter 3: exclusive connection * Parameter 4: automatically delete queue when not in use * parameter 5: other queue parameters */
channel.queueDeclare(Producer.TOPIC_QUEUE_1, true.false.false.null);

// The queue binds the switch
channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, "item.update");
channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, "item.delete");

// Create a consumer; And set up message handling
DefaultConsumer consumer = new DefaultConsumer(channel){
@Override
/** * consumerTag specifies the contents of the envelope message packet while channel.basicConsume, from which the message ID, message routingKey, and switch are obtained. Message and retransmission flags (whether a message needs to be resent if it fails to be received) * Properties property information * Body message */
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
/ / routing key
System.out.println("The route key is:" + envelope.getRoutingKey());
/ / switches
System.out.println("Switch is:" + envelope.getExchange());
/ / message id
System.out.println("Message ID is:" + envelope.getDeliveryTag());
// Received message
System.out.println("Consumer 1- received the message:" + new String(body, "utf-8")); }};// Listen for messages
/** * Parameter 1: queue name * Parameter 2: automatic acknowledgement. If this parameter is set to true, the message is automatically sent to MQ and will be deleted when the message is received. If this parameter is set to false, manual confirmation is required
channel.basicConsume(Producer.TOPIC_QUEUE_1, true, consumer);

Copy the code