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
原创粉丝点击