【微服务技术09】统一网关Gateway

案例代码:https://gitee.com/pikachu2333/spring-cloud-hexuan

1、网关作用

网关功能:

  • 身份认证和权限校验
  • 服务路由、负载均衡
  • 请求限流

权限控制: 网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。

路由和负载均衡: 一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。

限流: 当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。

在SpringCloud中网关的实现包括两种:gateway、zuul
Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。

2、搭建网关服务

创建maven项目引入依赖

<!--网关依赖-->
<!--nacos服务注册发现依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--网关gateway依赖-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

创建启动类

编写路由配置及nacos地址

server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称cloud:nacos:server-addr: localhost:8848 # nacos地址gateway:routes: # 网关路由配置- id: nacos-user-service # 路由id,自定义,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址uri: lb://nacos-user-service # 路由的目标地址 lb就是负载均衡(loadBalance),后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求- id: nacos-order-serviceuri: lb://nacos-order-servicepredicates:- Path=/order/**

启动服务,通过网关路由访问服务:
http://localhost:10010/user/1
http://localhost:10010/order/101


网关搭建步骤:
创建项目,引入nacos服务发现和gateway依赖
配置application.yml,包括服务基本信息、nacos地址、路由

路由配置包括:
路由id:路由的唯一标示
路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
路由断言(predicates):判断路由的规则,
路由过滤器(filters):对请求或响应做处理

3、路由断言工厂Route Predicate Factory

网关路由可以配置的内容包括:

路由id:路由唯一标示
uri:路由目的地,支持lb和http两种
predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地
filters:路由过滤器,处理请求或响应

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
例如Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的
像这样的断言工厂在SpringCloudGateway还有十几个

Spring提供了11种基本的Predicate工厂:

名称 说明 示例
After 是某个时间点后的请求 - After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before 是某个时间点之前的请求 - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between 是某两个时间点之前的请求 - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie 请求必须包含某些cookie - Cookie=chocolate, ch.p
Header 请求必须包含某些header - Header=X-Request-Id, \d+
Host 请求必须是访问某个host(域名) - Host=**.somehost.org,**.anotherhost.org
Method 请求方式必须是指定方式 - Method=GET,POST
Path 请求路径必须符合指定规则 - Path=/red/{segment},/blue/**
Query 请求参数必须包含指定参数 - Query=name, Jack或者- Query=name
RemoteAddr 请求者的ip必须是指定范围 - RemoteAddr=192.168.1.1/24
Weight 权重处理

4、路由过滤器

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:

Spring提供了31种不同的路由过滤器工厂。例如:

名称 说明
AddRequestHeader 给当前请求添加一个请求头
RemoveRequestHeader 移除请求中的一个请求头
AddResponseHeader 给响应结果中添加一个响应头
RemoveResponseHeader 从响应结果中移除有一个响应头
RequestRateLimiter 限制请求的流量

给请求都添加header

server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称cloud:nacos:server-addr: localhost:8848 # nacos地址gateway:routes: # 网关路由配置- id: nacos-user-service # 路由id,自定义,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址uri: lb://nacos-user-service # 路由的目标地址 lb就是负载均衡(loadBalance),后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
#          filter:
#            - AddRequestHeader=hexuan666!  # 添加请求头- id: nacos-order-serviceuri: lb://nacos-order-servicepredicates:- Path=/order/**default-filters: # 默认过滤器,对所以路由请求都生效- AddRequestHeader=Truth,hexuan666!  # 添加请求头

打印header验证是否添加成功

@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id,@RequestHeader(value = "Truth", required = false) String truth) {System.out.println("truth: " + truth);return userService.queryById(id);
}

5、全局过滤器 GlobalFilter

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。
区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。
定义方式是实现GlobalFilter接口。

public interface GlobalFilter {  /* 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理* @param exchange 请求上下文,里面可以获取Request、Response等信息    * @param chain 用来把请求委托给下一个过滤器     * @return {@code Mono<Void>} 返回标示当前过滤器业务结束 */Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

案例:定义全局过滤器,拦截并判断用户身份

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:

  • 参数中是否有authorization,
  • authorization参数值是否为admin

如果同时满足则放行,否则拦截
@Order注解设置过滤器的顺序,也可以实现Ordered接口实现

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1、获取请求参数ServerHttpRequest request = exchange.getRequest();MultiValueMap<String, String> queryParams = request.getQueryParams();// 2、获取参数中的authorization参数String authorization = queryParams.getFirst("authorization");//3、判断参数是否等于admin// 放行if ("admin".equals(authorization)) {return chain.filter(exchange);}// 拦截 设置响应状态码exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}
}

这样,当有这个请求参数时就会被放行,否则会被拦截报401了
http://localhost:10010/order/101?authorization=admin

总结

全局过滤器对所有路由都生效的过滤器,并且可以自定义处理逻辑

实现全局过滤器的步骤
实现GlobalFilter接口
添加@Order注解或实现Ordered接口
编写处理逻辑

6、过滤链执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
  • 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。
  • 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。
    可以参考下面几个类的源码来查看:

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。

org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链

7、网关的cors跨越配置

跨域:域名不一致就是跨域,主要包括:

  • 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com
  • 域名相同,端口不同:localhost:8080和localhost8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决方案:CORS

