public ResultDTO makeStrategy(MakeDecisionDTO makeDecisionDTO) {
final long current = System.currentTimeMillis();
final String request = JSON.toJSONString(makeDecisionDTO);
CatMonitor catMonitor = new CatMonitor();
ResultDTO result = new ResultDTO();
// 获取路由Topic
String routingTopic = routingTopic(makeDecisionDTO);
String keys = makeDecisionDTO.getSerialNo();
// 根据serialNo和路由队列组合key查询redis缓存
String combinationKey = PREFIX_EXIST_CASHE_DECISION + keys + ":" + routingTopic;
Maybe resultDTOMaybe = Maybe
.create((MaybeOnSubscribe) emitter -> {
if (!emitter.isDisposed()) {
emitter.onSuccess(makeDecisionDTO);
}
})
.doOnSubscribe((disposable) -> {
logger.info("{},收到请求,{}", Constants.API_MAKE_DECISION, request);
catMonitor.start(Constants.MSG_RISK_SERVICE_EXTERNAL, Constants.MSG_RISK_SERVICE_MAKE_DECISION);
// 验证productCode和sceneCode
validateMakeDecisionDTO(makeDecisionDTO);
})
.doAfterSuccess(makeDecision ->
// 接收决策后续处理
afterReceiveDecision(makeDecisionDTO, keys, combinationKey)
)
.doFinally(() -> {
String response = JSON.toJSONString(result);
long cost = System.currentTimeMillis() - current;
try {
keepApiLogThreadPool.execute(() -> {
ApiRequestLogDO apiLogDO = new ApiRequestLogDO();
apiLogDO.setName("makeStrategy");
apiLogDO.setType(Constants.API_LOG_TYPE_REQ);
apiLogDO.setUserId(makeDecisionDTO.getUserId());
apiLogDO.setSerialNo(makeDecisionDTO.getSerialNo());
apiLogDO.setProductCode(makeDecisionDTO.getProductCode());
apiLogDO.setSceneCode(makeDecisionDTO.getSceneCode());
apiLogDO.setRequest(request);
apiLogDO.setContent(JSON.toJSONString(makeDecisionDTO));
apiLogDO.setResponse(response);
apiLogDO.setCreateTime(new Date(current));
apiLogDO.setUpdateTime(new Date(System.currentTimeMillis()));
apiLogDO.setCostTime(cost);
apiRequestLogMapper.save(apiLogDO);
});
} catch (RejectedExecutionException e) {
logger.error("RejectedExecutionException happen in {}:serialNo:{}", Constants.API_MAKE_DECISION, makeDecisionDTO.getSerialNo());
}
logger.info("{},执行完成,{},{},{},{},{},{},{}",
Constants.API_MAKE_DECISION,
makeDecisionDTO.getUserId(),
makeDecisionDTO.getProductCode(),
makeDecisionDTO.getSceneCode(),
result.getSerialNo(),
result.getCode(),
result.getMessage(),
cost);
catMonitor.complete();
})
.map(makeDecision -> {
// 获取对应的处理器
RCBusiness rcBusiness = rcBusinessMapper.get(makeDecisionDTO.getProductCode(), makeDecisionDTO.getSceneCode());
if (rcBusiness == null) {
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add("接口不存在")
.add(makeDecisionDTO.getSerialNo())
.toString();
result.setCode(CodeEnum.ILLEGAL_PARAMETERS);
result.setSerialNo(makeDecisionDTO.getSerialNo());
logger.error(errMsg);
catMonitor.error(errMsg);
return result;
}
// 必要参数验证
rcBusiness.validate(makeDecisionDTO);
// 生成事件信息,后续为生成serialNo做数据补全
rcBusiness.analysisEventInfo(makeDecisionDTO);
// 生成风控唯一标识serialNo
rcBusiness.analysisSerialNo(makeDecisionDTO);
// 如果查询有结果,表示是重复请求
if (redisCacheTargetManager.existKey(combinationKey, true)) {
logger.info("repeated requests,{}", makeDecisionDTO.getSerialNo());
result.setCode(CodeEnum.DUPLICATE_REQUEST);
result.setSerialNo(makeDecisionDTO.getSerialNo());
catMonitor.success();
return result;
}
makeDecisionDTO.setCurrent(current);
int delayLevel = needWait(makeDecisionDTO);
// 发送MQ的消息体
String content = JSON.toJSONString(makeDecisionDTO);
if (delayLevel == DECISION_NO_DELAY_LEVEL) {
produce.syncProducer(content, TAGS, keys, routingTopic);
} else {
produce.syncProducer(content, TAGS, keys, delayLevel, routingTopic);
}
logger.info("{},放入队列等待执行,{},{}",
Constants.API_MAKE_DECISION,
content,
delayLevel);
result.setCode(CodeEnum.SUCCESS);
result.setSerialNo(makeDecisionDTO.getSerialNo());
catMonitor.success();
return result;
});
resultDTOMaybe.subscribe(resultDTO ->
logger.info("resultDTO is {}", resultDTO)
, e -> {
if (e instanceof InterruptedException) {
result.setCode(CodeEnum.UNKNOWN_EXCEPTION);
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add("发生中断")
.add(makeDecisionDTO.getSerialNo())
.toString();
logger.error(errMsg, e);
catMonitor.exception(InterruptedException.class.cast(e), errMsg);
Thread.currentThread().interrupt();
} else if (e instanceof RemotingException || e instanceof MQClientException || e instanceof MQBrokerException) {
result.setCode(CodeEnum.UNKNOWN_EXCEPTION);
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add("未知异常")
.add(makeDecisionDTO.getSerialNo())
.toString();
catMonitor.exception(Exception.class.cast(e), errMsg);
logger.error(errMsg, e);
} else if (e instanceof ServiceException) {
result.setCode(((ServiceException) e).getCode());
result.setMessage(e.getMessage());
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add(e.getMessage())
.add(makeDecisionDTO.getSerialNo())
.toString();
catMonitor.exception(ServiceException.class.cast(e), errMsg);
logger.error(errMsg, e);
}
});
// 返回指定结果
return resultDTOMaybe.blockingGet();
}
public ResultDTO makeStrategy(MakeDecisionDTO makeDecisionDTO) {
final long current = System.currentTimeMillis();
final String request = JSON.toJSONString(makeDecisionDTO);
logger.info("{},收到请求,{}", Constants.API_MAKE_DECISION, request);
CatMonitor catMonitor = new CatMonitor();
ResultDTO result = new ResultDTO();
try {
catMonitor.start(Constants.MSG_RISK_SERVICE_EXTERNAL, Constants.MSG_RISK_SERVICE_MAKE_DECISION);
// 验证productCode和sceneCode
validateMakeDecisionDTO(makeDecisionDTO);
// 获取对应的处理器
RCBusiness rcBusiness = rcBusinessMapper.get(makeDecisionDTO.getProductCode(), makeDecisionDTO.getSceneCode());
if (rcBusiness == null) {
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add("接口不存在")
.add(makeDecisionDTO.getSerialNo())
.toString();
result.setCode(CodeEnum.ILLEGAL_PARAMETERS);
result.setSerialNo(makeDecisionDTO.getSerialNo());
logger.error(errMsg);
catMonitor.error(errMsg);
return result;
}
// 必要参数验证
rcBusiness.validate(makeDecisionDTO);
// 生成事件信息,后续为生成serialNo做数据补全
rcBusiness.analysisEventInfo(makeDecisionDTO);
// 生成风控唯一标识serialNo
rcBusiness.analysisSerialNo(makeDecisionDTO);
// 获取路由Topic
String routingTopic = routingTopic(makeDecisionDTO);
String keys = makeDecisionDTO.getSerialNo();
// 根据serialNo和路由队列组合key查询redis缓存
String combinationKey = PREFIX_EXIST_CASHE_DECISION + keys + ":" + routingTopic;
// 如果查询有结果,表示是重复请求
if (redisCacheTargetManager.existKey(combinationKey, true)) {
logger.info("repeated requests,{}", makeDecisionDTO.getSerialNo());
result.setCode(CodeEnum.DUPLICATE_REQUEST);
result.setSerialNo(makeDecisionDTO.getSerialNo());
catMonitor.success();
return result;
}
makeDecisionDTO.setCurrent(current);
int delayLevel = needWait(makeDecisionDTO);
// 发送MQ的消息体
String content = JSON.toJSONString(makeDecisionDTO);
if (delayLevel == DECISION_NO_DELAY_LEVEL) {
produce.syncProducer(content, TAGS, keys, routingTopic);
} else {
produce.syncProducer(content, TAGS, keys, delayLevel, routingTopic);
}
logger.info("{},放入队列等待执行,{},{}",
Constants.API_MAKE_DECISION,
content,
delayLevel);
result.setCode(CodeEnum.SUCCESS);
result.setSerialNo(makeDecisionDTO.getSerialNo());
catMonitor.success();
afterReceiveDecision(makeDecisionDTO, keys, combinationKey);
return result;
} catch (InterruptedException e) {
result.setCode(CodeEnum.UNKNOWN_EXCEPTION);
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add("发生中断")
.add(makeDecisionDTO.getSerialNo())
.toString();
logger.error(errMsg, e);
catMonitor.exception(e, errMsg);
Thread.currentThread().interrupt();
return result;
} catch (RemotingException | MQClientException | MQBrokerException e) {
result.setCode(CodeEnum.UNKNOWN_EXCEPTION);
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add("未知异常")
.add(makeDecisionDTO.getSerialNo())
.toString();
catMonitor.exception(e, errMsg);
logger.error(errMsg, e);
return result;
} catch (ServiceException e) {
result.setCode(e.getCode());
result.setMessage(e.getMessage());
String errMsg = new StringJoiner(STR_COMMA)
.add(Constants.API_MAKE_DECISION)
.add(e.getMessage())
.add(makeDecisionDTO.getSerialNo())
.toString();
catMonitor.exception(e, errMsg);
logger.error(errMsg, e);
return result;
} finally {
String response = JSON.toJSONString(result);
long cost = System.currentTimeMillis() - current;
try {
keepApiLogThreadPool.execute(() -> {
ApiRequestLogDO apiLogDO = new ApiRequestLogDO();
apiLogDO.setName("makeStrategy");
apiLogDO.setType(Constants.API_LOG_TYPE_REQ);
apiLogDO.setUserId(makeDecisionDTO.getUserId());
apiLogDO.setSerialNo(makeDecisionDTO.getSerialNo());
apiLogDO.setProductCode(makeDecisionDTO.getProductCode());
apiLogDO.setSceneCode(makeDecisionDTO.getSceneCode());
apiLogDO.setRequest(request);
apiLogDO.setContent(JSON.toJSONString(makeDecisionDTO));
apiLogDO.setResponse(response);
apiLogDO.setCreateTime(new Date(current));
apiLogDO.setUpdateTime(new Date(System.currentTimeMillis()));
apiLogDO.setCostTime(cost);
apiRequestLogMapper.save(apiLogDO);
});
} catch (RejectedExecutionException e) {
logger.error("RejectedExecutionException happen in {}:serialNo:{}", Constants.API_MAKE_DECISION, makeDecisionDTO.getSerialNo());
}
logger.info("{},执行完成,{},{},{},{},{},{},{}",
Constants.API_MAKE_DECISION,
makeDecisionDTO.getUserId(),
makeDecisionDTO.getProductCode(),
makeDecisionDTO.getSceneCode(),
result.getSerialNo(),
result.getCode(),
result.getMessage(),
cost);
catMonitor.complete();
}
}
上面是改造后和改造前的代码,思前想后,还是不敢轻易用于生产,代码先记录下,看看是否后续有新的灵感,可以优化成不错的代码。