RabbitMQ working mode with pictures and texts

1, Simple mode 1. Simple mode The first mock ...
1, Simple mode

1. Simple mode

The first mock exam is a one to one mode, one producer, one consumer, and the producer sends messages to consumers.

Producer: the program that sends the message

Consumer: the receiver of the message, who will always wait for the message to arrive

Message queue: similar to a mailbox, it can cache messages; The producer delivers the message to it, and the consumer takes the message out of it

2. Example code:

//producer public class Producer { public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("118.31.55.110"); connectionFactory.setPort(5672); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); connectionFactory.setVirtualHost("/"); Connection connecte = connectionFactory.newConnection(); Channel channel = connecte.createChannel(); channel.queueDeclare("queue", false, false, false, null); String message = "Jaosn Hello World!"; channel.basicPublish("","queue",null,message.getBytes()); channel.close(); connecte.close(); System.out.println("=====Message sent successfully======"); } } //consumer public class Consumer { public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("118.31.55.110"); connectionFactory.setPort(5672); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); connectionFactory.setVirtualHost("/"); Connection connecte = connectionFactory.newConnection(); Channel channel = connecte.createChannel(); channel.queueDeclare("queue", false, false, false, null); //Get data from mq server channel.basicConsume("queue",false,new Reciver(channel)); } } class Reciver extends DefaultConsumer { private Channel channel; //Rewrite the constructor. The Channel object needs to be passed in from the outer layer and used in handleDelivery public Reciver(Channel channel) { super(channel); this.channel = channel; } @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body); System.out.println("Message received by consumer:"+message); System.out.println("Message TagId: "+envelope.getDeliveryTag()); //false only confirms to sign in the current message. When set to true, it means to sign in all unsigned messages of the consumer channel.basicAck(envelope.getDeliveryTag(), false); } }
2, Work queue mode

1. Work queue mode

In one to many mode, a producer, multiple consumers and a queue, each consumer obtains a unique message from the queue. Compared with the simple mode of the entry program, there are one or more consumers, and multiple consumers consume messages in the same queue together.

  • If there are multiple consumers in a queue, the relationship between consumers for the same message is a competitive relationship
  • Work mode for the case of heavy tasks or more tasks, using work queue can improve the speed of task processing. For example, if multiple SMS services are deployed, only one node needs to be sent successfully.

2. Code:

//Order system public class OrderSystem { public static void main(String[] args) throws IOException, TimeoutException { Connection connection = RabbitUtils.getConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SMS, false, false, false, null); for(int i = 1 ; i <= 100 ; i++) { SMS sms = new SMS("passenger" + i, "13900000" + i, "Your ticket has been booked successfully"); String jsonSMS = new Gson().toJson(sms); channel.basicPublish("" , RabbitConstant.QUEUE_SMS , null , jsonSMS.getBytes()); } System.out.println("Sending data succeeded"); channel.close(); connection.close(); } } //SMS service 1 public class SMSSender1 { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SMS, false, false, false, null); //If basicQos (1) is not written, MQ automatically sends all requests to all consumers on average //basicQos,MQ no longer sends multiple requests to consumers at one time, but after the consumer processes a message (after confirmation), it obtains a new request from the queue channel.basicQos(1);//Take one after processing channel.basicConsume(RabbitConstant.QUEUE_SMS , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String jsonSMS = new String(body); System.out.println("SMSSender1-SMS sent successfully:" + jsonSMS); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } channel.basicAck(envelope.getDeliveryTag() , false); } }); } } //SMS service 2 public class SMSSender2 { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SMS, false, false, false, null); //If basicQos (1) is not written, MQ automatically sends all requests to all consumers on average //basicQos,MQ no longer sends multiple requests to consumers at one time, but after the consumer processes a message (after confirmation), it obtains a new request from the queue channel.basicQos(1);//Take one after processing channel.basicConsume(RabbitConstant.QUEUE_SMS , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String jsonSMS = new String(body); System.out.println("SMSSender2-SMS sent successfully:" + jsonSMS); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } channel.basicAck(envelope.getDeliveryTag() , false); } }); } } //SMS service 3 public class SMSSender3 { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SMS, false, false, false, null); //If basicQos (1) is not written, MQ automatically sends all requests to all consumers on average //basicQos,MQ no longer sends multiple requests to consumers at one time, but after the consumer processes a message (after confirmation), it obtains a new request from the queue channel.basicQos(1);//Take one after processing channel.basicConsume(RabbitConstant.QUEUE_SMS , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String jsonSMS = new String(body); System.out.println("SMSSender3-SMS sent successfully:" + jsonSMS); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } channel.basicAck(envelope.getDeliveryTag() , false); } }); } }

3, Publish subscribe mode

1. Schematic diagram:

2. Publish subscribe mode

In the subscription model, an Exchange role is added, and the process changes slightly:

