解决微服务前后端分离过程中的映射Gateway网关路径问题
一、问题背景
在前后端分离项目中,由于前端Vue项目和后端框架是分离的,因此常常出现路径转发问题。如果后端有几个服务,前端往往需要在路由代理中配置N多个路径,这样在前端Vue项目打包发布到Nginx上面时,需要配置N多个代理转发,十分不方便,增加了维护成本。
随着SpringCloud网关概念的出现,很好地解决了这个问题。前端只需要配置到网关的映射,其它路径转发只需要加上网关的前缀加上网关项目的代理路径,十分方便。上线Nginx也只需要配置到网关路径的代理转发,减少了维护成本。
二、技术调研
Spring Cloud大家族生态圈中,在Spring Boot 1.X的系列中,都使用的是Zuul,起到了Nginx的路径转发功能。
随着Spring Cloud 2.X的兴起,以及Zuul的停止更新和维护,Spring Cloud Gateway逐渐占据了网关产品的头把交椅。
在阿里的微服务Nacos系列Open Cloud框架中更是对Spring Cloud Gateway做成了可视化配置,直接在页面添加动态路由和代理。
2.1Spring Cloud Gateway能做什么
【1】第一个能实现的功能就是反向代理
【2】可以利用Spring Cloud Gateway进行鉴权,配置网关接口权限
【3】可以进行流量控制
【4】能够进行隔离、触发熔断机制,降级
【5】可以进行日志的操作
三、配置项目
3.1引入Maven坐标
这样项目里面就引入了Spring Cloud Gateway
3.2静态配置方式
配置静态绝对路径
当启动网关工程时:/luoyun就指向了http://sports.163.com
这里配置的是绝对地址,静态路由
后端服务真实ip路径:http://sports.163.com
前端Vue通过访问网关/luoyun就指向了后端的真实路径地址
当在浏览器输入:http://127.0.0.1:9527/luoyun
访问了页面:
3.3动态路由
当接入Eureka注册中心之后,Spring Cloud Gateway就可以配置动态路由,映射到注册中心的模块就可以配置动态路由了。
Spring Cloud Gateway接入注册中心:
Eureka注册中心:
上面的这些服务都接入注册中心了
网关里面可以配置动态路由:
然后网关地址:/auth/**就指向了hxms-auth这个服务的地址,前端Vue请求映射路径为:网关代理/auth/**就能请求hxms-auth服务
/admin/**指向了hxms-upms-biz这个服务,前端Vue请求映射路径为:网关代理/admin/**就能请求hxms-upms-biz服务
3.4编码方式配置路由
编码方式配置路由地址
这种方式要修改Java源代码,不推荐使用
3.5解决网关跨域问题
针对网关Spring Cloud Gateway跨域问题,前端配置代理可以解决,或者后端解决。后端解决的方式:
只需要把这代码加到启动类:
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (!CorsUtils.isCorsRequest(request)) {
return chain.filter(ctx);
}
HttpHeaders requestHeaders = request.getHeaders();
ServerHttpResponse response = ctx.getResponse();
HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
if (requestMethod != null) {
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
}
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALL);
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
return chain.filter(ctx);
};
}
这样解决了跨域问题
四、总结
Spring Cloud Gateway减轻了前后端分离项目中多项目请求的路径问题,减少了路径转发的问题,减轻了维护压力,也为大家创造了良好的环境。
建议大家看下阿里Nacos系列的Open Cloud框架,动态可配置界面可视化路由,十分方便。