一、背景:由于最近在开发的工程中,需要在微服务架构中要加入websocket组件进行前端数据实时刷新功能,最开始项目中利用的时zuul1.x作为网关服务,由于zuul1.x是基于阻塞的,这导致websocket始终无法穿透zuul网关,在找了很多解决方案后,利用了socket.js基本可以解决问题,基于网上的 : https://github.com/mthizo247/spring-cloud-netflix-zuul-websocket 工程,结合他给的dom:https://github.com/mthizo247/zuul-websocket-support-demo 亲自检测使用过,可以使用;但是,又有新问题产生了,每次返回都是返回两次数据,而且,如果zuul中配置了跨域处理,socket.js就出现问了,返回的响应头信息中会出现两层,如下所示:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://**
Access-Control-Allow-Origin:http://**
网上查了很多资料说是因为两边都做了跨域请求就会出现这种情况,总之各种原因吧,socket.js这种方式用起来也很不爽,最终商定的解决方案是用gateway换掉zuul作为服务网关,基于gateway本身就是非阻塞的性质,可以很好的契合websocket。
二、换掉zuul带来的路由配置的问题:
由于zuul与gateway的差异,在路由方面配置有很大的区别,均使用8888作为端口测试;
1、首先贴一下之前利用zuul作为网关时的路由配置:
在test-fa 的congtroller的类中如下路径:
@RestController
@RequestMapping("/queryList")
在zuul的配置中,只要前端调用类似:http://127.0.0.1:8080/fa/queryList
它就会去调用test-fa 中/queryList这个路径;(注意,在RequestMapping中并没有配置fa这个路径,只是单纯的/queryList路径)
2、接下来贴一下gateway的路由配置:
同样在test-fa 的congtroller的类中如下路径:
@RestController
@RequestMapping("/queryList")
在gateway的配置中,前端调用类似:http://127.0.0.1:8888/fa/queryList的时候。此时会报错404找不到路径,当时就觉得怎么会这样,明明就是这样配置的啊;后来各种排查问题;它不是说404么,那么尝试一下在
@RequestMapping("/queryList")中加入/fa,抱着试一试的心态( @RequestMapping("/fa/fueryList") );
再次调用http://127.0.0.1:8888/fa/queryList,就正常调用了;
3、总结:
a、在zuul的路由配置中,path后面不论跟什么参数,只要前端调用路径中包含了这个参数,它就会去找对应的service-id中参数的服务进行调用;如调用:http://127.0.0.1:8888/fa/queryList这个路径,虽然在test-fa工程中的congtroller类的@RequestMapping中m没有包含这个fa参数,如:@RequestMapping("/queryList"),依然可以正确找到对应服务的接口;
b、在gateway的路由配置中,predicates后面跟的参数,如本文中的fa参数。在前端调用http://127.0.0.1:8888/fa/queryList这个路径时,在test-fa工程中的congtroller类的@RequestMapping中必须包含这个fa参数,如:@RequestMapping("/fa/queryList");这样它才能正确找到服务以及对应的接口;
c、但是,gateway也给出了方式,如果要想达到zuul的效果,要在配置的路由后面要加上
filters:
- StripPrefix=1
这样,在访问如:http://127.0.0.1:8888/fa/queryList(@RequestMapping("/queryList"))时,才会自动去掉/fa
4、在使用gateway时,请注意版本间的差异,下面附上springcloud各版本与springboot版本的兼容性图:
经过亲自不断的测试,得出了本文的结论,如有不正确的地方,望不吝指正。