此文章主要讲解 springcloud 中的网关 Gateway 的相关知识。
微服务网关概述
前言
根据前面的知识,微服务架构已经初具雏形。但是还有一些问题:不同的微服务一般会有不同的网络地址,客户端在访问这些微服务的时候需要记住几十甚至几百个地址,这对于客户端来说,是非常复杂而且难以维护的。
如果让客户端直接和各个微服务通信,可能会有很多问题:
- 客户端会请求多个不同的服务,需要维护不同的请求地址,增加了开发难度。
- 在某些场景下存在跨域请求的问题。
- 加大身份认证的难度,每个微服务需要独立认证。
因此,我们需要一个微服务网关,介于客户端和服务器之间的中间层,所有的外部请求都会先经过微服务网关。客户端只需要和网关交互,只需要知道一个网关地址即可,这样简化了开发,并且还有以下好处:
- 易于监控。
- 易于认证。
- 减少了客户端和各个微服务之间的交互次数。
微服务网关的概念
什么是微服务网关
API 网关是一个服务器,是系统对外的唯一入口。API 网关封装了系统内部架构,为每个客户端提供一个定制的 API。API 网关方式的核心要点是:所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。
通常,网关也提供 REST/HTTP 的访问 API。服务端通过 API 网关注册和管理服务。
微服务网关的作用和应用场景
- 网关的具体的职责有:身份认证、监控、负载均衡、缓存、请求分片和管理、静态响应处理。当然,最主要的职责还是和
外界联系
。
常见的 API 网关实现方式
Kong
基于 Nginx+Lua 开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可用开箱即用。
问题:
- 只支持 HTTP 协议。
- 二次开发、自由扩展困难。
- 提供管理 API,缺乏更医用的管理和配置方式。
Zuul(已过时)
Netflix 开源,功能丰富,使用 Java 开发,易于二次开发,需要运行在 Web 容器中,如 Tomcat。
问题:
- 缺乏管控,无法动态配置。
- 依赖组件较多。
- 处理 HTTP 请求依赖的是 Web 容器,性能不如 Nginx。
Traefik
Go 语言开发,轻量易用,提供大多数功能如服务路由,负载均衡等等,提供 Web UI 界面。
问题:
- 二进制文件部署,二次开发难度大。
- UI 更多的是监控,缺乏配置、管理能力。
Spring Cloud Gateway
- SpringCloud 提供的网关服务。
Nginx+Lua 实现
使用 Nginx 的反向代理和负载均衡可实现对 API 服务器的负载均衡和高可用。
问题:
- 自注册的问题。
- 网关本身的扩展性。
微服务网关 Gateway
简介
内容过多,开发可参考 https://docs.spring.io/ 官网文档
Spring Cloud Gateway 是 Spring 官方基于
Spring5.0、SpringBoot2.0和Project Reactor
等技术开发的网关,旨在为微服务框架提供一种简单而有效的统一的 API 路由管理方式,统一访问接口。Spring Cloud Gateway 作为 Spring Cloud 生态体系中的网关,目标是替代Netflix的Zuul
,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控/埋点和限流
等等。它是基于Netty
的响应式开发模式。
特性
Gateway 特性:
核心概念
路由(route)
:路由是网关最基础的部分,路由信息由一个 ID,一个目的 URL、一组断言工厂和一组 Filter 组成。如果断言为真,则说明请求 URL 和配置的路由匹配。断言(Predicate)
:Java8 中的断言函数,Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0 框架中的 ServerWebExchange。Spring Cloud Gateway 中的断言函数允许开发者去定义匹配来自 http Request 中的任何信息,比如请求头和参数等。过滤器(Filter)
:一个标准的 Spring WebFilter,Spring Cloud Gateway 中的 Filter 分为两种类型:Gateway Filter 和 Global Filter。过滤器 Filter 可以对请求和响应进行处理。
入门案例
新建模块
cloud-gateway-gateway9527
POM 文件
1 |
|
YML 文件
1 | server: |
主启动类
1 |
|
访问测试
- 启动 Eureka Server 7001
- 启动 cloud-provider-payment8001
- 启动 9527
当我们访问 http://localhost:9527/payment/1 时,即访问网关地址时,会给我们转发到 8001 项目的请求地址,以此作出响应。
加入网关前:
http://localhost:8001/payment/1
加入网关后:
http://localhost:9527/payment/1
Gateway 配置方式
通过配置文件配置
见前面步骤
通过配置类配置
1 |
|
动态路由
这里所谓的动态配置就是利用服务注册中心,来实现 负载均衡 的调用 多个微服务。
注意,这是 GateWay 的负载均衡
默认情况下 Gateway 会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
。
启动微服务
- 启动 eureka7001
- 启动两个服务提供者 8001/8002
POM 文件
1 | <dependency> |
YML 文件
1 | server: |
测试
访问 http://localhost:9527/payment/1 测试即可。
Predicate(断言)
注意到上面 yml 配置中,有个 predicates 属性值
在控制台输出也可以看到:
1 | [After] |
After
1 | // 获取下当前时区时间 |
使用:
1 | predicates: |
Before
1 | predicates: |
Between
1 | predicates: |
Cookie
发送请求可以通过:
1 | jmeter # 压测 |
比如:
1 | predicates: |
在 dos 窗口自测试试:
1 | curl http://localhost:9527/payment/lb --cookie "username=jinggege" |
Windows 下安装使用 Curl 及解决中文乱码问题:点我跳转
Header
1 | predicates: |
自测:
1 | curl http://localhost:9527/payment/lb -H "X-Request-Id:123" |
Host
防爬虫思路:前后端分离的话,只限定前端项目主机访问,这样可以屏蔽大量爬虫。
例如我加上: - Host=localhost:**
** 代表允许任何端口
,就只能是主机来访
配置错误页面:
注意,springboot 默认/static/error/ 下错误代码命名的页面为错误页面,即 404.html
而且不需要导入额外的包,Gateway 里面都有
Method
1 | predicates: |
Path
1 | predicates: |
Query
1 | predicates: |
像这些用法可以自行查询百度学习。
Filter(过滤器)
概述
Spring Cloud Gateway 除了具备请求路由功能之外,也支持对请求的过滤。
和 Zuul 网关类似,也是通过过滤器的形式来实现的。
过滤器基础
过滤器的生命周期
Spring Cloud Gateway 的 Filter 的生命周期不像 Zuul 那么丰富,只有两个:”pre”和”post”。
PRE:
这种过滤器在请求被路由之前调用。我们可以利用这种过滤器实现身份认证、在集群中选择请求的微服务、记录调试信息等。POST:
这种过滤器在路由到微服务以后执行。这种过滤器可以用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等等。
过滤器的类型
Spring Cloud Gateway 的 Filter 从作用范围可以分为两种:
GatewayFilter 和 GlobalFilter
。GatewayFilter:
应用到当个路由或者一个分组的路由上。GlobalFilter:
应用到所有的路由上。
局部过滤器
- 局部过滤器(GatewayFilter),是针对单个路由的过滤器。可以对访问的 URL 过滤,进行切面处理。在 Spring Cloud Gateway 中通过 GatewayFilter 的形式内置了很多不同类型的局部过滤器。
过滤器工厂 | 作用 | 参数 |
---|---|---|
AddRequestHeader | 为原始请求添加 Header | Header 的名称及值 |
AddRequestParameter | 为原始请求添加请求参数 | 参数名称及值 |
AddResponseHeader | 为原始响应添加 Header | Header 的名称及值 |
DedupeResponseHeader | 剔除响应头中重复的值 | 需要去重的 Header 名 称及去重策略 |
Hystrix | 为路由引入 Hystrix 的断路器保护 | HystrixCommand 的名 称 |
FallbackHeaders | 为 fallbackUri 的请求头中添加具 体的异常信息 | Header 的名称 |
PrefixPath | 为原始请求路径添加前缀 | 前缀路径 |
PreserveHostHeader | 为请求添加一个 preserveHostHeader=true 的属 性,路由过滤器会检查该属性以 决定是否要发送原始的 Host | 无 |
RequestRateLimiter | 用于对请求限流,限流算法为令 牌桶 | keyResolver、 rateLimiter、 statusCode、 denyEmptyKey、 emptyKeyStatus |
RedirectTo | 将原始请求重定向到指定的 URL | http 状态码及重定向的 url |
RemoveHopByHopHeadersFilter | 为原始请求删除 IETF 组织规定的 一系列 Header | 默认就会启用,可以通 过配置指定仅删除哪些 Header |
RemoveRequestHeader | 为原始请求删除某个 Header | Header 名称 |
RemoveResponseHeader | 为原始响应删除某个 Header | Header 名称 |
RewritePath | 重写原始的请求路径 | 原始路径正则表达式以 及重写后路径的正则表 达式 |
RewriteResponseHeader | 重写原始响应中的某个 Header | Header 名称,值的正 则表达式,重写后的值 |
SaveSession | 在转发请求之前,强制执行 WebSession::save 操作 | 无 |
secureHeaders | 为原始响应添加一系列起安全作 用的响应头 | 无,支持修改这些安全 响应头的值 |
SetPath | 修改原始的请求路径 | 修改后的路径 |
SetResponseHeader | 修改原始响应中某个 Header 的值 | Header 名称,修改后 的值 |
SetStatus | 修改原始响应的状态码 | HTTP 状态码,可以是 数字,也可以是字符串 |
StripPrefix | 用于截断原始请求的路径 | 使用数字表示要截断的 路径的数量 |
Retry | 针对不同的响应进行重试 | retries、statuses、 methods、series |
RequestSize | 设置允许接收最大请求包的大 小。如果请求包大小超过设置的 值,则返回 413 Payload Too Large | 请求包大小,单位为字 节,默认值为 5M |
ModifyRequestBody | 在转发请求之前修改原始请求体内容 | 修改后的请求体内容 |
ModifyResponseBody | 修改原始响应体的内容 | 修改后的响应体内容 |
每个过滤器工厂都对应一个实体类,并且这些类的名称必须以 GatewayFilterFactory 结尾,这是 Spring Cloud Gateway 的一个约定,例如 AddRequestHeader 对一个的实体类为 AddRequestHeaderGatewayFilterFactory。
全局过滤器
全局过滤器(GlobalFilter)作用于所有路由,Spring Cloud Gateway 定义了
GlobalFilter
接口,用户可以自定义实现自己的 Global Filter。通过全局过滤器可以实现对权限的统一校验,安全性校验等功能,并且全局过滤器也是程序员使用比较多的过滤器。Spring Cloud Gateway 内部也是通过一些列的内置全局过滤器对整个路由转发进行处理,如下图所示:
统一鉴权
概述
- 内置的过滤器已经可以完成大部分的功能,但是对于企业开发的一些业务功能处理,还是需要我们自己去编写过滤器来实现的,那么我们通过代码的形式自定义一个过滤器,去完成统一的权限校验。
鉴权逻辑
开发中的鉴权逻辑:
当客户端第一次请求服务的时候,服务端对用户进行信息认证(登录)。
认证通过,将用户信息进行加密形成 token,返回给客户端,作为登录凭证。
以后每次请求,客户端都携带认证的 token。
服务 daunt 对 token 进行解密,判断是否有效。
如上图所示,对于验证用户是否已经登录授权的过程可以在网关层统一校验。校验的标准就是请求中是否携带 token 凭证以及 token 的正确性。
代码实现
主要是配置全局自定义过滤器,其它的小配置具体看官网吧
1 | /** |
启动访问即可。
网关高可用
高可用HA
是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。我们都知道,单点是系统高可用的大敌,单点往往是系统高可用的最大的风险和敌人,应该尽量在系统设计的过程中避免单点。方法论上,
高可用保证的原则是“集群化”
,或者叫做“冗余”。只有一个单点,挂了服务会受影响;如果有冗余备份,挂了还有其他备份能够顶上。
- 我们实际使用 Spring Cloud Gateway 的方式如上图所示,不同的客户端使用不同的负载将请求分发到后端的 Gateway,Gateway 再通过 HTTP 调用后端服务,最后对外输出。因此为了保证 Gateway 的高可用性,前端可以同时启动多个 Gateway 实例进行负载,在 Gateway 的前端使用 Nginx 或者 F5 进行负载转发以达到高可用性。
发布时间: 2021-01-19
最后更新: 2024-06-24
本文标题: SpringCloud Alibaba入门到精通(九)- 微服务网关Gateway
本文链接: https://blog-yilia.xiaojingge.com/posts/f58edf61.html
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可。转载请注明出处!
