1.mq连接属性文件
spring:
rabbitmq4esb:
host: 192.168.0.1
rabbitmq:
host: 192.168.1.7
port: 5672
username: admin
password: ********
virtual-host: /
#连接超时,单位毫秒,0表示无穷大
connection-timeout: 15000
#缓存的连接数,只有是CONNECTION模式时生效
#spring.rabbitmq.cache.connection.size=16
#连接工厂缓存模式:CHANNEL 和 CONNECTION
#spring.rabbitmq.cache.connection.mode=CHANNEL
#发送重试是否可用
template:
retry:
enabled: true
#最大重试次数
max-attempts: 5
#第一次和第二次尝试发布或传递消息之间的间隔
initial-interval: 60000
#应用于上一重试间隔的乘数
multiplier: 5
#最大重试时间间隔
max-interval: 1500000
2. mq配置(连接数和连接工厂缓存模式未配置)
package com.java.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.CacheMode;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
@Configuration
public class RabbitMQTemplateConfig {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${spring.rabbitmq4esb.host}")
private String addresses4esb;
@Value("${spring.rabbitmq.host}")
private String addresses;
@Value("${spring.rabbitmq.port}")
private String port;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
@Value("${spring.rabbitmq.virtual-host}")
private String virtualHost;
@Value("${spring.rabbitmq.connection-timeout}")
private String connectionTimeout;
//@Value("${spring.rabbitmq.cache.connection.mode}")
//private String cacheMode;
//@Value("${spring.rabbitmq.cache.connection.size}")
//private String cacheSize;
@Autowired
private Environment env;
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(addresses + ":" + port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setConnectionTimeout(Integer.valueOf(connectionTimeout));
// if ("CONNECTION".equals(cacheMode)) {
// logger.info("connectionFactory CONNECTION cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CONNECTION);
// connectionFactory.setConnectionCacheSize(Integer.valueOf(cacheSize));
// } else {
// logger.info("connectionFactory CHANNEL cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CHANNEL);
// connectionFactory.setChannelCacheSize(Integer.valueOf(cacheSize));
// }
/** 如果要进行消息回调,则这里必须要设置为true */
//connectionFactory.setPublisherConfirms(false);
//connectionFactory.setPublisherReturns(true);
return connectionFactory;
}
@Primary
@Bean(name = "rabbitMQTemplate")
public RabbitTemplate rabbitTemplate() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
rabbitTemplate.setMessageConverter(jsonMessageConverter());
rabbitTemplate.setUsePublisherConnection(false);
/****
rabbitTemplate.setMandatory(false);
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("MsgSendConfirmCallBack , 回调id:" + correlationData);
if (ack) {
logger.info("消息发送成功:correlationData({}),ack({}),cause({})", correlationData, ack, cause);
} else {
System.out.println("消息消费失败:" + cause+"\n重新发送");
}
}
});
****/
/*rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
logger.info("消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}", exchange, routingKey,
replyCode, replyText, message);
}
});*/
return rabbitTemplate;
}
public ConnectionFactory consumeConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(addresses + ":" + port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setConnectionTimeout(Integer.valueOf(connectionTimeout));
// if ("CONNECTION".equals(cacheMode)) {
// logger.info("connectionFactory CONNECTION cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CONNECTION);
// //connectionFactory.setConnectionCacheSize(Integer.valueOf(cacheSize));
// } else {
// logger.info("connectionFactory CHANNEL cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CHANNEL);
// //connectionFactory.setChannelCacheSize(Integer.valueOf(cacheSize));
// }
/** 如果要进行消息回调,则这里必须要设置为true */
//connectionFactory.setPublisherConfirms(false);
//connectionFactory.setPublisherReturns(true);
return connectionFactory;
}
@Primary
@Bean(name = "rabbitListenerContainerFactory")
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(consumeConnectionFactory());
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setAcknowledgeMode(AcknowledgeMode.NONE);
factory.setPrefetchCount(100);
factory.setBatchSize(1);
return factory;
}
@Bean(name = "primaryRabbitAdmin")
@Primary
public RabbitAdmin primaryRabbitAdmin() {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory());
//设置忽略声明异常
rabbitAdmin.setIgnoreDeclarationExceptions(true);
return rabbitAdmin;
}
public ConnectionFactory connectionFactory4ESB() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(addresses4esb + ":" + port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setConnectionTimeout(Integer.valueOf(connectionTimeout));
// if ("CONNECTION".equals(cacheMode)) {
// logger.info("consumeConnectionFactory4ESB CONNECTION cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CONNECTION);
// //connectionFactory.setConnectionCacheSize(Integer.valueOf(cacheSize));
// } else {
// logger.info("consumeConnectionFactory4ESB CHANNEL cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CHANNEL);
// //connectionFactory.setChannelCacheSize(Integer.valueOf(cacheSize));
// }
/** 如果要进行消息回调,则这里必须要设置为true */
//connectionFactory.setPublisherConfirms(false);
//connectionFactory.setPublisherReturns(true);
return connectionFactory;
}
@Bean(name = "rabbitMQTemplate4ESB")
public RabbitTemplate rabbitTemplate4ESB() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory4ESB());
rabbitTemplate.setMessageConverter(jsonMessageConverter());
rabbitTemplate.setUsePublisherConnection(false);
return rabbitTemplate;
}
public ConnectionFactory consumeConnectionFactory4ESB() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(addresses4esb + ":" + port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setConnectionTimeout(Integer.valueOf(connectionTimeout));
// if ("CONNECTION".equals(cacheMode)) {
// logger.info("consumeConnectionFactory4ESB CONNECTION cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CONNECTION);
// //connectionFactory.setConnectionCacheSize(Integer.valueOf(cacheSize));
// } else {
// logger.info("consumeConnectionFactory4ESB CHANNEL cacheMode={}", cacheMode);
// connectionFactory.setCacheMode(CacheMode.CHANNEL);
// //connectionFactory.setChannelCacheSize(Integer.valueOf(cacheSize));
// }
/** 如果要进行消息回调,则这里必须要设置为true */
//connectionFactory.setPublisherConfirms(false);
//connectionFactory.setPublisherReturns(true);
return connectionFactory;
}
@Bean(name = "rabbitListenerContainerFactory4ESB")
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory4ESB() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(consumeConnectionFactory4ESB());
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setAcknowledgeMode(AcknowledgeMode.NONE);
factory.setPrefetchCount(100);
factory.setBatchSize(1);
return factory;
}
@Bean(name = "secondRabbitAdmin")
public RabbitAdmin secondRabbitAdmin() {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory4ESB());
//设置忽略声明异常
rabbitAdmin.setIgnoreDeclarationExceptions(true);
return rabbitAdmin;
}
}
3. 常量
public class MQConstant {
/***
* 延迟队列type x-delayed-message
*/
public static final String X_DELAYED_MESSAGE = "x-delayed-message";
/***
* 延迟队列args key = "x-delayed-type"
*/
public static final String DELAY_ARGS_KEY = "x-delayed-type";
/***
* 延迟队列args value = "direct"
*/
public static final String DELAY_ARGS_VALUE = "direct";
/***
* HEADER
*/
public static final String DELAY_HEADER_KEY = "x-delay";
public static final String EXCHANGE132 = "test_exchange132";
public static final String QUEUE132 = "test_queue132";
public static final String KEY132 = "queue132";
public static final String EXCHANGE74 = "test_exchange74";
public static final String QUEUE74 = "test_queue74";
public static final String KEY74 = "queue74";
}
4. 创建队列、交换机以及绑定
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MQConfig {
@Resource(name = "secondRabbitAdmin")
private RabbitAdmin secondRabbitAdmin;
@Resource(name = "primaryRabbitAdmin")
private RabbitAdmin primaryRabbitAdmin;
@Bean
void delayDeclareBinding132() {
Queue queue = new Queue(MQConstant.QUEUE132, true);
secondRabbitAdmin.declareQueue(queue);
CustomExchange delayExchange = delayExchange(MQConstant.EXCHANGE132);
secondRabbitAdmin.declareExchange(delayExchange);
secondRabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(delayExchange).with(MQConstant.KEY132).noargs());
}
@Bean
void directDeclareBinding74() {
Queue queue = new Queue(MQConstant.QUEUE74,true);
primaryRabbitAdmin.declareQueue(queue);
CustomExchange delayExchange = delayExchange(MQConstant.EXCHANGE74);
primaryRabbitAdmin.declareExchange(delayExchange);
primaryRabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(delayExchange).with(MQConstant.KEY74).noargs());
}
public CustomExchange delayExchange(String exchange) {
Map<String, Object> arguments = new HashMap<>();
/**
* 参数说明:
* 1.交换机的名称
* 2.交换机的类型
* 3.是否需要持久化
* 4.是否自动删除
* 5.其它参数
*/
// 参数固定写法 x-delayed-type 延迟插件名称 ,direct 直接模式
arguments.put(MQConstant.DELAY_ARGS_KEY, MQConstant.DELAY_ARGS_VALUE);
// 创建交换机
return new CustomExchange(exchange, MQConstant.X_DELAYED_MESSAGE, true, false, arguments);
}
}
5. 消费
@Component
public class Consumer7 {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@RabbitListener(queues = MQConstant.QUEUE74, containerFactory = "rabbitListenerContainerFactory", ackMode = "MANUAL", concurrency = "2-12")
public void doConsume7(Map<String, Object> messageMap, Channel channel, Message message) throws ParseException, IOException{
try {
log.info("Consumer192.168.0.7 MQ接收到的消息 messageMap={}, time={}", JSONObject.toJSONString(messageMap), CommonUtils.dateFormat(new Date(), null));
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
log.error("Consumer192.168.0.7 消费时发生异常", e);
}
}
}
@RabbitListener(queues = MQConstant.QUEUE132, containerFactory = "rabbitListenerContainerFactory4ESB", ackMode = "MANUAL", concurrency = "2-12")
public void doConsume1(Map<String, Object> messageMap, Channel channel, Message message)
throws ParseException, IOException {
try {
if (null == messageMap) {
log.error("Consume192.168.0.1 MQ接收到的消息messageMap为空");
} else {
log.info("Consume192.168.0.1 MQ接收到的消息 messageMap={}, time={}", JSONObject.toJSONString(messageMap), CommonUtils.dateFormat(new Date(), null));
}
// 此处不做确认,mq管理页面会显示有一个消息Unacked=1,防止程序异常消息丢失
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
log.error("doConsume132 ex:" + e.getMessage(), e);
e.printStackTrace();
}
}
6. 测试类
@Resource(name = "rabbitMQTemplate")
private RabbitTemplate rabbitTemplate;
@Resource(name = "rabbitMQTemplate4ESB")
private RabbitTemplate rabbitTemplate4esb;
@Resource
private MqUtils mqUtils;
@RequestMapping(value = "/mq")
public void testMQ() {
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("name", "123456789");
rabbitTemplate.convertAndSend(MQConstant.EXCHANGE74, MQConstant.KEY74, paramMap);
rabbitTemplate4esb.convertAndSend(MQConstant.EXCHANGE132, MQConstant.KEY132, paramMap);
paramMap.put("ip", "192.168.0.1");
paramMap.put("template", "1");
mqUtils.sendEsb(MQConstant.EXCHANGE132, MQConstant.KEY132, 20000, paramMap);
paramMap.put("ip", "192.168.0.7");
paramMap.put("template", "7");
mqUtils.send(MQConstant.EXCHANGE74, MQConstant.KEY74, 30000, paramMap);
}