当前位置: 代码迷 >> 综合 >> HttpRetryException: cannot retry due to redirection, in streaming mode
  详细解决方案

HttpRetryException: cannot retry due to redirection, in streaming mode

热度:21   发布时间:2023-12-12 11:43:29.0

错误栈

2021-07-30 16:56:09.979 ERROR 18697 --- [nio-8000-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.RetryableException: cannot retry due to redirection, in streaming mode executing POST http://gulimall-order/order/order/listWithItem] with root causejava.net.HttpRetryException: cannot retry due to redirection, in streaming mode

今天openFeign调用一个服务的时候发生这个问题,没有详细的提示,网上也是各种解决办法,不唯一不典型,只能debug进入各个节点看问题。
先捋一下 远程调用的执行过程
1、浏览器发送http请求(携带请求头)
2、进过本地host 路由至虚拟机80端口的nginx
3、nginx负载均衡至88端口的网关服务
4、网关将请求派送至指定服务,再根据携带的请求头 到指定路径处理请求

在请求入口,远程调用开始的地方和远程方法的具体实现打上断点
在这里插入图片描述
在这里插入图片描述
发现无法进入远程实现就抛出了异常,判断是拦截器中抛出了异常

在拦截器中打上断点,发现远程获取session时出现了错误,且session值也与页面存储的不一至。所以获取不到登陆信息。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
这是由于 feign 的远程调用丢失请求头问题,debug feign 的远程发起源码

debug feign源码的全过程与step_into节点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
发现源码中 一直在构建一个 请求模版 template ,这是feign用于发起远程调用的模版,其中 Cookie 的请求一直空,且在最后一步循环requestInterceptors时也没有加入任何模版,所以问题出在这里,没有将Cookie加入template的请求头中,导致远程调用无法获取到 session 值(之前的session值可是是feign自己生成的)。

解决办法 往容器中添加自定义的 requestInterceptor 以增强 template ,上面有说,feign会循环容器中的 requestInterceptor 将其都 apply 进template中。

@Configuration
public class GuliFeignConfig {
    @Bean("requestInterceptor")public RequestInterceptor requestInterceptor() {
    return new RequestInterceptor() {
    @Overridepublic void apply(RequestTemplate template) {
    //1、拿到刚进来的这个老请求ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes != null) {
    System.out.println("RequestInterceptor线程。。。" + Thread.currentThread().getId());HttpServletRequest request = attributes.getRequest();//老请求if (request != null) {
    //同步请求头信息,cookietemplate.header("Cookie", request.getHeader("Cookie"));//给新请求同步老请求的cookieSystem.out.println("feign远程之前先这里 apply 方法");}}}};}
}

再次debug,请求头中已经有Cookie 头 ,问题解决
在这里插入图片描述

  相关解决方案