java operation rabbitmq consumer example

    rabbitmq, as a message queue, is very common in practical applications. Producers send messages to a queue...

    rabbitmq, as a message queue, is very common in practical applications. Producers send messages to a queue, and consumers consume the queue.

      The message is in the queue. To consume, consumers need to listen to the queue. In short, it is to register a method to the message channel, which will be executed when there is a message.

      The following is a code example to operate rabbitmq through java.

      Here are three consumer example methods

      1. The simplest registration.

            Set callback directly through channel.basicConsume().

      2. Simulate a queue consumer and start the thread.

              Customize a consumer and start the consumer as a thread.

        The above only requires AMQP client dependency  

<dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.4.3</version> </dependency>

      3. Using spring boot's support for amqp, customize the MessageListener and bind it to the Container.

              This is the most common practice of customizing listeners and setting message processing methods. Inject the listener into the message listening container, and finally start the container.

      The spring boot starter AMQP dependency needs to be added here.

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> <version>2.1.4.RELEASE</version> </dependency>

    Here are the three consumer example codes described above:

      1. This method is primitive and easy to understand.

package com.xxx.huali.hualitest.amqp; import java.io.IOException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Consumer; import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.Envelope; import com.rabbitmq.client.AMQP.BasicProperties; public class SimpleConsumer { private static final String host = "192.168.226.100"; private static final String username = "huali"; private static final String password = "huali"; private static final String queue_name1 = "activate"; private static final String exchange_name = "core.down.topic"; public static void main(String[] args) { Connection conn = null; Channel channel = null; try { ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setUsername(username); factory.setPassword(password); factory.setVirtualHost("/mec"); //connection conn = factory.newConnection(); //channel channel = conn.createChannel(); //queue channel.queueDeclare(queue_name1, true, false, false, null); //exchange channel.exchangeDeclare(exchange_name, "topic",true); channel.queueBind(queue_name1, exchange_name, "TOPIC.*.*.*.*"); Consumer callback = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,byte[] body) throws IOException { System.out.println("received message -> "+new String(body)); } }; channel.basicConsume(queue_name1, true, callback); } catch (Exception e) { e.printStackTrace(); } } }

      2. Based on the first method, this method adds threads, starts threads and sets listening, which is a bit like the third method.

package com.xxx.huali.hualitest.amqp; import java.io.IOException; import com.rabbitmq.client.AMQP.BasicProperties; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Consumer; import com.rabbitmq.client.Envelope; import com.rabbitmq.client.ShutdownSignalException; public class QueueConsumer implements Consumer,Runnable{ private static final String host = "192.168.226.100"; private static final String username = "huali"; private static final String password = "huali"; private static final String queue_name1 = "activate"; private static final String exchange_name = "core.down.topic"; Connection conn = null; Channel channel = null; public QueueConsumer(){ try { ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setUsername(username); factory.setPassword(password); factory.setVirtualHost("/mec"); //connection conn = factory.newConnection(); //channel channel = conn.createChannel(); //queue channel.queueDeclare(queue_name1, true, false, false, null); //exchange channel.exchangeDeclare(exchange_name, "topic",true); channel.queueBind(queue_name1, exchange_name, "TOPIC.*.*.*.*"); } catch (Exception e) { e.printStackTrace(); } } public void close() throws IOException{ try { channel.close(); } catch (Exception e) { e.printStackTrace(); } this.conn.close(); } @Override public void run() { try { channel.basicConsume(queue_name1, true, this); } catch (IOException e) { e.printStackTrace(); } } @Override public void handleConsumeOk(String consumerTag) {} @Override public void handleCancelOk(String consumerTag) {} @Override public void handleCancel(String consumerTag) throws IOException {} @Override public void handleDelivery(String consumerTag, Envelope env, BasicProperties props, byte[] body) throws IOException { System.out.println("client received msg -> "+new String(body)); } @Override public void handleShutdownSignal(String consumerTag, ShutdownSignalException sig) {} @Override public void handleRecoverOk(String consumerTag) {} }

    Start main function:

package com.xxx.huali.hualitest.amqp; public class ConsumerMain { public static void main(String[] args) { QueueConsumer consumer = new QueueConsumer(); Thread thread = new Thread(consumer); thread.start(); } }

      3. The third method needs the support of spring AMQP. It is the most common in actual development. In springboot, the ConnectionFactory is directly configured, and the code is not required. We only need to configure a message listener.

package com.xxx.springbootamqp.test; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageListener; public class MyMessageListener implements MessageListener{ @Override public void onMessage(Message message) { System.out.println("received message -> "+new String(message.getBody())); } }

Start main function:

package com.xxx.springbootamqp.test; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; public class ConsumerMain { private static final String host = "192.168.226.100"; private static final String username = "huali"; private static final String password = "huali"; private static final String queue_name1 = "activate"; public static void main(String[] args) { try { CachingConnectionFactory factory = new CachingConnectionFactory(); factory.setHost(host); factory.setUsername(username); factory.setPassword(password); factory.setVirtualHost("/mec"); SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(factory); container.setMessageListener(new MyMessageListener()); container.setQueueNames(queue_name1); container.start(); } catch (Exception e) { e.printStackTrace(); } } }

    Strictly speaking, this code is not complete. It does not declare the queue, switch, and the binding relationship between queue and switch, because once the consumer binds the relationship between switch and queue, it does not need to be set repeatedly. This relationship is formed in rabbitmq. As long as it is not deleted manually, it will not be changed. Because this is the third example, the previous two examples have set up and bound queues and switches.

    You need to start the container here, which is similar to the second method of starting threads. In fact, it also uses the thread pool, which is an enhanced version of the second method. Moreover, consumers are encapsulated into BlockingQueueConsumer, which is more in line with the semantics of queue consumers.

    It should be noted that the queue used here is bound to the switch, and the switch type is the subject switch. The message producer only needs to send the message to the routing key corresponding to the switch. That is, routingKey.   

channel.basicPublish(exchange_name, "TOPIC.4.128.1.a1OHmhQSyrxMEC_1", null, message.getBytes());

    In the code   TOPIC.4.128.1.a1OHmhQSyrxMEC_1 is routingKey.

      Consumers bind the subject switch and queue themselves. One consumer can apply for one queue and two consumers can apply for two queues. In this way, messages are routed to multiple consumers without interference.

//queue channel.queueDeclare(queue_name1, true, false, false, null); //exchange channel.exchangeDeclare(exchange_name, "topic",true); channel.queueBind(queue_name1, exchange_name, "TOPIC.*.*.*.*");

    Finally, a simple producer code example is attached:

package com.xxx.huali.hualitest.amqp; import java.io.IOException; import java.util.Date; import java.util.concurrent.TimeoutException; import com.alibaba.fastjson.JSONObject; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class Publisher { private static final String host = "192.168.226.100"; private static final String username = "huali"; private static final String password = "huali"; private static final String exchange_name = "core.down.topic"; public static void main(String[] args) { Connection conn = null; Channel channel = null; try { ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setUsername(username); factory.setPassword(password); factory.setVirtualHost("/mec"); //connection conn = factory.newConnection(); //channel channel = conn.createChannel(); //exchange channel.exchangeDeclare(exchange_name, "topic",true); JSONObject object = new JSONObject(); String device_id = "a1OHmhQSyrxMEC_1"; object.put("device_id", device_id); object.put("opt_type", 128); JSONObject data = new JSONObject(); data.put("auzcode_devname", device_id); data.put("regist_result", 1); long time_stamp = new Date().getTime(); object.put("data", data); object.put("time_stamp", time_stamp); String message = object.toJSONString(); //for(int i=0;i<5;i++) { // System.out.println("i="+i); channel.basicPublish(exchange_name, "TOPIC.4.128.1.a1OHmhQSyrxMEC_1", null, message.getBytes()); //} System.out.println("done"); } catch (Exception e) { e.printStackTrace(); }finally { try { channel.close(); conn.close(); } catch (IOException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); } } } }

    The producer code is very simple. The key sentence is the message sending code of channel.basicPublish(). It only cares about which topic and route it is sent to, not the queue.

12 October 2021, 16:59 | Views: 4772

Add new comment

For adding a comment, please log in
or create account

0 comments