【代码优化】PAY:移除 PayClient 缓存,减少复杂性,性能足够(非高频读取)

pull/123/MERGE
YunaiV 2024-07-24 23:03:59 +08:00
parent c0df6eab4e
commit f717c0f9c6
6 changed files with 25 additions and 49 deletions

View File

@ -2,10 +2,12 @@ package cn.iocoder.yudao.framework.web.core.handler;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@ -222,8 +224,17 @@ public class GlobalExceptionHandler {
// 不包含的时候,才进行打印,避免 ex 堆栈过多
if (!IGNORE_ERROR_MESSAGES.contains(ex.getMessage())) {
// 即使打印,也只打印第一层 StackTraceElement并且使用 warn 在控制台输出,更容易看到
StackTraceElement[] stackTrace = ex.getStackTrace();
log.warn("[serviceExceptionHandler]\n\t{}", stackTrace[0]);
try {
StackTraceElement[] stackTraces = ex.getStackTrace();
for (StackTraceElement stackTrace : stackTraces) {
if (ObjUtil.notEqual(stackTrace.getClassName(), ServiceExceptionUtil.class.getName())) {
log.warn("[serviceExceptionHandler]\n\t{}", stackTrace);
break;
}
}
} catch (Exception ignored) {
// 忽略日志,避免影响主流程
}
}
return CommonResult.error(ex.getCode(), ex.getMessage());
}

View File

@ -22,9 +22,9 @@ import java.time.LocalDateTime;
public class PayOrderSyncJob {
/**
* N
* N
*
* 10
* 10
* 10
* 3060
*/

View File

@ -14,22 +14,17 @@ import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.validation.Validator;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
/**
@ -42,25 +37,6 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
@Validated
public class PayChannelServiceImpl implements PayChannelService {
/**
* {@link PayClient} smsClientFactory
*/
@Getter
private final LoadingCache<Long, PayClient> clientCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
new CacheLoader<Long, PayClient>() {
@Override
public PayClient load(Long id) {
// 查询,然后尝试清空
PayChannelDO channel = payChannelMapper.selectById(id);
if (channel != null) {
payClientFactory.createOrUpdatePayClient(channel.getId(), channel.getCode(), channel.getConfig());
}
return payClientFactory.getPayClient(id);
}
});
@Resource
private PayClientFactory payClientFactory;
@ -102,9 +78,6 @@ public class PayChannelServiceImpl implements PayChannelService {
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO)
.setConfig(parseConfig(dbChannel.getCode(), updateReqVO.getConfig()));
payChannelMapper.updateById(channel);
// 清空缓存
clearCache(channel.getId());
}
/**
@ -135,18 +108,6 @@ public class PayChannelServiceImpl implements PayChannelService {
// 删除
payChannelMapper.deleteById(id);
// 清空缓存
clearCache(id);
}
/**
*
*
* @param id
*/
private void clearCache(Long id) {
clientCache.invalidate(id);
}
private PayChannelDO validateChannelExists(Long id) {
@ -202,7 +163,8 @@ public class PayChannelServiceImpl implements PayChannelService {
@Override
public PayClient getPayClient(Long id) {
return clientCache.getUnchecked(id);
PayChannelDO channel = validPayChannel(id);
return payClientFactory.createOrUpdatePayClient(id, channel.getCode(), channel.getConfig());
}
}

View File

@ -23,9 +23,10 @@ public interface PayClientFactory {
* @param channelId
* @param channelCode
* @param config
* @return
*/
<Config extends PayClientConfig> void createOrUpdatePayClient(Long channelId, String channelCode,
Config config);
<Config extends PayClientConfig> PayClient createOrUpdatePayClient(Long channelId, String channelCode,
Config config);
/**
* Class PayClient

View File

@ -71,8 +71,8 @@ public class PayClientFactoryImpl implements PayClientFactory {
@Override
@SuppressWarnings("unchecked")
public <Config extends PayClientConfig> void createOrUpdatePayClient(Long channelId, String channelCode,
Config config) {
public <Config extends PayClientConfig> PayClient createOrUpdatePayClient(Long channelId, String channelCode,
Config config) {
AbstractPayClient<Config> client = (AbstractPayClient<Config>) clients.get(channelId);
if (client == null) {
client = this.createPayClient(channelId, channelCode, config);
@ -81,6 +81,7 @@ public class PayClientFactoryImpl implements PayClientFactory {
} else {
client.refresh(config);
}
return client;
}
@SuppressWarnings("unchecked")

View File

@ -34,7 +34,8 @@ public class WxNativePayClient extends AbstractWxPayClient {
@Override
protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO);
WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO)
.setProductId(reqDTO.getOutTradeNo()); // V2 必须传递 productId无需在微信配置。该参数在 V3 简化,无需传递!
// 执行请求
WxPayNativeOrderResult response = client.createOrder(request);