springcloud组件之Gateway:服务的统⼀⼊⼝
微服务避免直接暴露地址,需要⼀个统⼀⼊⼝进⾏隔离,增强服务调⽤的安全性。
Spring Cloud Gateway基于Filter链提供⽹关基本功能:安全、监控/埋点、限流等。
Spring Cloud Gateway为微服务架构提供简单、有效且统⼀的API路由管理⽅式。
Spring Cloud Gateway是替代Netflix Zuul(Zuul处于维护状态,不再进⾏新功能的开发)的⼀套解决⽅案,spring官⽅推荐我们,如果要⽤到⽹关的话使⽤Gateway代替Zuul.
Spring Cloud Gateway组件的核⼼是⼀系列的过滤器,通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。
Spring Cloud Gateway是加在整个微服务最前沿的防⽕墙(过滤)和代理器(路由),隐藏微服务结点IP端⼝信息,从⽽加强安全保护。Spring Cloud Gateway本⾝也是⼀个微服务,需要注册到Eureka服务注册中⼼,根据服务的名称,去Eureka注册中⼼查服务对应的所有实例列表,然后进⾏动态路由
微服务网关和注册中心区别Gateway加⼊后的架构
不管是来⾃于客户端(PC或移动端)的请求,还是服务内部调⽤,⼀切对服务的请求都可经过⽹关,然后再由⽹关来实现鉴权、动态路由等等操作。Gateway就是我们服务的统⼀⼊⼝。
核⼼概念
1、路由(routes)路由信息的组成:由⼀个ID(可以随意写)、⼀个⽬的URL、⼀组断⾔⼯⼚、⼀组Filter组成。如果路由断⾔为真,说明请求URL和配置路由匹配。
2、断⾔(Predicate) Spring Cloud Gateway中的断⾔函数输⼊类型是Spring 5.0框架中的ServerWebExchange。Spring Cloud Gateway的断⾔函数允许开发者去定义匹配来⾃于Http Request中的任何信息⽐如请求头和参数。
3、过滤器(Filter)⼀个标准的Spring WebFilter。 Spring Cloud Gateway中的Filter分为两种类型的Filter,分别是Gateway Filter(局部过滤器)和Global Filter(全局过滤器)。过滤器Filter将会对请求和响应进⾏修改处理
路由、断⾔、过滤器如下:
Spring
cloud:
gateway:
routes: #路由
# 路由id,可以随意写
- id: user-service-route
# 代理的服务地址;lb表⽰从eureka中获取具体服务
uri: lb://user-service
# 路由断⾔,可以配置映射路径
predicates: #断⾔
- Path=/**
filters: #当前路由下的局部过滤器
# 添加请求路径的前缀
-
PrefixPath=/user
⽹关的核⼼功能是:路由和过滤
路由routes
快速⼊门
1、新建maven⼯程
2、添加依赖:spring-cloud-starter-gateway、spring-cloud-starter-netflix-eureka-client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
3、编写启动类。注意添加注解@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
4、编写配置⽂件
server:
port: 10010
spring:
application:
name: api-gateway
eureka:
client:
service-url:
defaultZone: 127.0.0.1:10086/eureka,127.0.0.1:10087/eureka
instance:
prefer-ip-address: true
5、编写路由规则,需要⽤⽹关来代理 user-service 服务,先看⼀下控制⾯板中的服务状态:
修改l ⽂件为:
server:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
# 路由id,可以随意写
- id: user-service-route
# 代理的服务地址
uri: 127.0.0.1:9091
# 路由断⾔,可以配置映射路径
predicates:
- Path=/user/**
eureka:
client:
service-url:
defaultZone: 127.0.0.1:10086/eureka,127.0.0.1:10087/eureka
instance:
prefer-ip-address: true
id前的-表⽰多个的意思。path=/user/**表⽰路径中包含user的话,全部转到9091这台机器
注意Zuul⽹关的配置与Gateway不⼀样:
zuul:
routes:
manage-course: # 路由名称,名称任意,保持所有路由名称唯⼀
path: /course/**
serviceId: xc-service-manage-course #微服务名称,⽹关会从eureka中获取该服务名称下的服务实例的地址
# 例⼦:将请求转发到localhost:31200/course
#url: www.baidu #也可指定url,此url也可以是外⽹地址\
strip-prefix: false #true:代理转发时去掉/course/**的前缀,false:代理转发时不去掉/course/**的前缀
sensitiveHeaders: #默认zuul会屏蔽cookie,cookie不会传到下游服务,这⾥设置为空则取消默认的⿊名单,如果设置了具体的头信息则不会传到下游服务
# ignoredHeaders: 默认为空表⽰不过虑任何头
6、启动测试
⾯向(多个实例的)服务的路由
在刚才的路由规则中,把路径对应的服务地址写死了!如果同⼀服务有多个实例的话,这样做显然不合理,可以通过配置动态路由解决。应
修改映射配置,通过服务名称获取
# 代理的服务地址;lb表⽰从eureka中获取具体服务。LoadBalance的缩写
lb://user-service
路由配置中uri所⽤的协议为lb时(以uri: lb://user-service为例),gateway将使⽤ LoadBalancerClient把
user-service通过eureka解析为实际的主机和端⼝,并进⾏ribbon负载均衡。
路由的过滤器添加前缀(添加前缀过滤器PrefixPath)PrefixPath
GatewayFilter Factory
当客户端的请求地址和微服务的服务地址不⼀致的时候,可以通过配置过滤器实现前缀的添加与去除。
可以对请求到⽹关服务的地址添加或去除前缀。有些时候客户端的请求地址与微服务中的服务地址路径并不⼀定是⼀样的,那么可以在⽹关路由请求地址的时候,可以通过配置过滤器来实现对路径的调整。
在gateway中可以通过配置路由的过滤器PrefixPath,实现映射路径中地址的添加;修改l ⽂件:
spring:
cloud:
gateway:
routes:
# 路由id,可以随意写
- id: user-service-route
# 代理的服务地址
uri: lb://user-service
# 路由断⾔,可以配置映射路径
predicates:
- Path=/**
filters:
- PrefixPath=/user
注意:PrefixPath中两个P均为⼤写
也就是:(访问⽹关,通过⽹关将客户端发送的请求转发(路由)到对应的微服务)
路由的过滤器去除前缀(去除前缀过滤器StripPrefix)StripPrefix
GatewayFilter Factory
在gateway中可以通过配置路由的过滤器StripPrefix,实现映射路径中地址的去除;修改l ⽂件:
spring:
cloud:
gateway:
routes:
# 路由id,可以随意写
- id: user-service-route
# 代理的服务地址
uri: lb://user-service
# 路由断⾔,可以配置映射路径
predicates:
- Path=/api/user/**
filters:
# 1表⽰过滤1个路径 2表⽰过滤两个路径,依次类推
- StripPrefix=1
断⾔中path会多⼀个路径,当路径中有/api/user时,则会执⾏这个路由。即⼀个请求到⽹关服务,先根据断⾔中path来判断这个地址能不能进⼊这个路由,如果可以,则再经过过滤器,最后代理到uri指定的地址。
通过 StripPrefix=1 来指定了路由要去掉的前缀个数。如:路径 /api/user/1 将会被代理到 /user/1 。
也就是:
过滤
过滤器类型:
Gateway实现⽅式上,有两种过滤器;
1. 局部过滤器:通过 spring.utes.filters 配置在具体路由下,只作⽤在当前路由上;⾃带的过滤器都可以配置或者⾃定义按照⾃带过滤器的⽅式。如果配置spring.cloud.gateway.default-filters 上会对所有路由⽣效也算是全局的过滤器;但是这些过滤器(局部过滤器和default-filters)的实现上都是要实现GatewayFilterFactory接⼝。
2. 全局过滤器:不需要在配置⽂件中配置,作⽤在所有的路由上;实现GlobalFilter接⼝即可。
Gateway作为⽹关的其中⼀个重要功能,就是实现请求的鉴权。⽽这个动作往往是通过⽹关提供的过滤器来实现的。前⾯的路由前缀章节中的功能也是使⽤过滤器实现的。
Gateway⾃带过滤器有⼏⼗个,常见⾃带过滤器有:
局部过滤器:
局部过滤器都实现实现GatewayFilterFactory接⼝,该接⼝有⼀个抽象类AbstractGatewayFilterFactory,故局部过滤器可以继承该抽象类。所有局部过滤器如下:
1、局部过滤器----(也算全局)默认过滤器(default-filters)
默认过滤器对所有路由都⽣效,也算是全局过滤器,
这些⾃带的过滤器可以和使⽤路由前缀章节中的⽤法类似,也可以将这些过滤器配置成不只是针对某个路由;⽽是可以对所有路由⽣效,也就是配置默认过滤器:
If you would like to add a filter and apply it to all routes you can use spring.cloud.gateway.default-filters. This property takes a list of filters spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
- PrefixPath=/httpbin
本项⽬实例如下:
spring:
cloud:
gateway:
routes:
# 路由id,可以随意写
- id: user-service-route
# 代理的服务地址
uri: lb://user-service
# 路由断⾔,可以配置映射路径
predicates:
- Path=/api/user/**
filters:
# 1表⽰过滤1个路径 2表⽰过滤两个路径,依次类推
- StripPrefix=1
default-filters:
# 添加响应头过滤器,对输出的响应设置其头部属性名称为X-Response-Default-MyName,值为zwh;
#如果有多个参数多则重写⼀⾏设置不同的参数
- AddResponseHeader=X-Response-Default-MyName, zwh
- AddResponseHeader=X-Response-Default-Mywf, xpp
2、局部过滤器(只作⽤在当前路由上)
1)、AddRequestHeader GatewayFilter Factory
The AddRequestHeader GatewayFilter Factory takes a name and value parameter.
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri:
filters:
- AddRequestHeader=X-Request-Foo, Bar
This will add X-Request-Foo:Bar header to the downstream request’s headers for all matching requests.
2)、AddRequestParameter GatewayFilter Factory
The AddRequestParameter GatewayFilter Factory takes a name and value parameter.
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri:
filters:
- AddRequestParameter=foo, bar
This will add foo=bar to the downstream request’s query string for all matching requests.
3)、AddResponseHeader GatewayFilter Factory
The AddResponseHeader GatewayFilter Factory takes a name and value parameter.
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri:
filters:
- AddResponseHeader=X-Response-Foo, Bar
This will add X-Response-Foo:Bar header to the downstream response’s headers for all matching requests.
4)、RemoveRequestHeader GatewayFilter Factory
The RemoveRequestHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed.
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri:
filters:
- RemoveRequestHeader=X-Request-Foo
This will remove the X-Request-Foo header before it is sent downstream.
5)、RemoveResponseHeader GatewayFilter Factory
The RemoveResponseHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed.
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri:
filters:
- RemoveResponseHeader=X-Response-Foo
This will remove the X-Response-Foo header from the response before it is returned to the gateway client.
To remove any kind of sensitive header you should configure this filter for any routes that you may want to do so. In addition you can configure this filter once using spring.cloud.gateway.default-filters and have it applied to all routes.
6)、RequestSize GatewayFilter Factory
The RequestSize GatewayFilter Factory can restrict a request from reaching the downstream service , when the request size is greater than the permissible limit. The filter takes RequestSize as parameter which is the permissible size limit of the request defined in bytes.
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
The RequestSize GatewayFilter Factory set the response status as 413 Payload Too Large with a additional header errorMessage when the Request is rejected due to size. Following is an example of such an errorMessage .
errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
The default Request size will be set to 5 MB if not provided as filter argument in route definition.
Gateway的Filter的执⾏⽣命周期
Spring Cloud Gateway 的 Filter 的⽣命周期也类似Spring MVC的有两个:“pre” 和 “post”。“pre”和 “post” 分别会在请求被执⾏前调⽤和被执⾏后调⽤
这⾥的 pre 和 post 可以通过过滤器的 GatewayFilterChain 执⾏filter⽅法前后来实现。
使⽤场景
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论