Apache HttpClient 4.5.x 学习总结六:Exception handling(异常处理)

以下是对HTTP异常处理内容的翻译、知识点提炼及通俗解释:

通俗解释:

场景类比:网购订单系统

  1. 异常类型

    • 网络抖动(IOException) → 快递员联系不上你(可重试)
    • 协议错误(HttpException) → 填错收货地址(需人工修正)
  2. 幂等性重要性

    • 你点击"付款"但网络卡顿 → 重复提交 → 幂等设计
      ✅ 生成唯一订单号 → 即使重复提交也只扣款1次
      ❌ 无幂等设计 → 可能扣款多次
  3. 自动重试规则

    • 快递员发现:
      未发货时运输车故障 → 换车重发(类似GET请求重试)
      已发货后包裹丢失 → 不再自动重发(类似POST请求)
  4. 自定义重试策略

    自定义规则 = {
      最多重试5次,
      不重试:超时/SSL错误/主机失联,
      仅重试:查询类请求(不下单的请求)
    }
    

    就像电商平台设置:"对查询库存请求自动重试3次,但支付请求必须人工确认"


翻译:

1.5 异常处理
HTTP处理器抛出两类异常:

  1. IOException:I/O故障(如超时/连接断开),通常可恢复
  2. HttpException:HTTP协议错误(如协议违规),通常致命
    注:HttpClient将HttpException转为ClientProtocolException(IOException子类),方便统一捕获

1.5.1 HTTP传输安全性
HTTP不适于事务型操作:服务器执行请求后即使客户端未完整接收响应(如超时/崩溃),也不会回滚事务。重试请求可能导致:

  • 重复执行事务
  • 数据损坏
  • 状态不一致

1.5.2 幂等方法
幂等性定义:"N>0次相同请求产生的副作用 = 单次请求"
解决方案:

  • 使用唯一事务ID
  • 避免重复执行逻辑操作

默认幂等方法判定:
✅ GET/HEAD(无请求体)
❌ POST/PUT(含请求体)

1.5.3 自动恢复机制

  • 仅自动恢复I/O异常(非协议异常)
  • 自动重试场景:
    1. 幂等方法(如GET)
    2. 请求未完全发出时失败

1.5.4 自定义重试处理器

HttpRequestRetryHandler myRetryHandler = (exception, retryCount, context) -> {
    if (retryCount >= 5) return false; // 最多重试5次
    if (exception 是超时/SSL等错误) return false; // 不重试特定错误
    
    HttpRequest request = HttpClientContext.adapt(context).getRequest();
    // 仅重试幂等方法(非含实体的请求)
    return !(request instanceof HttpEntityEnclosingRequest); 
};

// 应用自定义重试器
CloseableHttpClient httpclient = HttpClients.custom()
        .setRetryHandler(myRetryHandler)
        .build();

提示:可用StandardHttpRequestRetryHandler默认支持RFC定义的幂等方法(GET/HEAD/PUT/DELETE/OPTIONS/TRACE)


核心知识点提炼:

主题 关键点
异常类型 IOException(可恢复) vs HttpException(致命)→转为ClientProtocolException
HTTP事务缺陷 请求执行后不回滚 → 重试导致重复执行 → 需幂等性保障
幂等性 多次执行效果 = 单次执行(GET/HEAD/PUT/DELETE等)
自动恢复 仅重试:1) 幂等方法 2) 请求未完全发出时的I/O错误
重试处理器 通过HttpRequestRetryHandler自定义重试逻辑

关键结论:HTTP协议不是为金融级交易设计的,必须通过幂等性设计+智能重试策略规避数据重复风险。

posted @ 2025-07-24 10:10  hqq的进阶日记  阅读(18)  评论(0)    收藏  举报