Spring Cloud Gateway

一 API 网关

API网关,就是指系统统一入口,它用来封装应用程序的内部结构,为客户端提供统一服务。一些与业务本身功能无关的公共逻辑可以在这里实现。比如:认证、鉴权、监控、路由转发 等等。

二 业界流行的网关

  1. Nginx+lua: 使用nginx 的反向代理和负载均衡均可实现api服务器的负载均衡及高可用。lua是一种脚本语言,可以编写一些简单的lua脚本来支持nginx。
  2. Kong:基于 nginx +lua 开发,性能高、稳定,有多个可用的插件(鉴权、限流)可以开箱即用。缺点:只支持http协议,二次开发、自由拓展困难;提供管理API,缺乏更易用的管控,配置方式。
  3. Zuul :Netflix 开源网关,功能丰富,使用java开发,易于二次开发。缺点:缺乏管控,无法动态配置;依赖组件较多;处理http请求依赖是web容器,性能不如nginx。
  4. Spring Cloud Gateway:Spring 公司为了替换zuul而开发的网关服务。

三SpringCloud Gateway 简介

SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代Netflix Zuul,其不仅提供统一的路由方式,而且基于Fliter链的方式提供了网关基本的功能,例如:安全,监控/指标和限流。
(1)优点:

性能强劲:是第一代网关Zuul的1.6倍

功能强大:内置了很多使用的功能,例如转发,监控,限流等

设计优雅,容易扩展

(2)缺点:

其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高

不能将其部署在tomcat,jetty等Servlet容器里,只能打成jar包执行

需要Spingboot2.0及以上的版本,才支持。
四 SpringCloud Gateway快速入门

  1. 创建新模块,导入依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
  1. 创建主类
@SpringBootApplication
public class RuoYiGatewayApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiGatewayApplication.class, args);
       
    }
}
  1. 添加配置文件application.yml
server:
  port: 8080
 
spring: 
  application:
    name: ruoyi-gateway
  cloud:
    gateway:
      routes: #路由数组[路由就是指定当请求满足什么条件的时候转到哪个微服务]
        # 系统模块
        - id: ruoyi-system #当前路有的标示,要求唯一
          uri: http://localhost:9201/ #请求要转发到的地址
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/system/** #当前请求路径满足Path指定的规则时,才进行路有转发
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1  #转发之前去掉1层路径
  1. 运行效果

在地址栏输入 localhost:8080/system/user/1就会自动跳转到 localhost:9201/user/1

其中路径中的system被过滤掉,8080变成9201

  1. 使用nacos注册中心配置方式进行优化

(1)现在在配置文件中写死了转发路径的地址,我们需要使用nacos获取此地址,

(2)并使用 uri: lb://ruoyi-system #请求要转发到的地址 自动实现负载均衡

第1步,加入nacos依赖

  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

第2部:应用加上注解@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient
public class RuoYiGatewayApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiGatewayApplication.class, args);
       
    }
}

第3部:修改配置文件

server:
  port: 8080
 
spring: 
  application:
    name: ruoyi-gateway
  cloud:
    nacos:
      discovery:
      server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
        lowerCaseServiceId: true
        enabled: true   #让gateway可以发现nacos的微服务
      routes: #路由数组[路由就是指定当请求满足什么条件的时候转到哪个微服务]
        # 系统模块
        - id: ruoyi-system #当前路有的标示,要求唯一
          uri: lb://ruoyi-system #请求要转发到的地址
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/system/** #当前请求路径满足Path指定的规则时,才进行路有转发
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1  #转发之前去掉1层路径

五 若依平台—ruoyi-gateway网关
(1)若依平台单独建立ruoyi-gateway网关模块,代码里有4个过滤器:

AuthFilter(全局过滤器),
BlackListUrlFilter(黑名单过滤器)
CacheRequestFilter
ValidateCodeFilter (验证码过滤器)
(2)在nacos里配置了路由信息 和白名单

spring:
  redis:
    host: localhost
    port: 6379
    password: 
  cloud:
    gateway:
      discovery:
        locator:
          lowerCaseServiceId: true
          enabled: true
      routes:
        # 认证中心
        - id: ruoyi-auth
          uri: lb://ruoyi-auth
          predicates:
            - Path=/auth/**
          filters:
            # 验证码处理
            - CacheRequestFilter
            - ValidateCodeFilter
            - StripPrefix=1
        # 代码生成
        - id: ruoyi-gen
          uri: lb://ruoyi-gen
          predicates:
            - Path=/code/**
          filters:
            - StripPrefix=1
        # 定时任务
        - id: ruoyi-job
          uri: lb://ruoyi-job
          predicates:
            - Path=/schedule/**
          filters:
            - StripPrefix=1
        # 系统模块
        - id: ruoyi-system
          uri: lb://ruoyi-system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix=1
        # 文件服务
        - id: ruoyi-file
          uri: lb://ruoyi-file
          predicates:
            - Path=/file/**
          filters:
            - StripPrefix=1
         # whaletest模块
        - id: ruoyi-whaletest
          uri: lb://ruoyi-whaletest
          predicates:
            - Path=/whaletest/**
          filters:
            - StripPrefix=1
 
# 不校验白名单
ignore:
  whites:
    - /auth/logout
    - /auth/login
    - /*/v2/api-docs
    - /csrf
    - /whaletest/test

