SpringBoot项目实战--RabbitMQ
来源:互联网 发布:java版qq 编辑:程序博客网 时间:2024/04/30 05:10
1、在pom.xml文件中添加以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId></dependency>
2、在application.properties文件中添加配置信息:
spring.rabbitmq.username=XXXspring.rabbitmq.password=XXXspring.rabbitmq.virtualHost=XXXspring.rabbitmq.addresses=ip:port,ip:port或者从第三方配置信息中读取:
/** * */import com.sohu.sns.manager.util.JsonMapper;import org.apache.commons.lang3.StringUtils;import java.util.Map;/** * mq连接配置 */public class AmqpInit {private static final JsonMapper jsonMapper = JsonMapper.nonEmptyMapper();public static void init() {try {String mqConfig = ZooKeeperInit.getData("/mq.properties");if (StringUtils.isEmpty(mqConfig)) {throw new Exception("mq.properties is not found in zk.");} else {Map<String,Object> configMap = jsonMapper.fromJson(mqConfig,Map.class);//初始化ConnectionFactory需要参数System.setProperty("spring.rabbitmq.username", configMap.get("user_name").toString());System.setProperty("spring.rabbitmq.password", configMap.get("pwd").toString());System.setProperty("spring.rabbitmq.virtualHost", configMap.get("virtual_host").toString());System.setProperty("spring.rabbitmq.addresses", configMap.get("hosts").toString());}} catch (Exception e) {e.printStackTrace();}}}
才用此种配置时在服务启动时需要初始化信息。
更多配置参考配置类信息:
@ConfigurationProperties( prefix = "spring.rabbitmq")public class RabbitProperties { private String host = "localhost"; private int port = 5672; private String username; private String password; private final RabbitProperties.Ssl ssl = new RabbitProperties.Ssl(); private String virtualHost; private String addresses; private Integer requestedHeartbeat;}
3、添加mq配置信息:
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.messaging.converter.MappingJackson2MessageConverter;@Configurationpublic class AmqpConfig { @Bean public RabbitMessagingTemplate rabbitMessagingTemplate(RabbitTemplate rabbitTemplate) { RabbitMessagingTemplate rabbitMessagingTemplate = new RabbitMessagingTemplate(); rabbitMessagingTemplate.setMessageConverter(jackson2Converter()); rabbitMessagingTemplate.setRabbitTemplate(rabbitTemplate); return rabbitMessagingTemplate; } @Bean public MappingJackson2MessageConverter jackson2Converter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); return converter; }}
由于我在项目中需要往多个实例中发送消息,所以采用Fanout Exchange 类型,在生产中发送消息无需进行其他配置,发送消息代码如下:
@Servicepublic class SendMessageServiceImpl implements SendMessageService{ private static final JsonMapper jsonMapper = JsonMapper.nonEmptyMapper(); private static Logger log = LoggerFactory.getLogger(SendMessageServiceImpl.class); @Autowired private RabbitTemplate rabbitMessagingTemplate; @Override public void sendMessageToMQ(String modelType, String operateType, Object data) { Map<String,Object> mqDataMap = Maps.newConcurrentMap(); mqDataMap.put("modelType",modelType); mqDataMap.put("operateType",operateType); mqDataMap.put("data",data); String exchangeName = System.getProperties().get("spring.rabbitmq.exchange_name").toString(); String message = jsonMapper.toJson(mqDataMap); log.info("send message to mq..........."+message); rabbitMessagingTemplate.convertAndSend(exchangeName,null,message); }}只需要把消息发送到指定名称的交换机中即可。
4、消费者配置:
添加mq服务器配置信息,同生产者配置。
添加消费配置:
import org.springframework.amqp.core.Binding;import org.springframework.amqp.core.BindingBuilder;import org.springframework.amqp.core.FanoutExchange;import org.springframework.amqp.core.Queue;import org.springframework.amqp.rabbit.connection.ConnectionFactory;import org.springframework.amqp.rabbit.core.RabbitAdmin;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * Created by zhangnan on 2016/12/22. */@Configurationpublic class AmqpConfig{ @Bean public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) { return new RabbitAdmin(connectionFactory); } @Bean public Queue mqQueue(RabbitAdmin rabbitAdmin) { String queueName = System.getProperties().get("spring.rabbitmq.queue").toString(); Queue queue = new Queue(queueName,true); rabbitAdmin.declareQueue(queue); return queue; } @Bean public FanoutExchange mqExchange(RabbitAdmin rabbitAdmin) { String exchangeName = System.getProperties().get("spring.rabbitmq.exchange_name").toString(); //将消息分发到所有的绑定队列,无routingkey的概念 FanoutExchange exchange = new FanoutExchange(exchangeName); rabbitAdmin.declareExchange(exchange); return exchange; } @Bean public Binding mqBinding(RabbitAdmin rabbitAdmin) { return BindingBuilder.bind(mqQueue(rabbitAdmin)).to(mqExchange(rabbitAdmin)); }}声明交换路由和队列,并且把队列和交换路由进行绑定。
消费消息:
@Servicepublic class ReceiverMessageServiceImpl { private static final JsonMapper jsonMapper = JsonMapper.nonEmptyMapper(); private static Logger log = LoggerFactory.getLogger(ReceiverMessageServiceImpl.class); @RabbitListener(queues = "${spring.rabbitmq.queue}") @RabbitHandler public void receiveQueue(String message) { log.info("receiver message from mq........"+message); }}由于在初始化配置信息时:spring.rabbitmq.queue采用的是一下配置:
System.setProperty("spring.rabbitmq.queue", configMap.get("queue_name").toString()+ InetAddress.getLocalHost());所以可以实现,每个实例的声明的队列是不一样的,实现消息的广播发送到每个队列中。接收消息也非常简单,只需要添加两个注解,监控指定的队列就可以了,再有消息到达时,就可以消费信息。
5、遇到的问题:
在发送消息时,我刚开始采用的监听的模式,在需要发送消息的地方抛出监听事件,在监听中发送消息mq队列中,在实际测试后发现消息会重复发送,后来废弃这种方式,采用现有的在Service中直接发送消息,重复发送消息的问题解决。
@Componentpublic class EventListener implements ApplicationListener{ private static Logger log = LoggerFactory.getLogger(EventListener.class); @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { }}
0 0
- SpringBoot项目实战--RabbitMQ
- SpringBoot项目集成RabbitMq
- SpringBoot项目实战--thymeleaf
- SpringBoot项目实战--mybatis
- SpringBoot项目实战--ehcache
- SpringBoot项目实战--Jetty
- springboot项目实战开篇
- springboot+rabbitMq整合开发实战一
- SpringBoot项目实战--环境搭建
- Springboot+RabbitMq
- SpringBoot项目实战--Servlet、Filter、拦截器
- SpringBoot创建maven多模块项目(实战)
- SpringBoot项目中整合dubbo/zookeeper实战
- SpringBoot实战_1 Spring项目搭建
- SpringBoot项目实战(7):Filter、Listener
- SpringBoot+Maven项目实战(2):集成SpringBoot
- SpringBoot 实战 (一) :如何创建SpringBoot项目 --入门篇
- SpringBoot+Maven项目实战(2):集成SpringBoot
- maven filter简介
- vs2005从编辑页面定位到解决方案资源管理器
- linux 同步IO: sync、fsync与fdatasync
- 关于Servlet的两种映射方法
- Intellij IDEA实用技巧
- SpringBoot项目实战--RabbitMQ
- Robot Framework之---iframe无id时的定位方法
- Java中Unsafe类详解
- mybatis源码DEBUG学习2
- jsonp原理详解——终于搞清楚jsonp是啥了
- VR 圈里经常被提起的概念
- 我的第一篇博客
- java 场景总结(一)
- gem5学习7——gem5仿真器启动过程