Gateway服务网关

简介: Gateway服务网关是微服务架构的统一入口,具备路由转发、权限控制、限流及负载均衡等核心功能。基于SpringCloud Gateway可实现高性能响应式编程,支持丰富的断言与过滤器工厂,并可通过全局过滤器扩展自定义逻辑,有效解决跨域等问题,是微服务治理的关键组件。

Gateway服务网关
cloud-demo(1).zip
(102.8 MB)
1.为什么需要网关
Gateway网关是我们服务的守门神,所有微服务的统一入口。网关的核心功能特性:
请求路由
权限控制
限流
其架构图如下:
权限控制:网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。
路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。
限流:当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。
什么是API网关,可参考:https://www.yuque.com/xiankanpengyouquandisitiaodongtai/yeq5ax/blo41c
在SpringCloud中网关的实现包括两种:
gateway
zuul
Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。(响应式变成WebFlux了解请移步至:什么是WebFlux)
2.gateway快速上手
1 创建gateway服务,引入依赖
引入依赖
2 编写启动类
3 编写基础配置和路由规则
创建application.yml文件,内容如下(示例配置多个路由规则):
我们将符合Path 规则的一切请求,都代理到 uri参数指定的地址。本例中,我们将 /user/开头的请求,代理到lb://userservice,lb是负载均衡,根据服务名拉取服务列表,实现负载均衡。
4 重启测试
重启网关,访问http://localhost:10010/user/1时,符合/user/
规则,请求转发到uri:http://userservice/user/1,效果如下,说明网关路由生效:
5 网关路由流程图
当用户请求过来之后首先请求网关,网关根据自己的路由规则判断决定路由到哪个服务(依赖Nacos注册中心的服务列表信息),同时借助自身负载均衡能力分配到指定服务多个实例中的某一个实例,完成一次请求&响应。
路由配置包括:
路由id:路由的唯一标示
路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
路由断言(predicates):判断路由的规则,
路由过滤器(filters):对请求或响应做处理
接下来,就重点来学习路由断言和路由过滤器的详细知识。
3.断言工厂
我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件,例如Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的,像这样的断言工厂在SpringCloudGateway还有十几个:
名称
说明
示例
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
    权重处理
    虽然断言规则有很多,但基本使用的都是Path这种路由工程,大家也重点关注此即可。
    4.过滤器工厂
    GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:

1 过滤器种类
Spring提供了31种不同的路由过滤器工厂,具体如下:
名称
说明
AddRequestHeader
给当前请求添加一个请求头
RemoveRequestHeader
移除请求中的一个请求头
AddResponseHeader
给响应结果中添加一个响应头
RemoveResponseHeader
从响应结果中移除有一个响应头
RequestRateLimiter
限制请求的流量
2 请求头过滤器
下面我们以AddRequestHeader 为例来讲解。
需求:给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking awesome!
只需要修改gateway服务的application.yml文件,添加路由过滤即可:
当前过滤器写在userservice路由下,因此仅仅对访问userservice的请求有效。
3 默认过滤器
如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:
4 总结
过滤器的作用:
① 对路由的请求或响应做加工处理,比如添加请求头
② 配置在路由下的过滤器只对当前路由的请求生效
defaultFilters的作用:
① 对所有路由都生效的过滤器
5.全局过滤器
上一节学习的过滤器,网关提供了31种,但每一种过滤器的作用都是固定的。如果我们希望拦截请求,做自己的业务逻辑则没办法实现。因此需要一种全局过滤器帮我们实现此功能。
1 全局过滤器作用
处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义,处理逻辑是固定的;而GlobalFilter的逻辑需要自己写代码实现。定义方式是实现GlobalFilter接口。
在filter中编写自定义逻辑,可以实现下列功能:
登录状态判断
权限校验
请求限流等
2 自定义全局过滤器
需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:
参数中是否有authorization,
authorization参数值是否为admin
如果同时满足则放行,否则拦截。其实现只要在gateway中定义一个过滤器:
此时我们访问必须追加参数才可以成功:http://localhost:10010/order/101?authorization=admin
3 过滤器执行顺序
请求进入网关会碰到三类过滤器:当前路由的过滤器、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排序,组织过滤器链
6.跨域问题
1 什么是跨域
跨域:域名不一致就是跨域,主要包括:
域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com
域名相同,端口不同:localhost:8080和localhost8081
跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决方案:CORS,这个以前应该学习过,这里不再赘述了。不知道的小伙伴可以查看:链接
2 模拟跨域问题
将文件:
index.html
(1 KB)
放入tomcat或者nginx:
nginx-1.18.0.zip
(1.6 MB)
这样的web服务器中,启动并访问。可以在浏览器控制台看到下面的错误:
从localhost:8090访问localhost:10010,端口不同,显然是跨域的请求。
3 解决跨域问题
在gateway服务的application.yml文件中,添加下面的配置:
跨域配置
YAML
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 # 是否允许携带cookie
        maxAge: 360000 # 这次跨域检测的有效期

