SpringBoot整合RabbitMQ非常简单,官网有对应的starter,可以自动装配。本文使用官网的starter整合rabbitmq。个人觉得官方有starter的组件就使用starter整合,不要再像以前那样自己写配置客户端,也不要二次封装,因为见过一些别人封装的代码,觉得把rabbitmq很多功能阉割了,也没有springboot提供的starter好用灵活。
下面开始集成rabbitmq
首先pom.xml中引入starter
org.springframework.boot
spring-boot-starter-amqp
application.properties配置文件中添加rabbitmq配置信息
spring.rabbitmq.host=192.168.2.198
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest2018
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.virtual-host=/
#并行消费者数量
spring.rabbitmq.constomers=5
spring.rabbitmq.max-constomers=20
定义一个queue的枚举类
public enum QueueConstants {
QUEUE_TEST1("queue_test_one", "队列1"),
QUEUE_TEST2("queue_test_two", "队列2");
String code;
String desc;
QueueConstants(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
新建一个配置类,用于配置rabbitmq的queue, exchange, binding及customers,自定义messageConverter等等。配置完成后项目启动可以自动建立对应的queue和exchange。当然也可以通过rabbitmq控制台创建。注意:通过控制台创建,queue和exchange的属性(如:durable, autoDelete等)要和此处相对应,否则启动会报异常:Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method
import com.xhd.constants.QueueConstants;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitmqConfig {
/**
* 此处使用自动装配,定义customers和max-customers
* @param connectionFactory
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.rabbitmq")
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
// factory.setMessageConverter(new FastJsonMessageConverter());
return factory;
}
@Bean("queue1")
public Queue queue1() {
return new Queue(QueueConstants.QUEUE_TEST1.getCode());
}
@Bean("queue2")
public Queue queue2() {
return new Queue(QueueConstants.QUEUE_TEST2.getCode());
}
/**
* 定义exchange. 根据需要定义不同的exchange
* @return
*/
@Bean
public TopicExchange exchange() {
return new TopicExchange("exchange_test", true, false);
}
@Bean
Binding bindingExchangeQueue(@Qualifier("queue1") Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("topic.message");
}
@Bean
Binding bindingExchangeMessages(@Qualifier("queue2") Queue queueMessages, TopicExchange exchange) {
return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
}
}
发送消息
@Autowired
private AmqpTemplate rabbitTemplate;
/**
* 发送字符串消息
*/
@Test
public void sendToMQ() {
String content = "this is test content";
rabbitTemplate.convertAndSend(QueueConstants.QUEUE_TEST1.getCode(), content);
}
/**
* 直接发送对象
*/
@Test
public void sendToMQ2() {
User user = new User();
user.setId(190L);
user.setUsername("xxxxx");
user.setEmail("[email protected]");
rabbitTemplate.convertAndSend(QueueConstants.QUEUE_TEST2.getCode(), user);
}
监听消息并接收
import com.rabbitmq.client.Channel;
import com.xhd.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RabbitmqConsumer {
@RabbitHandler
@RabbitListener(queues = "queue_test_one")
public void processQueue1(Message message, Channel channel) {
// //处理成功,消息已消费
// channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
// //处理失败,重新放入队列并重试
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
// //处理失败,丢在一边不重试
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
log.info("data:" + message);
}
@RabbitHandler
@RabbitListener(queues = "queue_test_one")
public void processQueue13(String data) {
try {
log.info("data:" + data);
//业务处理 ...
} catch (Exception e) {
log.error("peocess error", e);
throw new RuntimeException("process error", e); //抛出异常, 消息重新入列并重试
}
}
@RabbitHandler
@RabbitListener(queues = "queue_test_two")
public void processQueue2(User user) {
log.info("user:" + user);
}
}
参考资料:https://docs.spring.io/spring-amqp/docs/2.0.2.RELEASE/reference/html/