六 重要功能配置——路由断言和过滤器
我们看到每个路由主要对predicates 和filter进行了配置。这两个一个是断言,一个是过滤器。接下来我们对这两个重要功能进行说明

打开nacos中的ruoyi-gateway-dev.yml ,显示有路由的配置信息如下

系统模块

    - id: ruoyi-system #当前路有的标示,要求唯一
      uri: lb://ruoyi-system #请求要转发到的地址
      predicates: #断言(就是路由转发要满足的条件)
        - Path=/system/** #当前请求路径满足Path指定的规则时,才进行路有转发
      filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
        - StripPrefix=1  #转发之前去掉1层路径

一.predicates 断言:路有需要满足什么条件才能路由,是路由转发的判断条件,目前SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等,写法必须遵循 key=vlue的形式

Predicate 接受一个输入参数,返回一个布尔值结果。

(1)系统内置的断言

规则 实例 说明
Path - Path=/gate/,/rule/ ## 当请求的路径为gate、rule开头的时,转发到http://localhost:9023服务器上
Before - Before=2017-01-20T17:42:47.789-07:00[America/Denver] 在某个时间之前的请求才会被转发到 http://localhost:9023服务器上
After - After=2017-01-20T17:42:47.789-07:00[America/Denver] 在某个时间之后的请求才会被转发
Between - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver] 在某个时间段之间的才会被转发
Cookie - Cookie=chocolate, ch.p 名为chocolate的表单或者满足正则ch.p的表单才会被匹配到进行请求转发
Header - Header=X-Request-Id, \d+ 携带参数X-Request-Id或者满足\d+的请求头才会匹配
Host - Host=www.hd123.com 当主机名为www.hd123.com的时候直接转发到http://localhost:9023服务器上
Method - Method=GET 只有GET方法才会匹配转发请求,还可以限定POST、PUT等请求方式
(2)自定义断言

二.filters过滤

  1. 局部过滤,是针对单个路有的过滤器

(1)内置过滤规则

过滤规则 实例 说明
PrefixPath - PrefixPath=/app 在请求路径前加上app
RewritePath - RewritePath=/test, /app/test 访问localhost:9022/test,请求会转发到localhost:8001/app/test
SetPath - SetPath=/{segment} 设置请求路径,与RewritePath类似。如/red/blue的请求被转发到/blue。
SetStatus - SetStatus=401 设置回执状态码。
StripPrefix - StripPrefix=2 跳过指定路径。请求/name/blue/red会转发到/red。
(2)自定义过滤规则

若依平台中nacos中ruoyi-gateway-dev.yml,有添加自定义过滤规则

      filters:
        # 验证码处理
        - CacheRequestFilter
        - ValidateCodeFilter
        - StripPrefix=1

同时需要实现AbstractGatewayFilterFactory<>方法

  1. 全局过滤:全局过滤器作用于所有的路由,不需要单独配置,我们可以用它来实现很多统一化处理的业务需求,比如权限认证,IP访问限制等等。目前网关统一鉴权AuthFilter.java就是采用的全局过滤器。

自定义全局过滤规则,只需要实现GlobalFilter, Ordered这两个接口就可以了。



/**
 * 网关鉴权
 * 
 * @author ruoyi
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered
{
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
        
    }
 
   
    @Override
    public int getOrder()
    {
        return -200;
    }
}

七,高级配置——网关限流
网关是所有请求的公共入口,所以可以在网关进行限流,而且限流方式也很多。Sentinel支持对SpringCloud Gateway,Zuul等主流网关进行限流。

Sentinel可以提供两种资源的限流

  1. 路由route限流:即在Spring配置文件中配置的路由条目,资源名为对应的ruoteId

2.自定义API维度:用户可以利用sentinel提供的API来自定义一些API分组

需要添加如下依赖

  <!-- SpringCloud Alibaba Sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
 
        <!-- SpringCloud Alibaba Sentinel Gateway -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
        </dependency>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容