最近定位一个以前没有注意到的奇葩问题。在系统开发过程中,在测试环境有些人反馈偶尔会出现请求应用时会重定向到后端业务微服务地址,而且还不是必现问题,有点棘手。

    当前系统请求流如下:

    Request --> NGINX ---> ZUUL --> Business Micro Service

    即页面请求先到达暴露出来的反向代理服务器NGINX,NGINX将请求转发到ZUUL,ZUUL网管又将请求转发到实际需要处理的业务微服务。

    问题的现象是在浏览器地址栏中输入请求地址(NGINX地址),页面会重定向到Business Micro Service实际的地址,而该地址不应该暴露出来。

     通过浏览器调试模式下看到的请求重定向如下:

    

  为什么请求会重定向呢?哪个环节进行的重定向呢?

  Request首先经过NGINX,但是NGINX不知道具体的业务微服务地址,NGINX配置的ZUUL的地址,故NGINX配置问题应该可以排除。

  经过NGINX到ZUUL,ZUUL通过Eureka能够获取到具体的业务微服务地址,故ZUUL存在重新向的嫌疑。

  通过查看ZUUL官方文档,发现如下这段话:

  

       ZUUL作为前端web应用,如果响应码为3XX时请求进行重定向的情况需要重写Request请求Header中的Location,对于这种情况可以配置LocationRewriteFilter Bean,会将Location设置为ZUUL的地址。

     我们按照文档描述,定义了LocationRewriteFilter后,系统就可以了,以为这样就完美解决了。可能乐极生悲吧,后续系统功能开发过程中,发现重定向到其他系统时,系统发生了异常,重定向不过去。这时想起了文档中的Caution,某些场景不支持呀。

    文档中特别提醒这种重写Location方式,不适合所有的场景,如重写向地址是外部应用地址,这时重定向会报错,不能达到业务预期。

    问题又回到了起点。。。

    再沉下心,不断分析,认为ZUUL应该也不是导致请求重定向的原因,因为如果是ZUUL的话,所有的请求都经过ZUUL了,所有请求都应该被重定向呀。

    通过排除法,现在唯一可能就只剩下应用自己进行重定向了。

    经过不断的F5刷页面,查看请求的变化,偶然注意到请求的地址与重定向的地址不仅仅IP与端口变化了,后面请求的服务路径也有区别,我们请求的地址为http://localhost:21000/business,而重定向Location地址为http://localhost:20001/business/,服务后面居然多了一个反斜杠(/)。

    这时才突然想起,如果只输入context-path时应用服务器会重定向到context-path/,然后自动将index.html内容返回,进行页面加载渲染。

    想明白了这个问题以后,问题的解决方法也就出来了,既然最后端的业务微服务请求需要context-path/加载页面,那我们就把重定向前移就可以解决这个问题。

    于是在NGINX中增加了如下配置: 

rewrite ^/business$ /business/ redirect;

    这样NGINX对于请求Portal服务时如果缺少了反斜杠(/)就自动重定向了,避免最后端微服务请求自己重定向把服务地址暴露出来了。

     这种提前处理也可以放到ZUUL中,自定义过滤器进行请求拦截重定向。

     历时一周多的问题到此终于解决。反思一下,如果不是粗心,只关注最大的变化而忽略了细微的变化,所以在后续的开发中,不要轻易让表象蒙蔽,小心驶得万年船呀~~

    本应该快速解决的问题,却由于没有抓到问题的本质,导致问题迟迟不能解决,实属不该。

    浪费时间,就是浪费生命呀,血一般的教训,一个反斜杠(/)引起的血案~~

   

    

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