java 使用RabbitMQ实现延迟信息(main方法实现)

1. 引入jar包


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

2.发送端

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 消息生产者 
 */
public class MyDelayProducer {
    /*

    生产者输出消息到Queue1,并且这个消息是设置有有效时间的,比如60s。
    消息会在Queue1中等待60s,如果没有消费者收掉的话,它就是被转发到Queue2,
    Queue2有消费者,收到,处理延迟任务。

    具体实现步骤如下:

    第一步, 首先需要创建2个队列。Queue1和Queue2。
    Queue1是一个消息缓冲队列,在这个队列里面实现消息的过期转发,
    设置 Dead letter exchange ,当消息在这个队列中expire后,使用设置的路由发送。
    Dead letter exchange 的exchange需要事先创建好,就是一个普通的exchange。
    由于我们还需要向Queue1发送消息,那么还需要创建一个exchange,
    并且和Queue1绑定。

    */
    public static void main(String[] args) throws IOException, TimeoutException {

        ConnectionFactory cf = new ConnectionFactory();
        Connection conn = cf.newConnection();
        Channel channel = conn.createChannel();
        
        // 创建 exchange和queue
        // 创建两个路由,
        //一个向缓冲队列 queue_delay_begin 发送信息,信息过期时转到第二个路由,再发送给执行队列 queue_delay_done
        channel.exchangeDeclare("exchange_delay_begin", "direct"/*路由类型*/, true/*是否持久化*/); //向Queue1发消息的路由
        channel.exchangeDeclare("exchange_delay_done", "direct", true); //向Queue2发消息的路由
         
        Map<String, Object> param = new HashMap<String, Object>();
            //消息过期时转发到路由 exchange_delay_done
        param.put("x-dead-letter-exchange", "exchange_delay_done"); 
            // 创建缓冲队列 queue_delay_begin
        channel.queueDeclare("queue_delay_begin", true/*是否持久化*/, 
                                false/*是否排他*/, false/*是否自动删除*/, param); 
            //创建任务执行队列Queue2
        channel.queueDeclare("queue_delay_done", true, false, false, null); 
        
        //将队列与路由进行绑定
        channel.queueBind("queue_delay_begin", "exchange_delay_begin", "delay"/*路由关键字*/);
        channel.queueBind("queue_delay_done", "exchange_delay_done", "delay"); 
        
        // 延迟发送
        AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
        builder.expiration("3000");//设置消息TTL(消息生存时间)
        builder.deliveryMode(2);//设置消息持久化
        AMQP.BasicProperties properties = builder.build();
         
        String message = "延迟信息:"+LocalDateTime.now();
        channel.basicPublish("exchange_delay_begin","delay",properties,message.getBytes());
        
        channel.close();
        conn.close();
    }

}
/*
 队列按照顺序出去,如果第二个已经到期,但第一个不到期,第二个也不会出去,
     当第一个到期出去是,第二个马上出去
 
 */

2.接收端

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException;

/**
 * 消费者 
 */
public class MyDelayConsumer {
    
    public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {

        ConnectionFactory cf = new ConnectionFactory();
        Connection conn = cf.newConnection();
        Channel channel = conn.createChannel();
        
        
        //创建消费者,并接受消息
        Consumer consumer = new DefaultConsumer(channel) {
            
              @Override
              public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
                      throws IOException {
                  String msg = new String(body, "UTF-8");
              System.out.println("接收消息:"+ LocalDateTime.now());
              System.out.println(msg);
              System.out.println("路由:"+envelope.getExchange());
              System.out.println("routingKey: "+ envelope.getRoutingKey());
              long deliveryTag = envelope.getDeliveryTag();
              System.out.println("deliveryTag: "+deliveryTag);
              }
      };
      channel.basicConsume("queue_delay_done", true, consumer);


    }

}

猜你喜欢

转载自blog.csdn.net/liyongbing1122/article/details/81065238
今日推荐