SpringCloud Gateway(一)简单认识
Gateway
背景介绍
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty,Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty运行时,它不能在传统的Servlet容器中工作,也不能作为WAR构建,不能集成spring-boot-starter-web模块,也不能引入内嵌的Tomcat Server。
Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:统一入口,权限校验,限流等。在Gateway中有三大核心概念分别是:路由、断言和过滤器。当客户端向Spring Cloud Gateway发送请求,经由网关处理程序的谓词来决定是否与请求的URL条件匹配,若满足条件则将执行匹配后的过滤器,由过滤器进行请求重载(比如可以更改请求地址;更改Request Header等),包含多个谓词和多个过滤器的一组单元被称为路由;当一个路由中的谓词不满足条件时可以匹配下一组的路由数据(若存在下一组路由),所以它们三者的术语如下:
(1)路由:网关的基本构件。它由一个ID、一个目标URI、一组谓词和一组过滤器定义。如果聚合谓词为真,则匹配路由。
(2)谓词:这是一个Java 8函数谓词。输入类型是Spring Framework ServerWebExchange。这允许您匹配来自HTTP请求的任何内容,例如头或参数。谓词决定了请求是否被匹配,只有被匹配后才能执行局部Filter的请求拦截;
(3)过滤器:这些是使用特定工厂构造的GatewayFilter实例。在这里,您可以在发送下游请求之前或之后修改请求和响应。
简单的来理解:Gateway可以配置多组的路由规则,每一组里面有多个匹配条件(谓词),若同一组的所有条件匹配全部匹配则执行该路由地址的转发,在请求转发时再执行配置的过滤器进行拦截处理。跟Nginx的网关区别在于Gateway可以增加一些自己的Java代码处理逻辑。
(工作原理图)
有两种配置谓词和过滤器的方法:快捷方式和完全展开的参数。名称和参数名称将作为代码列在每个部分的第一个或两个句子中,参数通常按照快捷方式配置所需的顺序列出。
(1)快捷方式表示将参数名和参数值简写,写在同一行当中,使用等号来分割参数名和参数值,参数值部分以“,”来区分多个分割的值(多个值可能存在不同的含义),它们不能再出现特殊字符,如不能再出现“,”等,参考快捷方式的写法为:
(2)完全展开的方式表示将参数名和参数值以数组下标的形式进行单独赋值,具体到具体的参数名和参数值,参数值中可以有特殊的分割符,兼容性更好;
谓词工厂
序号 | 过滤器 | 说明 |
1 | After | 时间后置谓词,表示在此时间之后可匹配,时间格式为标准时间,含时区,参考写法:After=2017-01-20T17:42:47.789-07:00[America/Denver] |
2 | Before | 时间前置谓词,表示在此时间之前可匹配,时间格式为标准时间,含时区,参考写法:Before=2017-01-20T17:42:47.789-07:00[America/Denver] |
3 | Between | 时间区间谓词,表示在此时间范围内可匹配,参考格式:Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver] |
4 | Cookie | Cookie路由谓词工厂接受两个参数,Cookie名称和regexp(这是一个Java正则表达式),参考写法:Cookie=chocolate, ch.p(.表示任意字符) |
5 | Header |
Header路由谓词工厂接受两个参数,头和regexp(正则),该谓词与具有给定名称且值与正则表达式匹配的标头匹配, 如果请求有一个名为X-Request-Id的报头,其值与\d+正则表达式匹配(也就是说,它的值为一个或多个数字),则匹配此路由。 参考写法:Header=X-Request-Id, \d+(若要限定数字的长度,则需要使用完全展开参数的写法) |
6 | Host |
主机路由谓词工厂接受一个参数:主机名模式列表。该模式是ant风格的模式。作为分隔符。此谓词与与模式匹配的Host报头匹配。 参考写法:Host=**.somehost.org,**.anotherhost.org 也支持URI模板变量(例如{sub}.myhost.org)。 |
7 | Method | 方法路由谓词工厂接受一个方法参数,它是一个或多个参数:要匹配的HTTP方法,如:GET/POST/PUT/DELETE等,参考写法:Method=GET,POST |
8 | Path | 路径路由谓词工厂接受两个参数:一个Spring PathMatcher模式列表和一个名为matchTrailingSlash(默认为true)的可选标志。/**表示所有层路径;/*表示某一层的路径通配;其它路径变量/red/{segment};对于/red/\d+的正则写法有待验证; |
9 | Query | Query路由谓词工厂接受两个参数:一个必需的参数和一个可选的regexp(正则表达式)。如写法为:Query=green表示必须传递green参数名,值不限定,同时也可以指定value值的具体范围或正则;如Query=red, gree表示传递参数名为red,参数值为green。 |
10 | RemoteAddr | RemoteAddr路由谓词工厂接受一个源列表(最小大小为1),这些源是caddr表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码),其中子网掩码可以不写,类似192.*.0.1这种带星号或192.\d+.0.1这种写法需要验证是否支持。 |
11 | X-Forwarded-For | 修改远端地址的解析方式 |
12 | Weight X-Forwarded-For |
权重路由谓词工厂,要求多个路由策略配置的多个项目uri来源,(同一个项目命名会被默认的负载均衡),要求多个weight指定的group名称相同,按照随机的概率权重进行分发; 80%的请求在wighthigh上,20%的请求在weightlow上; |
13 | XForwardedRemoteAddr |
此路由谓词允许基于X-Forwarded-For HTTP报头对请求进行过滤。 这可以用于反向代理,如负载平衡器或web应用程序防火墙,只有当请求来自这些反向代理使用的可信IP地址列表时,才允许该请求。 |
After路由谓词工厂接受一个参数datetime(这是一个java的ZonedDateTime)。此谓词匹配在指定日期时间之后发生的请求。下面的示例配置一个after route谓词:
(After路由谓词工厂)
(Weight权重谓词)
局部过滤器
序号 | 过滤器 | 说明 |
1 | AddRequestHeader | 给请求中增加Header参数,支持传递固定的header参数名和参数值,也支持URI变量 |
2 | AddRequestParameter | 给请求中增加parameter参数,支持固定参数名和附带参数值,也支持URI变量 |
3 | DedupeResponseHeader | 删除请求响应中的重复Header,可选值为RETAIN_FIRST、RETAIN_LAST、RETAIN_UNIQUE ,如网关中和下游应用中同时进行响应Header |
4 | AddResponseHeader | 给请求响应中增加Header参数,支持传递固定的header参数名和参数值,也支持URI变量 |
5 | CircuitBreaker | 配置熔断 |
6 | FallbackHeaders | 在运行断路器时发生执行异常后,请求被转发到运行在localhost:9994上的应用程序中的回退端点或处理程序。FallbackHeaders过滤器将带有异常类型、消息以及(如果可用)根原因异常类型和消息的报头添加到该请求中 |
7 | MapRequestHeader | 接受fromHeader和toHeader参数。它创建了一个新的命名头(toHeader),该值从传入的http请求中已存在的命名头(fromHeader)中提取出来。如果输入头不存在,筛选器就没有影响。如果新的命名头已经存在,则它的值将使用新值进行扩充。 |
8 | PrefixPath | 增加路径层级,给下游请求统一增加项目访问前缀 |
9 | PreserveHostHeader | 没有参数,设置一个请求属性,路由筛选器检查该属性以确定是否应该发送原始的主机报头,而不是HTTP客户端确定的主机报头 |
10 | RateLimiter | 结合redis实现限流 |
11 | RedirectTo | 重定向,设置响应状态和url |
12 | RemoveRequestHeader | 要删除请求Header的参数名称 |
13 | RemoveResponseHeader | 要删除的响应Header的参数名称 |
14 | RemoveRequestParameter | 要删除的请求parameter的参数名称 |
15 | RequestHeaderSize | 接受maxSize和errorHeaderName参数。maxSize参数是请求头允许的最大数据大小(包括键和值)。参数errorHeaderName设置包含错误消息的响应头的名称,默认为"errorMessage" |
16 | RewritePath | GatewayFilter工厂接受一个路径regexp参数和一个替换参数。它使用Java正则表达式作为一种灵活的方式来重写请求路径 |
17 | RewriteLocationResponseHeader | 修改Location响应头的值,通常是为了去掉后端特定的细节。它接受stripVersionMode、locationHeaderName、hostValue和protocolsRegex参数 |
18 | RewriteResponseHeader | 接受名称、regexp和替换参数。它使用Java正则表达式来灵活地重写响应头值。 |
19 | SaveSession | 在向下游转发调用之前强制执行WebSession::save操作。这在使用带有惰性数据存储的Spring Session之类的东西时特别有用,并且您需要确保在进行前转调用之前已经保存了会话状态。如果有使用到Spring Security与Spring Session集成这将比较重要。 |
20 | SecureHeaders | 向响应中添加了许多报头 |
21 | SetPath | 允许路径的模板段提供了一种操作请求路径的简单方法。这使用了Spring Framework中的URI模板。允许有多个匹配段 |
22 | SetRequestHeader | 用给定的名称替换(而不是添加)Request Header头参数。即网关中的参数覆盖下游系统中设置的Header。 |
23 | SetResponseHeader | 用给定的名称替换(而不是添加)Response Header头参数。即网关中的参数覆盖下游系统中设置的Header。 |
24 | SetStatus | 必须是有效的Spring HttpStatus。它可以是整型值404或枚举的字符串表示形式:NOT_FOUND |
25 | StripPrefix | 数字参数,参数表示在将请求发送到下游之前要从请求中剥离的路径中的部件数量,即去除从前往后的几层路径 |
26 | Retry | 请求重试,可配置重试次数、响应码为多少时重试、请求方式重试、异常时重试等 |
27 | RequestSize | 请求大小大于允许的限制,限制请求到达下游服务。响应状态设置为413 Payload Too Large,当请求因大小而被拒绝时,会附加一个报头errorMessage。如果路由定义中没有提供过滤器参数,默认请求大小设置为5mb。 |
28 | SetRequestHostHeader | 用指定的名称替换主机头,筛选器接受一个主机参数 |
29 | ModifyRequestBody | 筛选器在请求正文被网关发送到下游之前修改它,类似修改@RequestBody的参数值 |
30 | ModifyResponseBody | 在将响应体发送回客户端之前,可以使用ModifyResponseBody筛选器修改响应体,类似修改@ResponseBody的参数值 |
31 | TokenRelay | 将(除了让用户登录和获取令牌之外)将身份验证令牌传递到下游的服务,使用者可以是纯客户端(如SSO应用程序)或资源服务器,将传入的令牌转发给传出的资源请求。 |
32 | CacheRequestBody | 由于请求体流只能读取一次,如果需要读取多次的话,我们需要缓存请求体,过滤器在请求正文发送到下游之前缓存请求正文。 |
33 | JsonToGrpc | JSON有效负载转换为Grpc请求 |
34 | default-filters | 要添加一些个过滤器并将其应用于所有路由,使得这些过滤器默认生效在所有路由规则上。 |
全局过滤器
全局过滤器是一种特殊的过滤器,有条件的应用于所有路由。
序号 | 过滤器 | 说明 |
1 | ForwardRoutingFilter | 如果URL有转发模式(比如forward:///localendpoint),它会使用Spring DispatcherHandler来处理请求。请求URL的路径部分将被转发URL中的路径覆盖。 |
2 | ReactiveLoadBalancerClientFilter | 如果URL具有lb方案(例如lb://myservice),它将使用Spring Cloud ReactorLoadBalancer将名称(本例中的myservice)解析为实际的主机和端口,并替换相同属性中的URI。 |
3 | Netty路由过滤器 | 删除请求响应中的重复Header,可选值为RETAIN_FIRST、RETAIN_LAST、RETAIN_UNIQUE ,如网关中和下游应用中同时进行响应Header |
4 | NettyWriteResponseFilter | 重写Response响应过滤器 |
5 | RouteToRequestUrl | 路由请求地址过滤器 |
6 | Websocket Routing Filter | WebSocket路由过滤器 |
7 | 网关指标过滤器 | 网关指标过滤器 |
点赞
发表评论
-
1 验证码为Gif图片,共4个字符和4帧图像交替闪烁,循环闪烁;
-
2 验证码每搁1秒闪烁一次,每次只显示3个字符和1个问号;
-
3 验证码为动态图片,问号出现位置交替变化;
-
4 验证码输入不区分字母大小写,参考以下为A123的验证码:
① 示例图片中没有字符角度旋转;
② 示例图片中没有干扰线;
③ 示例图片中没有网址信息;
-
5 再三权衡,还是将问号字符去除了,后台登录入口我个人使用予以保留;
1 如果您觉得验证码很难接收的话,欢迎给我反馈,我会继续改善,见顶部菜单栏的
作者介绍;
2 访问我站的朋友十有八九都是IT技术类大佬,这样式的验证码看起来不至于太复杂;
3 此处验证码前身使用的是腾讯防水墙免费验证码组件,由于一些原因切换为个人自定义的验证码;
4 所爱隔山海,山海界可平,欢迎留言评论;
评论列表