第3方接口交互-日志方案

1. 打印log日志
2. 异步记录到日志表中
日志表
CREATE TABLE `d_interaction_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增长id',
  `client_code` varchar(20) NOT NULL COMMENT '系统标识',
  `direction` char(1) NOT NULL COMMENT '数据流向:出(S)/入(R)',
  `key_code` varchar(50) DEFAULT NULL COMMENT '业务主键/applycd',
  `serialnumber` varchar(50) DEFAULT NULL COMMENT '流水号',
  `interface_name` varchar(200) DEFAULT NULL COMMENT '接口名称',
  `remotehost` varchar(200) DEFAULT NULL COMMENT '访问主机地址',
  `input_params` mediumtext COMMENT '入参',
  `output_params` mediumtext COMMENT '出参',
  `request_time` datetime DEFAULT NULL COMMENT '开始请求时间',
  `response_time` datetime DEFAULT NULL COMMENT '收到响应时间',
  `time_length` int(11) DEFAULT NULL COMMENT '耗时:ms',
  `result` int(11) DEFAULT NULL COMMENT '调用结果:1,成功;0,失败',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注,发生错误时放入异常信息',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `user_id` varchar(50) DEFAULT NULL COMMENT '用户id',
  PRIMARY KEY (`id`),
  KEY `IDX_KEYCODE` (`key_code`),
  KEY `IDX_SERNUM` (`serialnumber`)
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8 COMMENT='与外部业务系统交互日志'
日志 bean
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Date;


@TableName("d_interaction_log")
@Getter
@Setter
public class InteractionLog implements Serializable {
	private static final long serialVersionUID = 1L;

	/** 自增长id */
	@TableId(type = IdType.AUTO)
 	private Integer id;
	/** 系统标识 */
 	private String clientCode;
	/** 数据流向:出(S)/入(R) */
 	private String direction;
	/** 业务主键/applycd */
 	private String keyCode;
	/** 流水号 */
 	private String serialnumber;
	/** 接口名称 */
 	private String interfaceName;
	/** 访问主机地址 */
 	private String remotehost;
	/** 入参 */
 	private String inputParams;
	/** 出参 */
 	private String outputParams;
	/** 开始请求时间 */
 	private Date requestTime;
	/** 收到响应时间 */
 	private Date responseTime;
	/** 耗时:ms */
 	private Integer timeLength;
	/** 调用结果:1,成功;0,失败 */
 	private Integer result;
	/** 备注,发生错误时放入异常信息 */
 	private String remark;
	/** 创建时间 */
 	private Date createTime;
	/** 用户id */
 	private String userId;
};
import org.demo.model.entity.InteractionLog;
import org.cango.midbase.mybatis.CangoBaseMapper;

public interface InteractionLogMapper extends CangoBaseMapper<InteractionLog> {

}
public interface AsyncService {
    /**
     * 异步保存日志
     * @param interLog
     */
    void saveInterLog(InteractionLog interLog);
}


@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {
    @Autowired
    private InteractionLogMapper interLogMapper;

    @Override
    @Async("asyncServiceExecutor")
    public void saveInterLog(InteractionLog interLog) {
        interLogMapper.insert(interLog);
    }
}
异步线程池
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolTaskExecutorConfig {

    @Bean
    public Executor asyncServiceExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(20);
        //配置最大线程数
        executor.setMaxPoolSize(50);
        //空闲时间
        executor.setKeepAliveSeconds(60);
        //配置队列大小
        executor.setQueueCapacity(5000);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix("thread-");
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
}
package org.demo.service.invoke.paycenter.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.cango.base.exception.CangoBusinessException;
import org.demo.config.cache.LocalMapCache;
import org.demo.enums.PayCenterPayChannelEnum;
import org.demo.integration.ChargeBackPaymentRes;
import org.demo.integration.GetQrPayResultResponseModel;
import org.demo.integration.QrResponseModel;
import org.demo.model.dto.req.GetChargeBackResultReq;
import org.demo.model.dto.req.PayReq;
import org.demo.model.dto.req.paycenter.InsPayOrderReq;
import org.demo.model.dto.req.paycenter.PayOrderQueryReq;
import org.demo.model.dto.req.paycenter.QuotationRes;
import org.demo.model.dto.req.paycenter.TradeRefundReq;
import org.demo.model.dto.res.PayRes;
import org.demo.model.entity.CWorkOrderPayment;
import org.demo.model.entity.InteractionLog;
import org.demo.model.entity.quotation.QuotationEntity;
import org.demo.service.invoke.paycenter.PayCenterService;
import org.demo.service.system.AsyncService;
import org.demo.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 支付中心交互
 */
@Service
@Slf4j
public class PayCenterServiceImpl implements PayCenterService {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private AsyncService asyncService;

    @Override
    public ChargeBackPaymentRes queryResult(GetChargeBackResultReq req) {
        AssertsUtil.assertsNull(req.getApplyId(), "applyId不能为空");
        AssertsUtil.assertsNull(req.getClientId(), "clientId不能为空");

        Date start = Calendar.getInstance().getTime();
        JSONObject param = new JSONObject();
        String responseBody = "";
        String remark = null;
        Integer result = 1;

        // 退款结果查询 url
        final String url = "http://xxx.yyy";
        try {
            // 加解密密钥
            final String slatKey = "xxxxx";
            // 签名
            req.setSign(AESUtil.sign(req, slatKey));

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity entity = new HttpEntity(req, headers);

            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
            responseBody = responseEntity.getBody();
            JSONObject st = JSONObject.parseObject(responseBody);
            final String resultCode = st.getString("resultCode");
            final String resultMsg = st.getString("resultMsg");
            JSONObject obj = st.getJSONObject("obj");
            if (!"0000".equals(resultCode)) {
                throw new CangoBusinessException("0004", new Object[]{resultMsg});
            }
            if (obj == null) {
                throw new CangoBusinessException("0004", new Object[]{"接口未返回信息"});
            }
            return JSONObject.parseObject(obj.toJSONString(), ChargeBackPaymentRes.class);
        } catch (Exception e) {
            log.error("【退款结果查询】失败,入参:{}", req, e);
            remark = e.getMessage();
            result = 0;
            throw new CangoBusinessException("0004", new Object[]{"退款结果查询失败:" + remark});
        } finally {
            log.info("【退款结果查询】入参:{}, 出参:{}, 入参明文:{}", param, responseBody, req);

            // 异步写入日志
            InteractionLog interLog = new InteractionLog();
            // 系统标识
            interLog.setClientCode(TARGET_CLIENT_CODE);
            // 数据流向:出(S)/入(R)
            interLog.setDirection("S");
            // 业务主键
            interLog.setKeyCode(req.getApplyId());
            // 流水号
            interLog.setSerialnumber(req.getApplyId());
            // 接口名称
            interLog.setInterfaceName(url);
            // 入参
            interLog.setInputParams(req.toString());
            // 出参
            interLog.setOutputParams(responseBody);
            // 开始请求时间
            interLog.setRequestTime(start);
            Date end = Calendar.getInstance().getTime();
            // 收到响应时间
            interLog.setResponseTime(end);
            int tl = (int) (end.getTime() - start.getTime());
            // 耗时:ms
            interLog.setTimeLength(tl);
            interLog.setRemotehost(CommonUtil.getHost(url));
            // 备注
            if (null != remark && remark.length() > 500) {
                remark = remark.substring(0, 499);
            }
            interLog.setRemark(remark);
            // 调用结果
            interLog.setResult(result);
            interLog.setCreateTime(new Date());
            asyncService.saveInterLog(interLog);
        }
    }
}

posted @ 2023-01-31 15:59  亲爱的阿道君  阅读(346)  评论(0编辑  收藏  举报