定义
网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。
作用
- 路由转发:接收一切外界请求,转发到后端的微服务上去。
- 过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等。
为什么需要网关?
- 网关可以实现服务的统一管理。
- 网关可以解决微服务中通用代码的冗余问题(如权限控制,流量监控,限流等)。
网关在微服务中的架构
Gateway组件
1. 说明
这个项目提供了一个在Spring MVC之上构建API网关的库。Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为API提供横切关注点。比如:安全性、监控/度量和弹性。
2. 特性
- 基于Spring Boot
2.x
,Spring WebFlux和Reactor构建 - 响应式异步非阻塞IO模型
- 动态路由
- 请求过滤
Gateway动态路由开发
在Gateway中,可以使用配置文件或者配置类来配置动态路由。由于Spring Cloud官方推荐使用配置文件的方式配置动态路由,所以本文不再讲述使用配置类配置动态路由的方式。
1. 配置网关定向访问
-
创建独立的gateway模块。
-
将模块注册入服务注册中心(本文以Consul为注册中心)。
-
模块引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
-
模块编写网关配置
spring: application: name: gateway cloud: # consul配置 consul: ... # gateway配置 gateway: routes: # 路由唯一标识 - id: product_route # 路由访问地址 uri: http://localhost:9001/ # 路由匹配规则 predicates: - Path=/product/** - id: user_route uri: http://localhost:9002/ predicates: - Path=/user/**
-
通过访问 http://网关ip:网关port/Path ,网关会根据配置文件自动跳转到 uri/Path,从而访问不同服务中的接口。
注意:
-
当引入
spring-cloud-starter-gateway
依赖时,同时引入spring-boot-starter-web
依赖,那么项目会启动失败。因为Gateway是基于Spring WebFlux开发的,而Spring WebFlux底层封装了Spring MVC。如果同时引入两个依赖,那么会导致冲突。所以在使用Gateway组件时,必须移除spring-boot-starter-web
依赖。 -
gateway服务不引入common服务。因为common服务中配置了
spring-boot-starter-web
依赖,所以还需要手动配置consul等。 -
在配置路由中
predicates: - Path=/product/**
这种配置为yml文件中集合(字符串数据)配置方式,原型为
predicates: [Path=/product/**]
这里的
**
代表多级路径匹配。 -
在配置路由中
routes: - id: product_route uri: http://localhost:9001/ predicates: - Path=/product/** - id: user_route uri: http://localhost:9002/ predicates: - Path=/user/**
这种配置为yml文件中集合(对象数据)配置方式,原型为
routes: [ { id: product_route, uri: http://localhost:9001/, predicates: [Path=/product/**] }, { id: user_route, uri: http://localhost:9002/, predicates: [Path=/user/**] } ]
2. 配置网关负载均衡访问
-
创建gateway模块,注册,引入依赖。
-
网关配置
spring: application: name: gateway cloud: # consul配置 consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name} # gateway配置 gateway: routes: - id: product_route uri: lb://products predicates: - Path=/product/** - id: user_route uri: lb://users predicates: - Path=/user/** discovery: # 开启根据服务名动态获取路由 locator: enabled: true
注意:
-
在配置网关中
uri: lb://products
lb:网关使用负载均衡策略进行服务访问。
products:表示注册中心具体服务名。
解决Gateway跨域问题
在前后端分离的项目中,如果原先使用的是nginx做反向代理和负载均衡,那么只把nginx停掉和按照上述步骤配置gateway会产生跨域问题。
因为Gateway使用的是webflux,而不是springmvc,所以后端原本配置的@CrossOrigin已经解决不了跨域问题了。需要先关闭webflux的cors,再从gateway的filter里边配置cors即可。
-
在前端将nginx地址改为gateway地址
-
去掉后端所有controller上的@CrossOrigin注解
-
配置Gateway服务中的application.yml
spring: application: name: afterlives-gateway cloud: # consul配置 consul: ... # gateway配置 gateway: routes: ... discovery: ... # 配置跨域 globalcors: corsConfigurations: '[/**]': allowedHeaders: "*" allowedOrigins: "*" allowedMethods: - GET POST DELETE PUT OPTION
-
在Gateway服务中创建config包,创建CorsConfig类
// gateway跨域 @Configuration public class CorsConfig { @Bean public CorsWebFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedMethod("*"); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source); } }
查看网关路由规则列表
Gateway提供路由访问规则列表的web界面,但是默认是关闭的。如果想要查看服务路由规则可以在配置文件中开启。
-
网关模块开启所有web端点(其中包括Gateway暴露的端点)
management: endpoints: web: exposure: include: "*"
-
如果注册中心使用的是Nacos,则还需在Gateway中添加如下配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
访问路由管理列表地址:http://网关ip:网关port/actuator/gateway/routes