buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

# 跨系统异步业务调用的第一法则::明确失败才失败

我司企服系统的企业客户实名认证,通过与三方服务商“ebaoquan”的API通信来实现。

ebaoquan系统的企业实名认证接口采用异步处理机制,提供了以下3个关键接口:

  • ①企业实名认证上传:同步的数据请求接口,正常情况下会返回一个唯一的email地址,ebaoquan称之为“账户”。
  • ②企业实名认证状态查询:我司通过此接口主动发起查询,入参是①返回的email地址
  • ③企业实名认证回调:ebaoquan系统完成认证处理后,主动回调我司系统接口。

近期,我司系统频繁出现一个问题: 明明企业实名认证数据是正确的,系统里的认证状态却是“FAILED”。


经分析系统代码 , 发现程序调用②状态查询接口时, ebaoquan 返回的报文是“{"msg":"账户信息不存在:rqxsgo@serviceshare.com", "resultCode":"ACCOUNT_NOT_EXISTS", "success":false}”,其中success=false表示异常或错误,而不巧的是,我司程序将这个错误解读成了“认证失败”,将认证记录的认证状态设置成了“FAILED”。

进一步分析程序日志,发现,在调用之后的3~4s,ebaoquan侧 会主动回调我司系统,通知我们“认证通过”。而由于状态锁拦截,认证记录的状态无法再次变更。

责任归属与技术反思

问题核心在于接口②的异常返回逻辑:

  1. ebaoquan 系统问题
  • 在数据未完成处理时返回ACCOUNT_NOT_EXISTS不合理
  • 正确设计:应返回PROCESSINGPENDING状态
  1. 我司程序缺陷 - 将非明确失败视为业务失败
if (!response.isSuccess()) {
    authRecord.setStatus(AuthStatus.FAILED); // 立即标记失败
    authRecord.update();
}

经验老道的老司机,在未得到明确的失败状态的情况下,是不会将数据置为失败状态的,仅当明确失败时才改为FAILED

解决方案实施

  1. 逻辑修复 - 状态判断优化:

修复后逻辑:仅明确失败时才标记失败

if (isExplicitFailure(response)) { // 明确返回失败时才标记失败
    authRecord.setStatus(AuthStatus.FAILED);
} else if (response.isProcessing()) { // 保持当前状态不变
    log.info("认证处理中,暂不更新状态");
}
  1. 流程优化 - 增加延迟缓冲:

我司的查询机制存在缺陷。程序在调用①企业实名认证上传后立即调用②状态查询接口。ebaoquan系统固然存在缺陷(返回错误),而我司系统这个实现方式,也着实不明智。

业务发起后,需要延迟一段时间再去查询结果。我们研判后改为 延迟2s后再调用②状态查询接口,而不是无脑的立即调用

posted on 2025-06-27 15:00  buguge  阅读(48)  评论(0)    收藏  举报