网关处理跨域采用的同样是CORS方案,并且只需要简单配置即可实现:

spring:cloud:gateway:globalcors: # 全局的跨域处理add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题corsConfigurations:'[/**]':allowedOrigins: # 允许哪些网站的跨域请求- "http://localhost:8090" # 前端打包指定端口allowedMethods: # 允许的跨域ajax的请求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*" # 允许在请求中携带的头信息allowCredentials: true # 是否允许携带cookiemaxAge: 360000 # 这次跨域检测的有效期

【微服务技术09】统一网关Gateway相关推荐

  1. 「微服务系列」统一网关Gateway

    为什么需要网关 网关功能: 身份认证和权限校验 服务路由.负载均衡 请求限流 在SpringCloud中网关的实现包括两种: Zuul:基于Servlet的实现,属于阻塞式编程. SpringClou ...

  2. 基于go-micro微服务的实战-实现网关Gateway(三)

    基于go-micro微服务的实战-实现网关Gateway(三) 文章最后附带完整代码 基于go-micro实现网关层 创建好网关层目录 common: 公告模块,配置初始化等 conf: 配置文件 h ...

  3. 【微服务】—— 统一网关Gateway

    文章目录 1. 概述 1.1 为什么需要网关 1.2 SpringCloud Gateway 2. gateway快速入门 搭建网关服务 1.创建新的module,引入SpringCloudGatew ...

  4. 微服务技术栈:API网关中心,落地实现方案

    本文源码:GitHub·点这里 || GitEE·点这里 一.服务网关简介 1.外观模式 客户端与各个业务子系统的通信必须通过一个统一的外观对象进行,外观模式提供一个高层次的接口,使得子系统更易于使用 ...

  5. 微服务技术发展的现状与展望

    微服务技术发展的现状与展望 人工智能技术与咨询 来源:计算机研究与发展,作者冯志勇等 摘 要 随着云计算.物联网等技术迅速发展,用户对软件系统的需求趋于多样化,面向服务的体系架构(service or ...

  6. day02 Nacos集群配置、Feign远程调用和统一网关Gateway

    1.Nacos配置管理 Nacos除了可以做注册中心,同样可以做配置管理来使用. 统一配置管理 当微服务部署的实例越来越多,达到数十.数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错.我们需要一 ...

  7. 各大主流微服务技术SpringCloud、SpringCloudAlibaba、Dubbo、Motan、MSEC架构选型对比

    文章目录 技术选型考虑 为什么考虑SpringCloudAlibaba SpringCloudAlibaba和SpringCloud的区别及技术最终选型 开源微服务技术选型功能技术对比 SpringC ...

  8. 国内外微服务技术架构演进背景

    文章目录 (1)国内BAT互联网大厂的微服务架构演进路线 (2)海外硅谷互联网大厂的微服务架构演进路线 (3)目前国内公司的主流微服务技术栈介绍 (1)国内BAT互联网大厂的微服务架构演进路线 几乎所 ...

  9. SpringCloud微服务技术实践与总结(基础篇)

    1.认识微服务 1.1.单体架构 单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署. 单体架构的优缺点如下: 优点: 架构简单.部署成本低 缺点: 耦合度高(维护困难.升级困难) 1.2 ...

最新文章

  1. LeetCode简单题之键盘行
  2. 【nodejs爬虫】使用async控制并发写一个小说爬虫
  3. 8月25号 工作计划与实行
  4. VxWorks 6.9 内核编程指导之读书笔记 -- VxWorks kernel application (一)
  5. pytorch学习笔记(十二):权重衰减
  6. 用OpenCV检测图像中的长方形画布或纸张并提取图像内容
  7. git拉取远程计算机上的代码 并 与本地进行比较(git fetch; git pull)
  8. 微观社会调查数据:中国家庭追踪调查 CFPS
  9. 如何修改iphone服务器,iPhone手机配置教程
  10. 系统运维安全管理办法_7.系统运维安全管理规定
  11. python qt是什么_初识Python与Qt
  12. 会计专业计算机工具,会计工作需要用哪些工具
  13. python9行代码_如何用9行Python代码编写一个简易神经网络
  14. Linux命令之bc命令
  15. 【STM32H7教程】第29章 STM32H7的USART串口基础知识和HAL库API
  16. NIOS II 8:SDRAM(W9825G6KH-6),从这里开始使用软件版本改为18.
  17. #金数据#微信小程序#微信小程序跳转金数据小程序并获取问卷信息
  18. tbox系统启动过程分析及优化
  19. 5.12汶川7.8级大地震
  20. 网上超火的微信昵称和头像创意玩法 个性又帅气 有意思!

热门文章

  1. TensorFlow Eager 教程(转)
  2. 经纬度与UTM(Universal Transverse Mercator Projector:通用横轴卡墨托投影)的坐标变换代码
  3. 人体姿态识别-pose estimation
  4. 思想,坚持,信仰,一切
  5. 给Ubuntu服务器安装图形化界面
  6. Python PyQt5简介
  7. javax.net.ssl.SSLHandshakeException: No appropriate protocol
  8. containerd环境下build镜像
  9. 解读电力调度、电力市场、技术创新,国网南网新型电力系统行动方案
  10. usb设备复合g_webcam摄像头码流传输功能以及g_serial串口功能