The producer, that is, the program that sends the message, but it is no longer sent to the queue, but to X (switch)

The consumer, the receiver of the message, will always wait for the message to arrive

Message queue, receiving messages and caching messages

On the one hand, the switch receives messages sent by producers. On the other hand, you know how to process messages, such as delivering to a special queue, delivering to all queues, or discarding messages. How to operate depends on the type of Exchange. There are three common types of Exchange:

  • Fanout: broadcast and deliver messages to all queues bound to the switch
  • Direct: direct, which sends messages to queues that match the specified routing key
  • Topic: wildcard, which gives the message to the queue conforming to the routing pattern

Switch: it is only responsible for forwarding messages and does not have the ability to store messages. Therefore, if there is no queue bound to Exchange or no queue that meets the routing rules, the messages will be lost!

3. Example:

(1) Figure

(2) Create queue

(3) Create switch

(4) The queue is bound to the switch

(5) Code:

//Publisher public class WeatherBureau { public static void main(String[] args) throws Exception { Connection connection = RabbitUtils.getConnection(); String input = new Scanner(System.in).next(); Channel channel = connection.createChannel(); //The first parameter is the switch name, and other parameters are the same as before channel.basicPublish(RabbitConstant.EXCHANGE_WEATHER,"" , null , input.getBytes()); channel.close(); connection.close(); } } //subscriber public class Sina { public static void main(String[] args) throws IOException { //Get TCP long connection Connection connection = RabbitUtils.getConnection(); //Get virtual connection final Channel channel = connection.createChannel(); //Declare queue information channel.queueDeclare(RabbitConstant.QUEUE_SINA, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key (temporarily unavailable) channel.queueBind(RabbitConstant.QUEUE_SINA, RabbitConstant.EXCHANGE_WEATHER, ""); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_SINA , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Weather information received by Sina weather:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } } public class BiaDu { public static void main(String[] args) throws IOException { //Get TCP long connection Connection connection = RabbitUtils.getConnection(); //Get virtual connection final Channel channel = connection.createChannel(); //Declare queue information channel.queueDeclare(RabbitConstant.QUEUE_BAIDU, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key (temporarily unavailable) channel.queueBind(RabbitConstant.QUEUE_BAIDU, RabbitConstant.EXCHANGE_WEATHER, ""); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_BAIDU , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Weather information received by Baidu weather:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); }

(6) Summary:

a. The switch needs to bind to the queue. After binding, a message can be received by multiple consumers.

b. Differences between publish subscribe mode and work queue mode:

  • Work queue mode does not need to define switches, while publish / subscribe mode needs to define switches
  • The producer of publish / subscribe mode sends messages to the switch, and the producer of work queue mode sends messages to the queue (the default switch is used at the bottom)
  • The publish / subscribe mode needs to set the binding between the queue and the switch. The work queue mode does not need to be set. In fact, the work queue mode will bind the queue to the default switch

4, Routing mode

1. Routing mode:

  • The binding between the queue and the switch cannot be arbitrary, but a routing key should be specified
  • When sending a message to Exchange, the sender of the message must also specify the RoutingKey of the message
  • Exchange will no longer deliver messages to each bound queue, but will judge according to the routing key of the message. Messages will be received only if the routing key of the queue is completely consistent with the routing key of the message

2. Figure:

Illustration:

  • Producer: sends a message to the switch. When sending a message, a routing key will be specified
  • Switch: receive the producer's message, and then submit the message to the queue that exactly matches the routing key
  • Consumer 1: its queue specifies the messages whose routing key needs to be info and error
  • Consumer 2: its queue specifies the messages whose routing key needs to be error and warning

3. Example diagram:

4. Code:

