RxJava的一次业务尝试


 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();
        }
    }

上面是改造后和改造前的代码,思前想后,还是不敢轻易用于生产,代码先记录下,看看是否后续有新的灵感,可以优化成不错的代码。

你可能感兴趣的:(架构师之路)