生产者
下面展示一些 内联代码片
。
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.downtown.enums.EnvEnum;
import com.downtown.pos.util.EnvConfig;
import com.downtown.utils.enums.Bo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.downtown.pos.log.OLog;
/**
* MQ服务
*/
@Component
public class StoreMqService {
@Autowired
RabbitTemplate rabbitTemplate;
@Autowired
OLog oLog;
// @Autowired
// MQTTService mQTTService;
@Async
public void sendMq(String requstId , String action ,Object data ) {
readyGo( requstId , action ,data );
}
private void readyGo(String requstId ,String action ,Object data ) {
String routeKey = "storex";
if(StoreMqTopicConfig.getKdsMap().containsKey(action) ) {
routeKey += ".kds";
}
if(StoreMqTopicConfig.getFeeMap().containsKey(action) ) {
routeKey += ".fee";
}
if(StoreMqTopicConfig.getMktMap().containsKey(action) ) {
routeKey += ".mkt";
}
// if(StoreMqTopicConfig.getMemberMap().containsKey(action) ) {
// routeKey += ".member";
// }
if(StoreMqTopicConfig.getPayMap().containsKey(action) ) {
routeKey += ".pay";
}
if(StoreMqTopicConfig.getPosMap().containsKey(action) ) {
routeKey += ".pos";
}
if (Bo.cn.name().equals(EnvEnum.getByEvn(EnvConfig.envName).getBo())){
if(StoreMqTopicConfig.getAllianceMap().containsKey(action) ) {
routeKey += ".alliance";
}
}
go( requstId, action, routeKey ,data );
}
private void go(String requstId , String action, String routeKey ,Object data) {
try {
Map<String,Object> mqOrdersData = new HashMap<>(16);
mqOrdersData.put("data",data);
mqOrdersData.put("id",requstId);
mqOrdersData.put("addTime",new Date());
mqOrdersData.put("action",action);
CorrelationData correlationData = new CorrelationData(requstId);
rabbitTemplate.convertAndSend(StoreMqTopicConfig.TOPICExchange, routeKey,JSON.toJSONStringWithDateFormat(mqOrdersData, "yyyy-MM-dd HH:mm:ss"),correlationData);
oLog.info( "投递MQ:"+action, JSON.toJSONStringWithDateFormat(mqOrdersData, "yyyy-MM-dd HH:mm:ss"));
// logger.info("send to mq ,ordersId:" + ordersId + ",action:" + action +",requstId:" + requstId);
}catch(Exception e){
e.printStackTrace();
oLog.info( "投递MQ失败:"+action, routeKey);
}
}
}
交换机
package com.downtown.pos.mq;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import com.downtown.pos.log.OLog;
import com.downtown.pos.store.storeEvent.StoreEventsActionEnum;
/**
* mq交换机
* @author zhoucheng
*
*/
@Configuration
public class StoreMqTopicConfig {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
OLog ordersLogerService;
public final static String TOPICExchange = "posTopicExchange";
public static Map<String,Integer> KdsMap = new HashMap<>();
public static Map<String,Integer> PayMap = new HashMap<>();
public static Map<String,Integer> PosMap = new HashMap<>();
public static Map<String,Integer> MktMap = new HashMap<>();
public static Map<String,Integer> FeeMap = new HashMap<>();
public static Map<String,Integer> AllianceMap = new HashMap<>();
static {
//{
// [RabbitmqTopic.posAddBrand]: ['.pay', '.kds', '.fee', '.mkt.1'],
// [RabbitmqTopic.posAddStore]: ['.pay', '.kds', '.member', '.fee', '.mkt', '.pos.1'],
// [RabbitmqTopic.posDelStore]: ['.pay', '.kds', '.member', '.fee', '.mkt.1'],
// [RabbitmqTopic.posMenuChange]: ['.pos.1']
//}
KdsMap.put(StoreEventsActionEnum.CREATE.getAction(),1);
PayMap.put(StoreEventsActionEnum.CREATE.getAction(),1);
FeeMap.put(StoreEventsActionEnum.CREATE.getAction(),1);
MktMap.put(StoreEventsActionEnum.CREATE.getAction(),1);
PosMap.put(StoreEventsActionEnum.CREATE.getAction(),1);
KdsMap.put(StoreEventsActionEnum.UPDATE.getAction(),1);
MktMap.put(StoreEventsActionEnum.UPDATE.getAction(),1);
AllianceMap.put(StoreEventsActionEnum.UPDATE.getAction(),1);
KdsMap.put(StoreEventsActionEnum.DELETE.getAction(),1);
MktMap.put(StoreEventsActionEnum.DELETE.getAction(),1);
AllianceMap.put(StoreEventsActionEnum.DELETE.getAction(),1);
}
@Bean
TopicExchange exchange() {
return new TopicExchange(StoreMqTopicConfig.TOPICExchange);
}
// static KdsSimpleQueue = 'KdsSimpleQueue'
// [RabbitmqQueue.KdsSimpleQueue]: '#.kds.#',
@Bean
public Queue KdsQueue() {
return new Queue("KdsSimpleQueue");
}
@Bean
Binding bindingKdsExchangeMessage() {
return BindingBuilder.bind(KdsQueue()).to(exchange()).with("#.kds.#");
}
// static PayQueue = 'StorePayQueue'
// [RabbitmqQueue.PayQueue]: '#.pay.#',
@Bean
public Queue PayQueue() {
return new Queue("StorePayQueue");
}
@Bean
Binding bindingPayExchangeMessage() {
return BindingBuilder.bind(PayQueue()).to(exchange()).with("#.pay.#");
}
// static PosQueue = 'PosQueue'
// [RabbitmqQueue.PosQueue]: "#.pos.#",
@Bean
public Queue PosQueue() {
return new Queue("PosQueue");
}
@Bean
Binding bindingPosExchangeMessage() {
return BindingBuilder.bind(PosQueue()).to(exchange()).with("#.pos.#");
}
// static MemberSimpleQueue = 'MemberSimpleQueue'
// [RabbitmqQueue.MemberSimpleQueue]: "#.member.#",
// @Bean
// public Queue MemberSimpleQueue() {
// return new Queue("MemberSimpleQueue");
// }
//
// @Bean
// Binding bindingMemberExchangeMessage() {
// return BindingBuilder.bind(MemberSimpleQueue()).to(exchange()).with("#.member.#");
// }
// static FeeSimpleQueue = 'FeeSimpleQueue'
// [RabbitmqQueue.FeeSimpleQueue]: "#.fee.#",
@Bean
public Queue FeeSimpleQueue() {
return new Queue("FeeSimpleQueue");
}
@Bean
Binding bindingFeeExchangeMessage() {
return BindingBuilder.bind(FeeSimpleQueue()).to(exchange()).with("#.fee.#");
}
// [RabbitmqQueue.PosMkt]: "#.mkt.#"
// [RabbitmqQueue.PosMkt]: "#.mkt.#"
@Bean
public Queue PosMkt() {
return new Queue("PosMkt");
}
@Bean
Binding bindingMktExchangeMessage() {
return BindingBuilder.bind(PosMkt()).to(exchange()).with("#.mkt.#");
}
@Bean
public Queue PosAlliance() {
return new Queue("PosAlliance");
}
@Bean
Binding bindingAllianceExchangeMessage() {
return BindingBuilder.bind(PosAlliance()).to(exchange()).with("#.alliance.#");
}
@Bean
public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory){
RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
rabbitTemplate.setMandatory(true);
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(10));
rabbitTemplate.setRetryTemplate(retryTemplate);
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if(!ack) {
logger.info("ConfirmCallback:"+"确认情况:"+ack);
logger.info("ConfirmCallback: "+"相关数据:"+correlationData);
logger.info("ConfirmCallback: "+"原因:"+cause);
}else {
// int cnt = ordersEventDao.updateStatus(new Date(),correlationData.getId());
// if(cnt > 0) {
// try {
// OrdersEvent oe = ordersEventDao.findByRequstIdAndStatus(correlationData.getId(),1).get(0);
// ordersLogerService.info(oe.getOrdersId(), correlationData.getId(), "投递成功", oe);
// }catch(Exception e) {
// e.printStackTrace();
// }
// }
}
}
});
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
logger.error("ReturnCallback: "+"消息:"+message);
logger.error("ReturnCallback: "+"回应码:"+replyCode);
logger.error("ReturnCallback: "+"回应信息:"+replyText);
logger.error("ReturnCallback: "+"交换机:"+exchange);
logger.error("ReturnCallback: "+"路由键:"+routingKey);
// ordersLogerService.error(message., null, null, correlationData.getId(), "投递成功", message);
}
});
return rabbitTemplate;
}
public static Map<String, Integer> getKdsMap() {
return KdsMap;
}
public static Map<String, Integer> getPayMap() {
return PayMap;
}
public static Map<String, Integer> getPosMap() {
return PosMap;
}
// public static Map<String, Integer> getMemberMap() {
// return MemberMap;
// }
public static Map<String, Integer> getMktMap() {
return MktMap;
}
public static Map<String, Integer> getFeeMap() {
return FeeMap;
}
public static Map<String, Integer> getAllianceMap() { return AllianceMap; }
}
消费者
package com.downtown.service.mq;
import com.alibaba.fastjson.JSON;
import com.downtown.service.alliance.storeSaleResource.service.StoreSaleResourceService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
/**
* 新门店创建消息处理
* @author Zhaobin
*/
@Slf4j
@Component
/*@RabbitListener(queues = "StorePayQueue")*/
public class CreateBrandStoreQueueListener {
private static final String ACTION_ADD_STORE = "Pos_StoreAdd";
private static final String ACTION_ADD_BRAND = "Pos_BrandAdd";
private static final String POS_TOPIC_EXCHANGE = "posTopicExchange";
private static final String STORE_ALLIANCE_QUEUE = "StoreAllianceQueue";
private static final String STORE_PAY_QUEUE = "StorePayQueue";
/**
* 借用支付接口的BindingKey
*/
private static final String ALLIANCE_BINDING_KEY = "#.pay.#";
@Value("${mq.create-brand-store.enabled}")
private boolean enabled;
@Resource
private StoreSaleResourceService storeSaleResourceService;
@RabbitListener(
bindings =
@QueueBinding(
value = @Queue(value = STORE_ALLIANCE_QUEUE, durable = "true"),
exchange =
@Exchange(
value = POS_TOPIC_EXCHANGE,
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC),
key = {ALLIANCE_BINDING_KEY})
)
@RabbitHandler
public void process(Message message, Channel channel) throws IOException {
String content = new String(message.getBody());
log.info("StoreAllianceQueue MQ String Process 收到授权MQ消息:" + content);
goprocess(content, message, channel);
}
// @RabbitListener(
// bindings =
// @QueueBinding(
// value = @Queue(value = STORE_ALLIANCE_QUEUE, durable = "true"),
// exchange =
// @Exchange(
// value = POS_TOPIC_EXCHANGE,
// ignoreDeclarationExceptions = "true",
// type = ExchangeTypes.TOPIC),
// key = {ALLIANCE_BINDING_KEY})
// ack
// )
// @RabbitHandler
// public void process(Message message, Channel channel) throws IOException {
// String content = new String(message.getBody());
// log.info("StoreAllianceQueue MQ String Process 收到授权MQ消息:" + content);
// goprocess(content, message, channel);
// }
/**
* @param content
* @param message
* @param channel
*/
public void goprocess(String content, Message message, Channel channel) {
if (!enabled) {
return;
}
try {
CreateBrandStoreMsg createBrandStoreMsg = JSON.parseObject(content, CreateBrandStoreMsg.class);
String action = createBrandStoreMsg.getAction();
if (null != message && null != channel) {
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
CreateBrandStoreDataDTO data = createBrandStoreMsg.getData();
if (null == data) {
log.error("消息格式错误,无法获取object节点");
return;
}
// 新增门店,所有的可授权模块自动授权5天试用时间
if (action.equals(ACTION_ADD_STORE)) {
storeSaleResourceService.autoGrantNewStore(data.getBrandId(), data.getStoreId(), data.getStoreName());
} else if (action.equals(ACTION_ADD_BRAND)) {
storeSaleResourceService.autoGrantNewBrand(data.getBrandId(), data.getBrandName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
延时队列
package com.downtown.service.mq;
import com.downtown.log.OLog;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.concurrent.TimeUnit;
/**
* @author zcz
* rabbitMq生产者
*/
@Component
public class RabbitProduct {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private OLog logger;
@Value("${time-zone.offset}")
String timeZone;
/**
* 发送延时消息
* @param params
* @param delayMill
*/
public void sendDelayMessage(Object params, long delayMill) {
//这里的消息可以是任意对象,无需额外配置,直接传即可
this.logger.info("发送延时消息", params);
this.rabbitTemplate.convertAndSend(
"deliveryDelayExchange",
"#.delivery.#",
params,
message -> {
//注意这里时间可以使long,而且是设置header
message.getMessageProperties().setHeader("x-delay", delayMill);
return message;
}
);
}
public void sendDelayMessage(Object params, LocalDateTime delayTime) {
LocalDateTime nowTime = LocalDateTime.now(ZoneId.of(timeZone));
Duration duration = Duration.between(nowTime, delayTime);
long delayMill = duration.toMillis();
this.sendDelayMessage(params, delayMill);
}
/**
*
* @param params 参数
* @param delayTime 延迟时间
*/
public void sendBatchCallMessage(Object params, long delayTime) {
long delayDate = TimeUnit.MINUTES.toMillis(delayTime);
this.sendDelayMessage(params, delayDate);
}
}
消费
package com.downtown.service.mq;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.downtown.enums.TaskTypeEnum;
import com.downtown.log.OLog;
import com.downtown.service.service.OrderService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* @author zcz
* 配送延时队列
*/
@Component
public class DeliveryDelayQueue {
@Autowired
OLog logger;
@Autowired
OrderService orderService;
@RabbitListener(queues = "DeliveryDelayQueue")
@RabbitHandler
public void process(Message oMessage, Channel channel) throws IOException {
String messageString = new String(oMessage.getBody());
try {
logger.info("配送延迟任务", messageString);
JSONObject objContent = JSON.parseObject(messageString);
String type = objContent.getString("type");
String uniqueId = objContent.getString("uniqueId");
if (TaskTypeEnum.RESERVE.getTaskType().equals(type)) {
this.orderService.dealReserveDelayTask(new Integer(uniqueId));
}
//分批呼叫
if (TaskTypeEnum.BATCH_CALL.getTaskType().equals(type)) {
this.logger.info("mq分批呼叫延迟消费", objContent);
this.orderService.batchCallOrderProcessingDelayTask(new Integer(uniqueId));
}
}catch(Exception err) {
this.logger.info("订单配送单取消失败", err);
}finally {
channel.basicAck(oMessage.getMessageProperties().getDeliveryTag(), false);
}
}
}
配置
package com.downtown.service.mq;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @author zcz
* RabbitMq配置
*/
@Configuration
public class RabbitMqConfig {
@Bean
public CustomExchange delayExchange() {
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
//属性参数 交换机名称 交换机类型 是否持久化 是否自动删除 配置参数
return new CustomExchange("deliveryDelayExchange", "x-delayed-message", true, false, args);
}
@Bean
public Queue delayQueue() {
//属性参数 队列名称 是否持久化
return new Queue("DeliveryDelayQueue", true);
}
@Bean
public Binding cfgDelayBinding() {
return BindingBuilder.bind(delayQueue()).to(delayExchange()).with("#.delivery.#").noargs();
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>