7.总结
本节针对微服务中另一重要组件:网关 进行了实战性演练,网关作为分布式架构中的重要中间件,不仅承担着路由分发(重点关注Path规则配置),同时可根据自身负载均衡策略,对多个注册服务实例进行均衡调用。本节我们借助GateWay实现的网关只是技术实现的方案之一,后续大家可能会接触像:Zuul、Kong等,其实现细节或有差异,但整体目标是一致的。
截至目前我们的工程如下:
cloud-demo.zip
(162 KB)
8.推荐阅读资料
网关发展的前世今生:https://zhuanlan.zhihu.com/p/406006556
WebFlux响应式编程:https://www.yuque.com/xiankanpengyouquandisitiaodongtai/diods0/szn9t1hs0g7gcq13

相关文章
|
27天前
|
SQL 容灾 Nacos
Seata的部署和集成
本文介绍Seata分布式事务框架的部署与集成。首先下载并解压seata-server-1.5.1,修改application.yml配置,将seataServer.properties配置上传至Nacos作为统一配置中心,并创建所需数据库表。启动tc-server后,注册到Nacos,通过控制台可查看服务状态。各微服务需引入Seata依赖,并在application.yml中配置相关参数。为实现高可用,可搭建多节点TC集群,如GZ和HZ集群,通过Nacos统一管理事务组映射,微服务从Nacos读取client.properties配置,动态切换TC集群连接,提升系统容灾能力。
101 0
|
负载均衡 安全 Java
【微服务系列笔记】Gateway
Gateway是Spring Cloud生态系统中的网关服务,作为微服务架构的入口,提供路由、负载均衡、限流、鉴权等功能。借助于过滤器和路由器,Gateway能够动态地管理请求流量,保障系统的安全和性能。
2089 7
|
28天前
|
JSON Dubbo Java
Feign远程调用
Feign简化Spring Cloud微服务间HTTP调用,替代RestTemplate,解决硬编码、可读性差问题。通过注解声明客户端,集成注册中心实现服务发现。支持自定义日志、编码器、连接池(如Apache HttpClient)优化性能,并可通过抽取公共模块实现最佳实践,提升代码复用与维护性。(238字)
75 0
|
28天前
|
存储 Java API
SpringCloud工程部署启动
本文介绍SpringCloud微服务工程的搭建与部署,涵盖项目导入、模块创建、数据库配置及服务启动。通过RestTemplate实现order-service与user-service间的远程调用,解决跨服务数据获取问题,帮助理解微服务拆分与通信机制。
56 0
|
27天前
|
存储 NoSQL Linux
Redis集群部署指南
本教程基于CentOS7详解Redis集群部署,涵盖单机安装、主从复制、哨兵高可用及分片集群搭建。通过多实例模拟真实环境,深入讲解配置、启动、主从切换与数据读写测试,助你掌握Redis分布式架构核心技能。
85 0
|
28天前
|
XML Java 数据格式
SpringBoot. 打包
将项目打包为单一JAR文件,包含配置文件,通过`mvn clean package`命令构建。运行时可前台或后台启动:`java -jar **.jar` 或 `nohup java -jar **.jar`;停止服务需查找进程PID并执行`kill -9 pid`。也可分离JAR、依赖与配置文件以方便管理。
39 0
|
28天前
|
XML Java 数据格式
SpringBoot@Configuration
`@Configuration` 注解用于标记配置类,相当于 XML 配置文件。配合 `@Bean` 可注册 Bean 实例。通过 `AnnotationConfigApplicationContext` 启动容器,可加载配置类并管理其定义的 Bean,实现基于 Java 的 Spring 容器配置。
56 0
|
28天前
|
XML Java 数据库连接
MyBatis
本内容介绍MyBatis中四种映射关系:一对一(属性与字段映射,解决命名不一致)、一对多(如用户关联多个角色,使用`<collection>`)、多对一(如博客关联作者,使用`<association>`)和多对多(通过中间类关联,如用户与部门互相关联),详解如何通过resultMap配置实现复杂对象关系映射。
37 0
|
6月前
|
人工智能 监控 搜索推荐
API如何赋能电商营销:自动化促销活动生成
在电商竞争中,API通过自动化促销活动生成,实现精准营销与高效运营,提升转化率与用户体验。
242 0
|
消息中间件 Java Kafka
Spring Boot与Kafka的集成应用
Spring Boot与Kafka的集成应用
1851 0