1、Rabbit服务连接
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
listener:
simple:
concurrency: 100
max-concurrency: 100
bxwell:
consume:
default_concurrent: 1
default_prefetch_count: 1
queue:
name: platform.pushinfo.top.surface
exchange:
name: platform.pushinfo.topicExchange
routing_key: platform.pushinfo.topicExchange.*
2、RabbitConfig 配置环境用的是阿巴的Nacos所以很多配置东西本地项目看不到
package com.bxwell.hj360.surfacewater.config.rabbit;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author hanjq
* @des
* @date 2020/9/7 17:12
*/
@Configuration
public class RabbitConfig {
/**
* 消费者数量
*/
@Value("${bxwell.rabbitmq.consume.default_concurrent}")
public int DEFAULT_CONCURRENT;
/**
* 每个消费者获取最大投递数量
*/
@Value("${bxwell.rabbitmq.consume.default_prefetch_count}")
public int DEFAULT_PREFETCH_COUNT;
/**
* 队列名称
*/
@Value("${bxwell.rabbitmq.queue.name}")
public String queueName;
/**
* 交换机名称
*/
@Value("${bxwell.rabbitmq.exchange.name}")
public String exchangeName;
/**
* 路由
*/
@Value("${bxwell.rabbitmq.routing_key}")
public String routingKey;
@Autowired
private CachingConnectionFactory connectionFactory;
@Autowired
private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;
@Bean(name = "pointTaskContainerFactory")
public SimpleRabbitListenerContainerFactory pointTaskContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factoryConfigurer.configure(factory, connectionFactory);
//配置接收消息反序列化转换器
factory.setMessageConverter(jackson2MessageConverter());
//设置为手动ack
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//消费者并发数量
factory.setConcurrentConsumers(DEFAULT_CONCURRENT);
//限流,每次接收消息的数量
factory.setPrefetchCount(DEFAULT_PREFETCH_COUNT);
return factory;
}
/**
* 配置发送端rabbitTemplate的序列化转换器
* @return
*/
@Bean
public RabbitTemplate rabbitTemplate() {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//配置发送消息序列化转换器
rabbitTemplate.setMessageConverter(jackson2MessageConverter());
return rabbitTemplate;
}
public Jackson2JsonMessageConverter jackson2MessageConverter() {
return new Jackson2JsonMessageConverter();
}
/**
* 创建交换机
*
* @return
*/
@Bean
public TopicExchange topicExchange() {
TopicExchange topicExchange = new TopicExchange(exchangeName, true, false);
return topicExchange;
}
/**
* 创建队列
*
* @return
*/
@Bean
public Queue platformDataQueue() {
Queue queue = new Queue(queueName, true, false, false);
return queue;
}
/**
* 绑定队列到交换机
*
* @return
*/
@Bean
public Binding platformDataBinding() {
Binding binding = BindingBuilder.bind(platformDataQueue()).to(topicExchange()).with(routingKey);
return binding;
}
}
3、rabbit AMQP协议
<!-- rabbitmq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
4、生产者
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 生产者
* @author hanjq
* @des
* @date 2020/9/8 13:05
*/
@RestController
@RequestMapping("/produce")
public class produceMsg {
@Autowired
private RabbitTemplate rabbitTemplate;
@GetMapping("/sendTopicMessage")
public String sendDirectMessage() {
//参数1:exchange(队列) 参数2:routingkey(队列索引) 参数3:数据体对象
//发送消息
rabbitTemplate.convertAndSend("platform.pushinfo.topicExchange", "platform.pushinfo.top.surface", new JSONObject());
return "ok";
}
}
5、消费者
package com.bxwell.hj360.surfacewater.consume;
import com.alibaba.fastjson.JSONObject;
import com.bxwell.hj360.surfacewater.consume.service.ImqMsgService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
/**
* 消费者
* @author hanjq
* @des
* @date 2020/9/7 18:55
*/
@Component
@Slf4j
public class ReceivePlatformMqMsg {
private static String exhange = "platform.pushinfo.topicExchange";
private static String routingKey = "platform.pushinfo.top.surface";
@Autowired
ImqMsgService iMqMsgService;
@RabbitListener(queues = "platform.pushinfo.top.surface", containerFactory = "pointTaskContainerFactory")
public void receive(Message message, Channel channel, JSONObject json) {
//获取消息索引
Long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
if (Objects.isNull(json)) {
//消息为空丢弃消息
channel.basicReject(deliveryTag, false);
return;
}
//消费数据
//此处consumerDatas方法为自己的业务处理
if (consumerDatas(json)) {
//手动ack
channel.basicAck(deliveryTag, false);
} else {
channel.basicReject(deliveryTag, false);
//TODO 将消费失败消息存储到数据库
iMqMsgService.insertMqMsg(exhange,routingKey, json);
}
} catch (Exception e) {
try {
channel.basicReject(deliveryTag, false);
//TODO 将消费失败消息存储到数据库
iMqMsgService.insertMqMsg(exhange,routingKey, json);
} catch (Exception ex) {
log.error("Mq拒绝消费数据失败", ex.getStackTrace());
}
log.error("接收平台消息失败", e.getStackTrace());
}
}
private boolean consumerDatas(JSONObject json) {
try {
//业务代码
return true;
} catch (Exception ex) {
log.error("接收平台消息失败", ex.getStackTrace());
return false;
}
}
}