feign.RetryableException null executing post

本文探讨了在使用Feign进行微服务间调用时遇到的RetryableException问题,具体表现为null executing GET请求。问题源于webservice客户端请求携带了'chunked'编码的header,导致Spring Cloud在转发请求时引发错误。解决方案是通过实现Feign的RequestInterceptor,移除或处理掉'chunked'编码的header,确保内部feign调用正常。

feign调用遇到的问题,该文为转载,记录一下

feign.RetryableException: null executing GET http://****/cr**t/e**/cre****ount/2**8060
at feign.FeignException.errorExecuting(FeignException.java:132)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:113)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
at com.sun.proxy.$Proxy189.getCustomerCredit4Ebs(Unknown Source)
at com.crpt.biz.service.impl.ebs.QueryCustomeCreditService.execute(QueryCustomeCreditService.java:56)
at com.crpt.biz.service.impl.ebs.QueryCustomeCreditService.execute(QueryCustomeCreditService.java:23)
at com.crpt.biz.ebs.webservice.CrptEBSService.request(CrptEBSService.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.performInvocation(JAXWSMethodInvoker.java:66)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.invoke(AbstractJAXWSMethodInvoker.java:232)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:85)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:74)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)

CXF能够正常接入数据,但是接入后调用微服务内部的feign报错

原因webservice客户端请求时,携带了这个header信息:transfer-encoding:chunked

而springcloud会把请求过来的http header信息转嫁给下一次发生调用的feign中,源码详见feign.SynchronousMethodHandler#targetRequest

这样就需要我们定值一个RequestInterceptor去简化一下header

@Component
@Slf4j
public class FeignRequestInterceptor implements RequestInterceptor {
final static String TRANSFER_ENCODING = "transfer-encoding";
@Override
public void apply(RequestTemplate requestTemplate) {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    if(attributes==null)
        return ;
    HttpServletRequest request= attributes.getRequest();
    Enumeration<String> headerNames = request.getHeaderNames();
    if (headerNames != null) {
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String values = request.getHeader(name);
            if(isOverLapHeader(requestTemplate,name))
                requestTemplate.header(name, values);
        }
    }
}
//是否允许覆盖requestTemplate中的header
private boolean isOverLapHeader(RequestTemplate requestTemplate,String headerName)
{
    Map<String, Collection<String>> headers= requestTemplate.headers();
  	  if(headers==null)
    {
        return true;
    }
    if (TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
        return false;
    }
    return true;

}

这样内部的feign调用时就不会有问题了

原文链接:https://juejin.cn/post/6964174845051404302#comment

Feign 是一个声明式的 Web 客户端,广泛用于 Spring Cloud 微服务架构中进行服务间通信。当遇到 `feign.RetryableException: too many bytes written executing` 异常时,通常表示 Feign 在执行请求过程中遇到了底层 I/O 问题,特别是在使用默认的 JDK `HttpURLConnection` 作为 HTTP 客户端时较为常见。 ### 常见原因 1. **底层 HTTP 客户端限制**:Feign 默认使用的是 `HttpURLConnection`,它在处理大请求或响应体时存在性能和稳定性问题,容易导致连接异常。 2. **缓冲区溢出或流写入过多数据**:当请求体过大、上传内容未正确分块传输(chunked transfer),或服务器端提前关闭连接时,可能引发此异常。 3. **网络不稳定或超时**:如果服务调用链路中的网络出现波动或响应时间过长,也可能导致写入失败。 ### 解决方案 #### 使用 Apache HttpClient 或 OkHttp 替代默认客户端 推荐将 Feign 的底层客户端更换为功能更强大且更稳定的 `HttpClient` 或 `OkHttp`,以提升稳定性和兼容性。以下是使用 `HttpClient` 的配置方式: ##### 1. 添加依赖 ```xml <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> ``` 该依赖会引入 `HttpClient` 并将其设置为 Feign 的默认 HTTP 客户端 [^2]。 ##### 2. 配置 Feign 使用 HttpClient 在 `application.yml` 中启用 Feign 客户端配置: ```yaml feign: client: config: default: http-client: org.apache.http.impl.client.HttpClients ``` 或者通过 Java 配置类显式指定: ```java import feign.Client; import feign.httpclient.ApacheHttpClient; import org.apache.http.impl.client.HttpClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignClientConfig { @Bean public Client feignClient() { return new ApacheHttpClient(HttpClients.createDefault()); } } ``` #### 调整 Feign 请求参数 对于大请求体或文件上传场景,可以调整以下参数以避免缓冲区问题: ```yaml feign: request-interceptors[0]: com.pojo.common.core.config.FeignConfig retryer: feign.Retryer.Default logger-level: full ``` 同时确保 `FeignConfig` 中的拦截器逻辑无误,如传递 Header 等操作不会导致额外的数据写入异常 [^3]。 #### 检查网络与服务端行为 - 确保目标服务能够正确接收并处理请求体。 - 查看服务端日志,确认是否因请求体过大而拒绝处理。 - 设置合理的超时时间,防止长时间等待导致连接中断。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值