Process of building rabbitmq message middleware with Java

Time:2021-5-12

This article mainly introduces the process of building rabbitmq message middleware in Java, and introduces it in great detail through the example code, which has a certain reference learning value for everyone’s study or work. Friends who need it can refer to it

preface

When the speed or stability of “production” and “consumption” are inconsistent in the system, message queuing is needed.

noun

  • Exchange: Exchange
  • Routingkey: routing key
  • Queue: queue

Console port: 15672

Exchange and queue need to be bound together, and then the message is sent to exchange, which then sends it to the corresponding queue through routingkey.

Usage scenarios

1. Skill order will be automatically cancelled in 3 minutes and the status will be changed

2. 15 minutes before live broadcast

3. Live state ends automatically

technological process

Producer sends message – > order_ pre_ Exchange switch – > order_ per_ ttl_ delay_ Queue

– > time expired – > order_ delay_ Exchange switch – > order_ delay_ process_ Queue > consumer

Step 1: add in the POM file


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

Step 2: add in the application. Properties file


spring.rabbitmq.host=172.xx.xx.xxx
spring.rabbitmq.port=5672
spring.rabbitmq.username=rabbit
spring.rabbitmq.password=123456
spring.rabbitmq.virtual-host=/
spring.rabbitmq.connection-timeout=15000

spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.template.mandatory=true

Step 3: configure orderqueueconfig

package com.tuohang.platform.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 *Queue setting of rabbitmq (messages sent by producers always enter exchange first, and then forward to queue through routing)
 * 
 * 
 * @author Administrator
 * @version 1.0
 *@ date 18 September 2018
 */
@Configuration
public class OrderQueueConfig {

  /**
   *Order buffer switch name
   */
  public final static String ORDER_PRE_EXCHANGE_NAME = "order_pre_exchange";

  /**
   *The message sent to the queue will expire and enter the order after a period of time_ delay_ process_ Queue [all messages in the queue have a unified expiration time]
   */
  public final static String ORDER_PRE_TTL_DELAY_QUEUE_NAME = "order_pre_ttl_delay_queue";

  /**
   *Switch Dlx name of the order
   */
  final static String ORDER_DELAY_EXCHANGE_NAME = "order_delay_exchange";

  /**
   *The queue entered after the order message time expired is the actual consumption queue of the order
   */
  public final static String ORDER_DELAY_PROCESS_QUEUE_NAME = "order_delay_process_queue";

  /**
   *Order expiration time in buffer queue (MS) 30 minutes
   */
  public final static int ORDER_QUEUE_EXPIRATION = 1800000;

  /**
   *Order buffer switch
   * 
   * @return
   */
  @Bean
  public DirectExchange preOrderExange() {
    return new DirectExchange(ORDER_PRE_EXCHANGE_NAME);
  }

  /**
   *Create order_ per_ ttl_ delay_ Queue, the order message through the buffer switch, will enter the queue
   * 
   * @return
   */
  @Bean
  public Queue delayQueuePerOrderTTLQueue() {
    return QueueBuilder.durable(ORDER_PRE_TTL_DELAY_QUEUE_NAME)
        .withArgument("x-dead-letter-exchange", ORDER_DELAY_EXCHANGE_NAME) // DLX
        .withArgument("x-dead-letter-routing-key", ORDER_ DELAY_ PROCESS_ QUEUE_ Name) // routing key carried by dead letter
        .withArgument("x-message-ttl", ORDER_ QUEUE_ Expiration) // set the expiration time of the order queue
        .build();
  }

  /**
   *Order_ pre_ Exchange bound to order_ pre_ ttl_ delay_ Queue
   *
   * @param delayQueuePerOrderTTLQueue
   * @param preOrderExange
   * @return
   */
  @Bean
  public Binding queueOrderTTLBinding(Queue delayQueuePerOrderTTLQueue, DirectExchange preOrderExange) {
    return BindingBuilder.bind(delayQueuePerOrderTTLQueue).to(preOrderExange).with(ORDER_PRE_TTL_DELAY_QUEUE_NAME);
  }

  /**
   *Dlx exchange to create an order
   *
   * @return
   */
  @Bean
  public DirectExchange delayOrderExchange() {
    return new DirectExchange(ORDER_DELAY_EXCHANGE_NAME);
  }

  /**
   *Create order_ delay_ process_ Queue queue is the actual consumption queue of orders
   *
   * @return
   */
  @Bean
  public Queue delayProcessOrderQueue() {
    return QueueBuilder.durable(ORDER_DELAY_PROCESS_QUEUE_NAME).build();
  }

  /**
   *Bind Dlx to the actual consumption queue
   *
   * @param delayProcessOrderQueue
   * @param delayExchange
   * @return
   */
  @Bean
  public Binding dlxOrderBinding(Queue delayProcessOrderQueue, DirectExchange delayOrderExchange) {
    return BindingBuilder.bind(delayProcessOrderQueue).to(delayOrderExchange).with(ORDER_DELAY_PROCESS_QUEUE_NAME);
  }

