#####一生成订单后如果一个小时没有打款,就自动撤单,并做出惩罚措施。
- 本文所涉及技术RocketMQ版本:4.3.1 ,JDK1.8,protostuff版本1.1.3
```
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.1.3</version>
</dependency>```
```
@Autowired
private NoticeService noticeService; // 封装的一个mq service类
private RuntimeSchema<String> timeSchema = RuntimeSchema.createFrom(String.class);//序列化需要使用
public void test() {
String messages = buildMQMessage(merchantOrder.getOrderNo(), p.getInvoke(), p.getMethod(), Datas.BORROW);
this.noticeService.delayNotice(messages, this.timeSchema, "OtcTimer", "timer", p.getTimeLevel());
}
//构建JSON消息体,有orderNo,需要定时结束执行的反射方法,当前方法(方便日志),类型(区分业务)
protected String buildMQMessage(String orderNo, String invoke, String method, String type) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderNo", orderNo);
jsonObject.put("invoke", invoke);
jsonObject.put("method", method);
jsonObject.put("type", type);
return jsonObject.toJSONString();
}
//重点讲讲这个方法
/**
*messages:消息体
schema:加一个缓冲区,加快序列化速度
topic:根据topic找消费者
tags:标签
timeLevel:延迟等级messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h (取下标为获取对应的延迟时间,也可自定义)
*/
public <T> void delayNotice(T messages, RuntimeSchema<T> schema, String topic, String tags, Integer timeLevel) {
String key = OtcUtil.createUUId();
try {
byte[] bytes = ProtostuffIOUtil.toByteArray(messages, schema,
LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));//加一个缓冲区,加快序列化速度
Message message = new Message(topic, tags, key, bytes);//组建消息体
message.setDelayTimeLevel(timeLevel);//设置等级(下标)
SendResult sendResult = this.defaultMQProducer.send(message);//(发送)
if (sendResult.getSendStatus() == SendStatus.SEND_OK) {
}
} catch (Exception e) {
// TODO: handle exception
logger.error("sendMq onException , key : " + key, e);
}
}```
```
@Component
public class TimerConsumer {
private final static Logger logger = LoggerFactory.getLogger(TimerConsumer.class);
private RuntimeSchema<String> schema = RuntimeSchema.createFrom(String.class);
@Autowired
private RedisService redisService;//redis去重,防止重复消费
@Autowired
private TestService testTimerService;
@EventListener(condition = "#event.topic == 'OtcTimer'")
public void rocketmqMsgListen(DefaultMQCustomerEvent event) throws Exception {
try {
// 判断key是否存在,去重
String key = event.getMsg().getKeys();
Set<Object> set = this.redisService.getRepeat(key);
if (set.size() > ) {
return;
}
// 参数解析,反序列化解析参数
String paramter = schema.newMessage();
ProtostuffIOUtil.mergeFrom(event.getMsg().getBody(), paramter, schema);
if (StringUtils.isEmpty(paramter)) {
throw new BusinessException(Codes.CODE_500, Messages.OTC_MQ_MESSAGE_ISNULL);
}
JSONObject jsonObject = JSONObject.parseObject(paramter);
String orderNo = jsonObject.getString("orderNo");
String method = jsonObject.getString("method");
String invoke = jsonObject.getString("invoke");//需要反射的方法
String type = jsonObject.getString("type");
// 重点讲解
//getMethod(需要执行的反射方法,方法里的参数类型)
//invoke(需要执行的反射类,方法里的参数)
if (type.equals(Datas.BORROW)) {
this.testService.getClass().getMethod(invoke, String.class, String.class, String.class)
.invoke(this.testService, orderNo, method, invoke);
}
// 将消费完的key放入缓存,去重
this.redisService.setRepeat("Otc:Timer:" + orderNo + ":" + invoke, paramter,
Double.valueOf(System.nanoTime()));
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new BusinessException(Codes.CODE_500, e.getMessage()); // 自定义异常类
}
}
}```
```
@Service
public class TestService {
@Transactional(rollbackFor = Exception.class)
public void orderTimer(String orderNo, String method, String invoke) {
// 具体逻辑
// 我这里用到了事务,分布式锁==保证安全
// 处理异常日志
}
}
找到如下配置

messageDelayLevel=1s 5s 10s 15s 20s 25s 30s 35s 40s 45s 50s 55s 1m 5m 10m 15m 20m 25m 30m 35m 40m 45m 50m 55m 1h 2h 3h 4h 5h 6h 7h 8h 9h 10h 11h 12h 13h 14h 15h 16h 17h 18h 19h 20h 21h 22h 23h 24h 25h 26h 27h 28h 29h 30h 31h 32h 33h 34h 35h 36h 37h 38h 39h 40h 41h 42h 43h 44h 45h 46h 47h 48h 49h 50h 51h 52h 53h 54h 55h 56h 57h 58h 59h 60h 61h 62h 63h 64h 65h 66h 67h 68h 69h 70h 71h 72h
找到messageDelayLevel就可以配置啦!
总结:
(1)无需再轮询全部订单,效率高
(2)一个订单,任务只执行一次
(3)时效性好
-
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69918097/viewspace-3131290/ ,如需转载,请注明出处,否则将追究法律责任。