Rabbitmq publish subscribe mode to synchronize user data

Time:2021-1-13

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

Rabbitmq publish subscribe mode to synchronize user data

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

Rabbitmq publish subscribe mode to synchronize user data