  /**
   *Listen to the actual consumer queue order_ delay_ process_ queue
   * 
   * @param connectionFactory
   * @param processReceiver
   * @return
   */
  @Bean
  public SimpleMessageListenerContainer orderProcessContainer(ConnectionFactory connectionFactory,
      OrderProcessReceiver processReceiver) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setQueueNames(ORDER_ DELAY_ PROCESS_ QUEUE_ NAME); //  Monitor order_ delay_ process_ queue
    container.setMessageListener(new MessageListenerAdapter(processReceiver));
    return container;
  }
}

Consumer orderprocessreceiver:

package com.tuohang.platform.config;

import java.util.Objects;

import org.apache.tools.ant.types.resources.selectors.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;

/**
 *Order delay consumer
 * 
 * 
 * @author Administrator
 * @version 1.0
 *@ date 18 September 2018
 */
@Component
public class OrderProcessReceiver implements ChannelAwareMessageListener {

  private static Logger logger = LoggerFactory.getLogger(OrderProcessReceiver.class);

  String msg = "The failed message will auto retry after a certain delay";

  @Override
  public void onMessage(Message message, Channel channel) throws Exception {
    try {
      processMessage(message);
    } catch (Exception e) {
      //If an exception occurs, the message is redirected to the buffer queue and automatically redone after a certain delay
      channel.basicPublish(OrderQueueConfig.ORDER_PRE_EXCHANGE_NAME, OrderQueueConfig.ORDER_PRE_TTL_DELAY_QUEUE_NAME, null,
          msg.getBytes());
    }
  }
  
  /**
   *Process the order message. If the order is not paid, cancel the order (if the message content is fail)_ If message, you need to throw an exception.)
   *
   * @param message
   * @throws Exception
   */
  public void processMessage(Message message) throws Exception {
    String realMessage = new String(message.getBody());
    logger.info("Received <" + realMessage + ">");
    //Cancel order
    if(!Objects.equals(realMessage, msg)) {
//      SpringKit.getBean(ITestService.class).resetSexById(Long.valueOf(realMessage));
      System. Out. Println ("test 111111 ------" + new date());
      System.out.println(message);
    }
  }
}

perhaps

/**
 *Testing rabbit consumers
 * 
 * 
 * @author Administrator
 * @version 1.0
 *@ date September 25, 2018
 */
@Component
@RabbitListener(queues = TestQueueConfig.TEST_DELAY_PROCESS_QUEUE_NAME)
public class TestProcessReceiver {

  private static Logger logger = LoggerFactory.getLogger(TestProcessReceiver.class);

  String msg = "The failed message will auto retry after a certain delay";

  @RabbitHandler
  public void onMessage(Message message, Channel channel) throws Exception {
    try {
      processMessage(message);
      //Tell the server that this message has been consumed by me and can be deleted in the queue; Otherwise, the message server thinks that this message has not been processed and will be sent later
      channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    } catch (Exception e) {
      //If an exception occurs, the message is redirected to the buffer queue and automatically redone after a certain delay
      channel.basicPublish(TestQueueConfig.TEST_PRE_EXCHANGE_NAME, TestQueueConfig.TEST_PRE_TTL_DELAY_QUEUE_NAME, null,
          msg.getBytes());
    }
  }
  
  /**
   *Process the order message. If the order is not paid, cancel the order (if the message content is fail)_ If message, you need to throw an exception.)
   *
   * @param message
   * @throws Exception
   */
  public void processMessage(Message message) throws Exception {
    String realMessage = new String(message.getBody());
    logger.info("Received < " + realMessage + " >");
    //Cancel order
    if(!Objects.equals(realMessage, msg)) {
      System. Out. Println ("test 111111 ------" + new date());
    }else {
      System.out.println("rabbit else...");
    }
  }
}

producer

/**
   *Test rabbitmq
   * 
   * @return
   */
  @RequestMapping(value = "/testrab")
  public String testraa() {
    GenericResult gr = null;
    try {
      String name = "test_pre_ttl_delay_queue";
  long expiration = 10000;// 10s expiration time
      rabbitTemplate.convertAndSend(name,String.valueOf(123456));
 //Set expiration time on a single message
 //rabbitTemplate.convertAndSend(name,(Object)String.valueOf(123456), new ExpirationMessagePostProcessor(expiration));


    } catch (ServiceException e) {
      e.printStackTrace();
      gr = new GenericResult(StateCode.ERROR, languageMap.get("network_error"), e.getMessage());
    }
    
    return getWrite(gr);
  }

The above is the whole content of this article, I hope to help you learn, and I hope you can support developer more.

Recommended Today

Fscan: an open source tool with one click automation and omni-directional vulnerability scanning

brief introduction Fscan is a comprehensive intranet scanning tool, which is convenient for one click automation and all-round vulnerability scanning. It supports host survival detection, port scanning, blasting of common services, ms17010, redis batch writing public key, planning task rebound shell, reading win network card information, web fingerprint identification, web vulnerability scanning, NetBIOS detection, domain […]