RPC调用异常行为与处理方案总结

背景

在使用IAcsClient或者dubbo进行rpc调用时, 异常情况总是不可避免的.
这里总结下各种异常, 以及对应的表现形式与处理方式.

异常总结

错误分类 错误细分 IAcsClient Dubbo
客户端异常 客户端网络无连接, 闪断等
  • IAcsClient 抛出ClientException异常
    com.aliyuncs.exceptions.ClientException: SDK.ServerUnreachable : Server unreachable: connection
    |
  • 抛出RpcException异常:

|
| | SDK参数缺失错误等 |

  • IAcsClient 抛出ClientException异常
    com.aliyuncs.exceptions.ClientException: SDK.InvalidProfile : No active profile found.
    |
  • 不会有该场景, 因为dubbo调用没有SDK
    |
    | 服务端异常 | 服务端限流, 处理超时 |
  • IAcsClient 抛出ServerException异常
    | |
    | | 业务异常, 例如请求参数错误, SPOT价格设置过低等 |
  • IAcsClient 抛出ClientException异常
  • 注意ServerException是ClientException的子类
    |
  • 不抛异常, 返回 PlainResult isSuccess=false; data=null; message != null

    |
    | | 服务端未提供该服务 |

    • IAcsClient抛出ClientException异常
      com.aliyuncs.exceptions.ClientException: InvalidVersion : Specified parameter Version is not valid.
      RequestId : xxx
      
      com.aliyuncs.exceptions.ClientException: InvalidAction.NotFound : Specified api is not found, please check your url and method.
      RequestId : xxx
      |
    • 抛出RpcException异常:
      com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method xxx in the service xxx. No provider available for the service xxx from registry xxx
      |
      | 其他异常 | | IAcsClient正常返回. 返回对象里:
      AcsResponse有requestId, 但返回结果为空, success=false
      啥时候会有这种异常? | |

    异常处理

    IAcsClient异常处理

    所以针对IAcsClient, 可以按照如下方式进行异常处理:

    try {
        ecsInnerClient.getAcsResponse(req);
    }
    catch (ServerException e) {
         // client调用超时, 被服务端限流等, 都会抛出异常, 走到这里, 需要后续降级到库存缓存实现.
         listResourceResponse.setSuccess(Boolean.FALSE);
         log.error("DescribeResourceAllocation ServerException. request: {}", JSON.toJSONString(req), e);
     } catch (ClientException e) {
         // SPOT价格不满足, 客户端传入参数有错误, 等业务异常, 走到这里, 无需后续降级到库存缓存实现.
         listResourceResponse.setSuccess(Boolean.TRUE);
         log.error("DescribeResourceAllocation ClientException. request: {}", JSON.toJSONString(req), e);
     }