In the previous articles, we introduced how to publish a simple message through rabbitmq, then go to the work queue, multiple consumers consume, and finally go to the work queue distribution and message response mechanism (ACK);
The modes we shared before are all deleted from the queue after being consumed. Ideally, they will not be consumed repeatedly. Imagine another scenario, such as the novel business I did before. After successful login, the user needs to synchronize the gold coins of the temporary account and the book information of the bookshelf to the official account.
If we are integrated with login, after successful login, if the user account or bookshelf synchronization fails, it will certainly affect our entire login experience. In order to make the user imperceptible and do not need to do more operations, we use message queue to synchronize asynchronously.
Publish subscribe mode
This is the flow chart of data synchronization for a user, and it is also the flow chart of rabbitmq publish subscribe. You may notice how there is one more in the middleSwitch。
Note that in the publish subscribe mode, the switch must be bound to the queue. If it is not bound, the message will not be sent to any queue, let alone consumed.
Switch type
There are four types of switches: direct, topic, headers and fanout. This time we mainly talk about fanout, because this is the switch type we need to use this time.
Fanout, as the name suggests, is the broadcast mode. It pushes messages to all queues that subscribe to it.
code
producer
public class Send {
/**
*Switch name
*/
private final static String EXCHANGE_NAME = "test_exchange_fanout";
public static void main(String[] args) throws IOException, TimeoutException {
//Get a connection
Connection connection = MQConnectUtil.getConnection();
//Create channel
Channel channel = connection.createChannel();
//Declare switch fanout: distribution mode, splitting
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
//Message content
String MSG = "I am a successful login message";
//Send message
channel.basicPublish(EXCHANGE_NAME, "", null, msg.getBytes());
System.out.println (message sent successfully: + MSG);
channel.close();
connection.close();
}
}
Consumer synchronous account
public class Consumer1 {
/**
*Switch name
*/
private final static String EXCHANGE_NAME = "test_exchange_fanout";
private final static String QUEUE_NAME = "test_topic_publish_account";
public static void main(String[] args) throws IOException, TimeoutException {
//Get a connection
Connection connection = MQConnectUtil.getConnection();
//Create channel
Channel channel = connection.createChannel();
//Claim queue
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//Bind queue to switch
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
//Ensure that only one message is received at a time, and ensure that rabbitmq sends messages to idle consumers every time
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@SneakyThrows
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body, StandardCharsets.UTF_8);
System.out.println (synchronous account [1]: + MSG);
Thread.sleep(1000);
//Manual response
channel.basicAck(envelope.getDeliveryTag(), false);
}
};
//Listening queue
channel.basicConsume(QUEUE_NAME, false, consumer);
}
}
Consumer synchronous bookshelf
public class Consumer2 {
/**
*Switch name
*/
private final static String EXCHANGE_NAME = "test_exchange_fanout";
private final static String QUEUE_NAME = "test_topic_publish_book_case";
public static void main(String[] args) throws IOException, TimeoutException {
//Get a connection
Connection connection = MQConnectUtil.getConnection();
//Create channel
Channel channel = connection.createChannel();
//Claim queue
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//Bind queue to switch
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
//Ensure that only one message is received at a time, and ensure that rabbitmq sends messages to idle consumers every time
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@SneakyThrows
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body, StandardCharsets.UTF_8);
System.out.println (synchronous bookshelf [2]: + MSG);
Thread.sleep(1000);
//Manual response
channel.basicAck(envelope.getDeliveryTag(), false);
}
};
//Listening queue
channel.basicConsume(QUEUE_NAME, false, consumer);
}
}
summary
So based on the need to synchronize user data, in order to ensure that the data synchronization does not affect each other and reduce the coupling, we can use multiple queues to synchronize user data. Improve the high availability of the whole system.
The day arch one death, the merit does not Tang donate
Please pay attention to more content