//Publisher public class WeatherBureau { public static void main(String[] args) throws Exception { Map area = new LinkedHashMap<String, String>(); area.put("china.hunan.changsha.20201127", "Weather data of Changsha, Hunan, China 20201127"); area.put("china.hubei.wuhan.20201127", "Weather data of Wuhan, Hubei, China 20201127"); area.put("china.hunan.zhuzhou.20201127", "Weather data of Zhuzhou, Hunan, China 20201128"); area.put("us.cal.lsj.20201127", "Weather data of Los Angeles, California 20201127"); area.put("china.hebei.shijiazhuang.20201128", "China Hebei Shijiazhuang 20201128 weather data"); area.put("china.hubei.wuhan.20201128", "Weather data of Wuhan, Hubei, China 20201128"); area.put("china.henan.zhengzhou.20201128", "Weather data of Zhengzhou, Henan, China 20201128"); area.put("us.cal.lsj.20201128", "Weather data of Los Angeles, California 20201128"); Connection connection = RabbitUtils.getConnection(); Channel channel = connection.createChannel(); Iterator<Map.Entry<String, String>> itr = area.entrySet().iterator(); while (itr.hasNext()) { Map.Entry<String, String> me = itr.next(); //The first parameter is the switch name, and the second parameter is the routing key of the message channel.basicPublish(RabbitConstant.EXCHANGE_WEATHER_ROUTING,me.getKey() , null , me.getValue().getBytes()); } channel.close(); connection.close(); } } //consumer public class Sina { public static void main(String[] args) throws IOException { //Get TCP long connection Connection connection = RabbitUtils.getConnection(); //Get virtual connection final Channel channel = connection.createChannel(); //Declare queue information channel.queueDeclare(RabbitConstant.QUEUE_SINA, false, false, false, null); //Specify the relationship between the queue and the switch and the routing key channel.queueBind(RabbitConstant.QUEUE_SINA, RabbitConstant.EXCHANGE_WEATHER_ROUTING, "us.cal.lsj.20201127"); channel.queueBind(RabbitConstant.QUEUE_SINA, RabbitConstant.EXCHANGE_WEATHER_ROUTING, "china.hubei.wuhan.20201127"); channel.queueBind(RabbitConstant.QUEUE_SINA, RabbitConstant.EXCHANGE_WEATHER_ROUTING, "us.cal.lsj.20201128"); channel.queueBind(RabbitConstant.QUEUE_SINA, RabbitConstant.EXCHANGE_WEATHER_ROUTING, "china.henan.zhengzhou.20201012"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_SINA , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Weather information received by Sina weather:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } } public class BiaDu { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_BAIDU, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key channel.queueBind(RabbitConstant.QUEUE_BAIDU, RabbitConstant.EXCHANGE_WEATHER_ROUTING, "china.hunan.changsha.20201127"); channel.queueBind(RabbitConstant.QUEUE_BAIDU, RabbitConstant.EXCHANGE_WEATHER_ROUTING, "china.hebei.shijiazhuang.20201128"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_BAIDU , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Weather information received by Baidu weather:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }

5. Summary

The Routing mode requires the queue to specify the routing key when binding the switch, and the message will be forwarded to the queue matching the routing key.

5, Wildcard pattern

1. Wildcard pattern

  • Compared with Direct, Topic can route messages to different queues according to RoutingKey. However, Topic Exchange allows the queue to use wildcards when Binding routing keys!
  • Routingkey s are generally composed of one or more words, which are separated by ".", such as item.insert
  • Wildcard rule: # match one or more words, * match exactly one word, for example: item. # can match item.insert.abc or item.insert, and item. * can only match item.insert

2. Example code:

//Publisher public class WeatherBureau { public static void main(String[] args) throws Exception { Map area = new LinkedHashMap<String, String>(); area.put("china.hunan.changsha.20201127", "Weather data of Changsha, Hunan, China 20201127"); area.put("china.hubei.wuhan.20201127", "Weather data of Wuhan, Hubei, China 20201127"); area.put("china.hunan.zhuzhou.20201127", "Weather data of Zhuzhou, Hunan, China 20201127"); area.put("us.cal.lsj.20201127", "Weather data of Los Angeles, California 20201127"); area.put("china.hebei.shijiazhuang.20201128", "China Hebei Shijiazhuang 20201128 weather data"); area.put("china.hubei.wuhan.20201128", "Weather data of Wuhan, Hubei, China 20201128"); area.put("china.henan.zhengzhou.20201128", "Weather data of Zhengzhou, Henan, China 20201128"); area.put("us.cal.lsj.20201128", "Weather data of Los Angeles, California 20201128"); Connection connection = RabbitUtils.getConnection(); Channel channel = connection.createChannel(); Iterator<Map.Entry<String, String>> itr = area.entrySet().iterator(); while (itr.hasNext()) { Map.Entry<String, String> me = itr.next(); //The first parameter is the switch name, and the second parameter is the routing key of the message channel.basicPublish(RabbitConstant.EXCHANGE_WEATHER_TOPIC,me.getKey() , null , me.getValue().getBytes()); } channel.close(); connection.close(); } } //consumer public class Sina { public static void main(String[] args) throws IOException { //Get TCP long connection Connection connection = RabbitUtils.getConnection(); //Get virtual connection final Channel channel = connection.createChannel(); //Declare queue information channel.queueDeclare(RabbitConstant.QUEUE_SINA, false, false, false, null); //Specify the relationship between the queue and the switch and the routing key channel.queueBind(RabbitConstant.QUEUE_SINA, RabbitConstant.EXCHANGE_WEATHER_TOPIC, "us.#"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_SINA , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Weather information received by Sina weather:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } } public class BiaDu { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_BAIDU, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key channel.queueBind(RabbitConstant.QUEUE_BAIDU, RabbitConstant.EXCHANGE_WEATHER_TOPIC, "*.*.*.20201127"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_BAIDU , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Weather information received by Baidu weather:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }

15 September 2021, 15:48 | Views: 5726

Add new comment

For adding a comment, please log in
or create account

0 comments