Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

调用微信接口异常重试逻辑问题 #2098

Closed
foreveryang321 opened this issue Apr 29, 2021 · 1 comment · Fixed by #2122
Closed

调用微信接口异常重试逻辑问题 #2098

foreveryang321 opened this issue Apr 29, 2021 · 1 comment · Fixed by #2122
Milestone

Comments

@foreveryang321
Copy link

foreveryang321 commented Apr 29, 2021

简要描述

调用微信接口响应超时异常,会导致重复调用接口,从而导致重复发送模板消息、客服消息等

模块版本情况

  • WxJava 模块名: weixin-java-mp
  • WxJava 版本号: 4.0.8.B

详细描述

重试逻辑有问题,问题代码

errorCode == -1 时会重试

if (error.getErrorCode() == -1) {
// 判断是否已经超了最大重试次数
if (retryTimes + 1 > this.maxRetryTimes) {
log.warn("重试达到最大次数【{}】", maxRetryTimes);
//最后一次重试失败后,直接抛出异常,不再等待
throw new WxRuntimeException("微信服务端异常,超出重试次数");
}
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try {
log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
Thread.sleep(sleepMillis);
} catch (InterruptedException e1) {
throw new WxRuntimeException(e1);
}
} else {
throw e;
}

请求超时(连接超时、响应超时),WxError.getErrorCode() 默认是 -1

} catch (IOException e) {
log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
throw new WxErrorException(e);
}

public WxErrorException(Throwable cause) {
super(cause.getMessage(), cause);
this.error = WxError.builder().errorCode(-1).errorMsg(cause.getMessage()).build();
}

以下异常定义

// errorCode == -1 
throw new WxErrorException("请先设置WebhookKey");

基于以上代码,可以发现

  • IOException异常会导致重试(猜测这个并不需要重试,会导致响应超时异常也重复调用接口,影响:调用发送模板、发送群推等接口会导致用户收到多条)
  • throw new WxErrorException("异常信息")定义异常会导致重试
  • 微信官方接口返回{"errcode":-1,"errmsg":"system error rid: 60891646-03eed615-7f6889ef"}会重试(猜测实现重试是这个意图)

日志

此处复现的是连接超时导致重试(响应超时也会存在重试问题)

2021-04-29 11:59:20.825 ERROR 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 
【请求地址】: https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=token脱敏
【请求参数】:null
【异常信息】:java.net.SocketException: Connection reset
2021-04-29 11:59:20.827  WARN 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 微信系统繁忙,1000 ms 后重试(第1次)
2021-04-29 11:59:26.836 ERROR 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 
【请求地址】: https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=token脱敏
【请求参数】:null
【异常信息】:java.net.SocketException: Connection reset
2021-04-29 11:59:26.836  WARN 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 微信系统繁忙,2000 ms 后重试(第2次)
2021-04-29 11:59:33.840 ERROR 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 
【请求地址】: https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=token脱敏
【请求参数】:null
【异常信息】:java.net.SocketException: Connection reset
2021-04-29 11:59:33.840  WARN 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 微信系统繁忙,4000 ms 后重试(第3次)
2021-04-29 11:59:42.848 ERROR 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 
【请求地址】: https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=token脱敏
【请求参数】:null
【异常信息】:java.net.SocketException: Connection reset
2021-04-29 11:59:42.848  WARN 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 微信系统繁忙,8000 ms 后重试(第4次)
2021-04-29 11:59:55.866 ERROR 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 
【请求地址】: https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=token脱敏
【请求参数】:null
【异常信息】:java.net.SocketException: Connection reset
2021-04-29 12:00:26.431  WARN 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 微信系统繁忙,16000 ms 后重试(第5次)
2021-04-29 12:01:10.443 ERROR 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 
【请求地址】: https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=token脱敏
【请求参数】:null
【异常信息】:java.net.SocketException: Connection reset
2021-04-29 12:01:10.445  WARN 6517 --- [sync-scheduler1] m.c.w.mp.api.impl.BaseWxMpServiceImpl    : 重试达到最大次数【5】

修复建议

public WxErrorException(String message) {
this(WxError.builder().errorCode(-1).errorMsg(message).build());
}

public WxErrorException(Throwable cause) {
super(cause.getMessage(), cause);
this.error = WxError.builder().errorCode(-1).errorMsg(cause.getMessage()).build();
}

初始化默认值-1,改成其他(比如-99、-10000等),保证不和微信接口官方返回错误码重复即可

@binarywang
Copy link
Member

欢迎自行修复,如果测试没问题,直接提交PR即可

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants