以下是Exchange类型为x-delayed-message,发送延时消息的例子:
(注意:延时时间最大值是86,400,000,即1天)
发送消息
package com.example.rockbund.utils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
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 AMQPUtils {
/**
* 发送消息
*
* @param body
* @throws IOException
* @throws TimeoutException
*/
public static void sendMs(String body, int delayTime) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
// 设置接入点,在消息队列RabbitMQ版控制台实例详情页面查看。
factory.setHost(接入点);
// 用户名,在消息队列RabbitMQ版控制台静态用户名密码页面查看。
factory.setUsername(用户名);
// 密码,在消息队列RabbitMQ版控制台静态用户名密码页面查看。
factory.setPassword(密码);
// 设置为true,开启Connection自动恢复功能;设置为false,关闭Connection自动恢复功能。
factory.setAutomaticRecoveryEnabled(true);
factory.setNetworkRecoveryInterval(5000);
// 设置Vhost名称,请确保已在消息队列RabbitMQ版控制台上创建完成。
factory.setVirtualHost(virtualHost);
// 默认端口,非加密端口5672,加密端口5671。
factory.setPort(5672);
// 基于网络环境合理设置超时时间。
factory.setConnectionTimeout(30 * 1000);
factory.setHandshakeTimeout(30 * 1000);
factory.setShutdownTimeout(0);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 如果exchange类型是x-delayed-message的话,需要加上以下两行
Map<String, Object> argsvv = new HashMap<String, Object>();
argsvv.put("x-delayed-type", x-delayed-type);// 创建Exchange选择x-delayed-message时配置的参数
channel.exchangeDeclare(ExchangeName, exchangeType, true, false, argsvv);
channel.queueDeclare(QueueName, true, false, false, new HashMap<String, Object>());
channel.queueBind(QueueName, ExchangeName, BindingKey);
// 开始发送消息。
// ${ExchangeName}必须在消息队列RabbitMQ版控制台上已存在,并且Exchange的类型与控制台上的类型一致。
// BindingKey根据业务需求填入相应的BindingKey。
// 需要延时发送消息时配置以下两行
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("x-delay", delayTime);
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().messageId(UUID.randomUUID().toString())
.headers(headers).build();
channel.basicPublish(ExchangeName, BindingKey, true, props,
(body).getBytes(StandardCharsets.UTF_8));
connection.close();
}
}
接收消息
package com.example.rockbund.controller.back;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import com.example.rockbund.service.IActivityService;
import com.example.rockbund.service.ITopicService;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
@Component
public class AMQPController {
/**
* 接收消息
*
* @throws IOException
* @throws TimeoutException
*/
@PostConstruct
public void receiveMs() throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
// 设置接入点,在消息队列RabbitMQ版控制台实例详情页面查看。
factory.setHost(接入点);
// 用户名,在消息队列RabbitMQ版控制台静态用户名密码页面查看。
factory.setUsername(用户名);
// 密码,在消息队列RabbitMQ版控制台静态用户名密码页面查看。
factory.setPassword(密码);
// 设置为true,开启Connection自动恢复功能;设置为false,关闭Connection自动恢复功能。
factory.setAutomaticRecoveryEnabled(true);
factory.setNetworkRecoveryInterval(5000);
// 设置Vhost名称,请确保已在消息队列RabbitMQ版控制台上创建完成。
factory.setVirtualHost(virtualHost);
// 默认端口,非加密端口5672,加密端口5671。
factory.setPort(5672);
factory.setConnectionTimeout(300 * 1000);
factory.setHandshakeTimeout(300 * 1000);
factory.setShutdownTimeout(0);
Connection connection = factory.newConnection();
final Channel channel = connection.createChannel();
// 如果exchange类型是x-delayed-message的话,需要加上以下两行
Map<String, Object> argsvv = new HashMap<String, Object>();
argsvv.put("x-delayed-type", x-delayed-type);// 创建Exchange选择x-delayed-message时配置的参数
// 创建${ExchangeName},该Exchange必须在消息队列RabbitMQ版控制台上已存在,并且Exchange的类型与控制台上的类型一致。
AMQP.Exchange.DeclareOk exchangeDeclareOk = channel.exchangeDeclare(ExchangeName, ExchangeType, true,
false, false, argsvv);
// 创建${QueueName} ,该Queue必须在消息队列RabbitMQ版控制台上已存在。
AMQP.Queue.DeclareOk queueDeclareOk = channel.queueDeclare(QueueName, true, false, false,
new HashMap<String, Object>());
// Queue与Exchange进行绑定,并确认绑定的BindingKeyTest。
AMQP.Queue.BindOk bindOk = channel.queueBind(QueueName, ExchangeName, BindingKey);
// 开始消费消息。
channel.basicConsume(QueueName, false, "ConsumerTag", new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
// 接收到的消息,进行业务逻辑处理。
String str= new String(body, StandardCharsets.UTF_8);
System.out.println(str);
channel.basicAck(envelope.getDeliveryTag(), false);
}
});
}
}
在项目启动类中调用接收消息的方法。
在需要发送消息的时候调用发行消息的方法。
调用错误时根据AMQP协议返回错误码排查