一、使用接口声明:
package com.beauty.common.dispatch;
import java.util.List;
/**
* 审核用户队列
*/
public interface IAuditorQueue {
/**
* 用户id队列
*/
List<String> queueUser(String redisKey);
/**
* 插入一个用户到队列,并且返回用户在队列的位置,若用户已在队列中或插入失败则返回-1
* @return
*/
boolean offerUser(String redisKey, String userId);
/**
* 让用户离开队列
*/
boolean leaveUser(String redisKey, String userId);
/**
* 获取订单信息
*/
List<String> queueOrder(String redisKey);
/**
* 插入订单到队列,并且返回用户在队列的位置,若用户已在队列中或插入失败则返回-1
* @return
*/
boolean offerOrder(String redisKey, String orderId);
/**
* 让订单离开队列
*/
boolean leaveOrder(String redisKey, String orderId);
}
这里redisKey 为存入redis里面的key值,以上接口对应实现类
package com.beauty.common.dispatch.impl;
import com.beauty.common.dispatch.IAuditorQueue;
import com.beauty.common.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Component
public class AuditorQueueImpl implements IAuditorQueue {
@Autowired
private RedisUtil redisUtil;
/**
* 获取列表
* @return
*/
private List<String> queue(String redisKey){
if (StringUtils.isBlank(redisKey)){
return null;
}
if (!redisUtil.hasKey(redisKey)){
return null;
}
List<String> ids = (List<String>) redisUtil.get(redisKey);
return ids;
}
/**
* 进入审核池子
* @return
*/
private boolean offer(String redisKey,String id){
List<String> ids = queueUser(redisKey);
if (CollectionUtils.isEmpty(ids)){
ids = new ArrayList<>();
}
ids.add(id);
redisUtil.set(redisKey,ids);
return true;
}
/**
* 离开审核池子
* @param id
* @return
*/
private boolean leave(String redisKey,String id){
List<String> ids = queueUser(redisKey);
if (CollectionUtils.isEmpty(ids)){
return false;
}
if (ids.contains(id)){
ids.remove(id);
redisUtil.set(redisKey,ids);
}
return true;
}
@Override
public List<String> queueUser(String redisKey) {
return this.queue(redisKey);
}
@Override
public boolean offerUser(String redisKey,String userId) {
return this.offer(redisKey,userId);
}
@Override
public boolean leaveUser(String redisKey,String userId) {
return this.leave(redisKey,userId);
}
@Override
public List<String> queueOrder(String redisKey) {
return this.queue(redisKey);
}
@Override
public boolean offerOrder(String redisKey,String orderId) {
return this.offer(redisKey,orderId);
}
@Override
public boolean leaveOrder(String redisKey,String orderId) {
return this.leave(redisKey,orderId);
}
}
备注:此为最基础的进入和出入,这里用string,使用的时候可自己声明对象。
二、再声明一个接口,与业务场景挂钩:
package com.beauty.common.dispatch;
import java.util.List;
/**
* @desc: 开始处理订单
* @version: 1.0
*/
public interface IAutoDispatchOrders {
/**
* 执行匹配
*/
void executeMatching(String redisKey);
/**
* 插入一个用户到队列,并且返回用户在队列的位置,若用户已在队列中或插入失败则返回-1
* @return
*/
boolean offerUser(String redisKey, String userId);
/**
* 让用户离开队列
*/
boolean leaveUser(String redisKey, String userId);
/**
* 初始化创建审核人员
*/
void initQueueUser(String redisKey, List<String> userIds);
/**
* 插入订单到队列,并且返回用户在队列的位置,若用户已在队列中或插入失败则返回-1
* @return
*/
boolean offerOrder(String redisKey, String orderId);
/**
* 初始化创建订单缓存
*/
void initQueueOrder(String redisKey, List<String> orderIds);
}
package com.beauty.common.dispatch.impl;
import com.beauty.common.dispatch.IAuditorQueue;
import com.beauty.common.dispatch.IAutoDispatchOrders;
import com.beauty.common.dispatch.constant.AuditQueueConstant;
import com.beauty.common.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
*/
@Slf4j
@Component
public class AutoDispatchOrdersImpl implements IAutoDispatchOrders {
@Autowired
private IAuditorQueue auditorQueue;
@Autowired
private RedisUtil redisUtil;
@Autowired
private QueueExecuteMatchImpl executeMatch;
@Override
public void executeMatching(String redisKey){
log.info("--executeMatching--开启连接池匹配:{}",redisKey);
executeMatch.orderMatchingUser(redisKey);
}
@Override
public boolean offerUser(String redisKey, String userId) {
boolean result = auditorQueue.offerUser(redisKey + AuditQueueConstant.USER_NAME_KEY,userId);
if (result)executeMatching(redisKey);
return result;
}
@Override
public boolean leaveUser(String redisKey, String userId) {
return auditorQueue.leaveUser(redisKey + AuditQueueConstant.USER_NAME_KEY,userId);
}
@Override
public void initQueueUser(String redisKey, List<String> userIds) {
if (CollectionUtils.isEmpty(userIds)){
return;
}
String key = redisKey + AuditQueueConstant.USER_NAME_KEY;
if (redisUtil.hasKey(key)){
redisUtil.del(key);
}
redisUtil.set(key,userIds);
}
@Override
public boolean offerOrder(String redisKey, String orderId) {
boolean result = auditorQueue.offerOrder(redisKey + AuditQueueConstant.ORDER_NAME_KEY,orderId);
if (result)executeMatching(redisKey);
return result;
}
@Override
public void initQueueOrder(String redisKey, List<String> orderIds) {
if (CollectionUtils.isEmpty(orderIds)){
return;
}
String key = redisKey + AuditQueueConstant.ORDER_NAME_KEY;
if (redisUtil.hasKey(key)){
redisUtil.del(key);
}
redisUtil.set(key,orderIds);
}
}
1.executeMatch.orderMatchingUser 此方法为处理匹配规则。
2.executeMatch.orderMatchingUser 为异步方法。
3.进入人员/订单都会触发匹配规则。
4.初始化装载人员和订单,需代码调用触发匹配规则。
三、匹配成功后的接口声明:
public interface IQueueMach {
/**
* 匹配成功进行业务处理
*/
void machResult(List<MatchQueueDTO> matchQueues);
}
@Slf4j
@Component("riskQueueMach")
public class RiskQueueMachImpl implements IQueueMach {
@Override
public void machResult(List<MatchQueueDTO> matchQueues) {
for (MatchQueueDTO matchQueueDTO : matchQueues){
log.info("--machResult--匹配成功:{}",matchQueueDTO);
}
}
1.上面的 redisKey 对应 riskQueueMach
/**
* @desc: 审核队列变量声明
* @version: 1.0
*/
public interface AuditQueueConstant {
/**
* redis key 订单集合后缀
*/
String ORDER_NAME_KEY = "Order";
/**
*redis key 用户集合后缀
*/
String USER_NAME_KEY = "User";
/**
* 审核队列
*/
String RISK_CONTROL_AUDIT = "riskQueueMach";
}
2.使用 ApplicationContext spring上下文对象获取对应的bean
ApplicationContext context; //注入
IQueueMach bean =(IQueueMach)context.getBean(redisKey);
if (bean == null){
log.error("请编写:{}类的实现类",redisKey);
return;
}
bean.machResult(matchQueues);
备注:1.可支持多个派单池,业务自身需管理人员和订单进出。
2.匹配规则也可根据不同redisKey,编写相应实现类。
3.匹配成功后需写自身的业务处理。