实例代码
package com.bkjk.message.config;
import lombok.Data;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 链接管理
* @author kiven·ing
*/
@ConfigurationProperties(prefix = "spring.rabbitmq")
@Data
@Configuration
public class RabbitConnectConfig {
String host;
String port;
String username;
String password;
@Bean("mqConnectionFactory")
public ConnectionFactory mqConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost("/");
connectionFactory.setPublisherConfirms(true);
/**
* 设置通道数量
*/
connectionFactory.setChannelCacheSize(40);
//该方法配置多个host,在当前连接host down掉的时候会自动去重连后面的host
connectionFactory.setAddresses(host);
return connectionFactory;
}
@Bean
public RabbitAdmin rabbitAdmin( ) {
return new RabbitAdmin(mqConnectionFactory());
}
}
@Component
public class MessageManager {
private static final String DELAY_ROU = "_delay";
private static final Integer DELAY_DUTATION = 1000;
@Resource
RabbitAdmin rabbitAdmin;
@Resource
private RabbitTemplate rabbitTemplate;
## 配置发送格式
@Bean
public AmqpTemplate amqpTemplate() {
//使用jackson 消息转换器
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
rabbitTemplate.setEncoding("UTF-8");
// 开启returncallback
rabbitTemplate.setMandatory(true);
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
String correlationId = message.getMessageProperties().getCorrelationIdString();
logger.info("消息:{} 发送失败, 应答码:{} 原因:{} 交换机: {} 路由键: {}", correlationId, replyCode, replyText, exchange, routingKey);
});
// 消息确认 yml 需要配置
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
if (ack) {
logger.info("消息发送到exchange成功");
} else {
logger.info("消息发送到exchange失败,原因: {}", cause);
}
});
return rabbitTemplate;
}
## 创建动态队列与交换机
/**
* 发送延迟消息
* @param object
* @param delayTime
*/
public void createQueueAndSend( MessagePo object,Integer delayTime) throws AmqpException {
DirectExchange exchange = createExchange(rabbitConfig.getExchange() + DELAY_ROU);
addExchange(exchange);
String delayQueueName = rabbitConfig.getDelay() + "_" + delayTime;
Queue delayQueue = createDelayQueue(delayQueueName, delayTime );
addQueue(delayQueue);
addBinding(delayQueue, exchange, delayQueueName);
rabbitTemplate.convertAndSend(delayQueueName,object,new CorrelationData(object.getTag()));
}
/**
* 根据发送延迟消息
* @param object
* @param secondDelayTime 单位秒
*/
public void sendDelayMessage( MessagePo object,Integer secondDelayTime) throws AmqpException {
String queueSerial = NotifyDailyEnum.getDescByCode(secondDelayTime);
if (StringUtils.isNoneBlank(queueSerial)) {
String delayQueueName = rabbitConfig.getDelay() + "_" + queueSerial;
rabbitTemplate.convertAndSend(delayQueueName, object,new CorrelationData(object.getTag()));
} else {
createQueueAndSend(object, secondDelayTime * DELAY_DUTATION);
}
}
/**
* 根据que 和rout发送消息
* @param routingKey
* @param object
*/
public void sendQueueMessage(String routingKey, MessagePo object){
rabbitTemplate.convertAndSend(routingKey,object,new CorrelationData(object.getTag()));
}
/**
* 根据exhange 和rout发送
* @param exchange
* @param routingKey
* @param object
*/
public void sentExchangeMessage(String exchange, String routingKey, Object object){
rabbitTemplate.convertAndSend(exchange,routingKey,object);
}
/**
* 创建Exchange
*
* @param exchange
*/
private void addExchange(AbstractExchange exchange) {
rabbitAdmin.declareExchange(exchange);
}
/**
* 创建一个指定的Queue
*
* @param queue
* @return queueName
*/
private String addQueue(Queue queue) {
return rabbitAdmin.declareQueue(queue);
}
/**
* 绑定一个队列到一个匹配型交换器使用一个routingKey
*
* @param queue
* @param exchange
* @param routingKey
*/
private void addBinding(Queue queue, DirectExchange exchange, String routingKey) {
Binding binding = BindingBuilder.bind(queue).to(exchange).with(routingKey);
rabbitAdmin.declareBinding(binding);
}
private Queue createDelayQueue(String queueName, Integer delayMillis) {
/**
* 队列名称 //死信时间 ,死信重新投递的交换机 ,路由到队列的routingKey
*/
return QueueBuilder.durable(queueName)
.withArgument("x-message-ttl", delayMillis)
.withArgument("x-expires", delayMillis * DELAY_LIFE) //设置队列自动删除时间
.withArgument("x-dead-letter-exchange", rabbitConfig.getExchange())
.withArgument("x-dead-letter-routing-key", rabbitConfig.getQueue())
.build();
}
/**
* 创建不删除的队列
* @param queueName
* @param delayMillis
* @return
*/
private Queue createDelayQueueNoDelete(String queueName, Integer delayMillis) {
/**
* 队列名称 //死信时间 ,死信重新投递的交换机 ,路由到队列的routingKey
*/
return QueueBuilder.durable(queueName)
.withArgument("x-message-ttl", delayMillis)
.withArgument("x-dead-letter-exchange", rabbitConfig.getExchange())
.withArgument("x-dead-letter-routing-key", rabbitConfig.getQueue())
.build();
}
private DirectExchange createExchange(String exchangeName) {
return new DirectExchange(exchangeName, true, false);
}