用rabbitmq的延时队列来实现,直接上代码
接收者实现:
public class RevDemo {
static Logger log = LoggerFactory.getLogger(RevDemo.class);
public static void revDelay(String queueName) throws Exception {
log.info("消费者revDelay[{}]开始启动", queueName);
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SendDemo.ip);
factory.setPassword(SendDemo.password);
factory.setUsername(SendDemo.username);
Connection connection;
Channel channel = null;
QueueingConsumer consumer = null;
try {
connection = factory.newConnection();
channel = connection.createChannel();
channel.queueDeclare(queueName, true, false, false, null);
// 死信队列
String delay_q_name = queueName + "_delay";
HashMap<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-dead-letter-exchange", "amq.direct");
arguments.put("x-dead-letter-routing-key", "message_ttl_routingKey");
channel.queueDeclare(delay_q_name, true, false, false, arguments);
// 声明死信处理队列
channel.queueDeclare(queueName, true, false, false, null);
// 绑定路由
channel.queueBind(queueName, "amq.direct", "message_ttl_routingKey");
consumer = new QueueingConsumer(channel);
// 打开消息应答机制
channel.basicConsume(queueName, false, consumer);
} catch (Exception e) {
throw new RuntimeException(e);
}
while (true) {
try {
Thread.sleep(50);
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
if (StringUtils.isBlank(message)) {
continue;
}
log.info(" [{}] Received [{}]", queueName, message);
// 如果没有确认收到,消息队列不会被删除,下个消费者会继续收到此消息,此消费者实例不会收到此消息
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
String queueName = SendDemo.qName;
// rev(queueName);
revDelay(queueName);
}
}
发送者实现:
public class SendDemo {
static Logger log = LoggerFactory.getLogger(SendDemo.class);
public static void sendDelay(String queueName, String msg) throws Exception {
log.info("向queueName=[{}],msg=[{}]", queueName, msg);
ConnectionFactory factory = new ConnectionFactory();
factory.setHost( ip);
factory.setPassword( password);
factory.setUsername( username);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String delay_q_name = queueName + "_delay";
// 死信队列
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-dead-letter-exchange", "amq.direct");
args.put("x-dead-letter-routing-key", "message_ttl_routingKey");
channel.queueDeclare(delay_q_name, true, false, false, args);
// 声明死信处理队列
channel.queueDeclare(queueName, true, false, false, null);
// 绑定路由
channel.queueBind(queueName, "amq.direct", "message_ttl_routingKey");
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
// 延时2秒,测试-1秒
AMQP.BasicProperties properties = builder.expiration("0").deliveryMode(2).build();
channel.basicPublish("", delay_q_name, properties, msg.getBytes());
channel.close();
connection.close();
log.info("msg=[{}]推送完毕", msg);
}
static String ip = "192.168.0.167";
static String username = "guest";
static String password = "guest";
public static final String qName = "eshop_update_activity_product_price";
public static void main(String[] args) throws Exception {
String msg=qName + "_" + DateUtil.formatyyyyMMddHHmmss(new Date());
sendDelay(qName, msg);
// send(qName, msg);
}
}