hello大家好,我是阿七。

在前面的文章中,我们已经基本搭建了一套微服务系统,包含内容中心和用户中心,我们在接口调用的时候,分别通过两个微服务的端口进行调用。那么,如果微服务有几十个,几百个呢?这种方式肯定是行不通的,此时我们就需要一个网关来进行统一管理。

我整理了之前发布的SpringCloud Alibaba系列文章:

一、Spring Cloud Netflix简介

二、Nacos服务注册与发现

三、你要的负载均衡Ribbon

四、Feign如何使用?看看这篇文章吧

五、Sentinel:分布式系统流量防卫兵

六、微服务消息通信RocketMQ及分布式事务

一、Zuul和Gateway的恩怨情仇

1、背景
Zuul是Netflix开源的一个项目,Spring只是将Zuul集成在了Spring Cloud中。而Spring Cloud Gateway是Spring Cloud的一个子项目。

还有一个版本的说法是Zuul2的连续跳票和Zuul1的性能并不是很理想,从而催生了Spring Cloud Gateway。

2、性能比较
网上很多地方都说Zuul是阻塞的,Gateway是非阻塞的,这么说是不严谨的,准确的讲Zuul1.x是阻塞的,而在2.x的版本中,Zuul也是基于Netty,也是非阻塞的,如果一定要说性能,其实这个真没多大差距。

而官方出过一个测试项目,创建了一个benchmark的测试项目:spring-cloud-gateway-bench,其中对比了:

Spring Cloud Gateway
Zuul1.x
Linkerd

从结果可知,Spring Cloud Gateway的RPS是Zuul1.x的1.6倍

ok,我们进入正题,开始聊聊Spring Cloud Gateway的一些事情,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

二、搭建Gateway微服务

1、通过Spring Initializr快速搭建一个gateway微服务,pom如下

<?xml version="1.0" encoding="UTF-8"?>4.0.0org.springframework.boot        spring-boot-starter-parent        2.1.5.RELEASEcom.seven    gateway    0.0.1-SNAPSHOTgatewayDemo project for Spring Boot1.8org.springframework.cloud            spring-cloud-starter-gateway        org.springframework.boot            spring-boot-starter-actuator        org.springframework.cloud            spring-cloud-starter-alibaba-nacos-discovery        org.springframework.boot            spring-boot-starter-test            testorg.junit.vintage                    junit-vintage-engine                org.springframework.cloud                spring-cloud-dependencies                Greenwich.SR1pomimportorg.springframework.cloud                spring-cloud-alibaba-dependencies                0.9.0.RELEASEpomimportorg.springframework.boot                spring-boot-maven-plugin            

2、修改配置文件

server:  port: 8888spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: localhost:8848    gateway:      discovery:        locator:          #让Gateway通过服务发现组件找到其他的微服务          enabled: truemanagement:  endpoints:    web:      exposure:        include: '*'  endpoint:    health:      show-details: always

3、测试,我们通过使用localhost:8888/{微服务名称}/路径,这样的方式就可以调用内容中心的接口了。

三、Gateway核心概念和流程

1、概念
Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。

Predicate(谓词):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。

Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。

2、流程
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

四、路由谓词工厂Route Predicate Factories

下面来详细探讨Spring Cloud Gateway的路由谓词工厂 (Route Predicate Factories),路由谓词工厂的作用是:符合Predicate的条件,就使用该路由的配置,否则就不管。只要掌握这一句,掌握路由谓词工厂就比较轻松了。

Predicate是Java 8提供的一个函数式编程接口。

Spring Cloud Gateway中内置的谓词工厂,包括:After、Before、Between、Cookie、Header、Host、Method、Path、Query、RemoteAddr

下面正式探讨路由谓词工厂。Spring Cloud Gateway提供了十来种路由谓词工厂。为网关实现灵活的转发提供了基石。

After
示例:

spring:  cloud:    gateway:      routes:        - id: after_route          uri: lb://user-center          predicates:            # 当且仅当请求时的时间After配置的时间时,才会转发到用户微服务            # 目前配置不会进该路由配置,所以返回404            # 将时间改成 < now的时间,则访问localhost:8887/** -> user-center/**            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - After=2030-01-20T17:42:47.789-07:00[America/Denver]

TIPS

技巧:时间可使用 System.out.println(ZonedDateTime.now()); 打印,然后即可看到时区。例如:2020-09-10T19:50:42.579+08:00[Asia/Shanghai]时间格式的相关逻辑:默认时间格式:org.springframework.format.support.DefaultFormattingConversionService#addDefaultFormatters时间格式注册:org.springframework.format.datetime.standard.DateTimeFormatterRegistrar#registerFormatters

Before
示例:

spring:  cloud:    gateway:      routes:        - id: before_route          uri: lb://user-center          predicates:            # 当且仅当请求时的时间Before配置的时间时,才会转发到用户微服务            # 目前配置不会进该路由配置,所以返回404            # 将时间改成 > now的时间,则访问localhost:8887/** -> user-center/**            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - Before=2018-01-20T17:42:47.789-07:00[America/Denver]

Between
示例:

spring:  cloud:    gateway:      routes:        - id: between_route          uri: lb://user-center          predicates:            # 当且仅当请求时的时间Between配置的时间时,才会转发到用户微服务            # 因此,访问localhost:8887/** -> user-center/**            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2027-01-21T17:42:47.789-07:00[America/Denver]

Cookie
示例:

spring:  cloud:    gateway:      routes:        - id: cookie_route          uri: lb://user-center          predicates:            # 当且仅当带有名为somecookie,并且值符合正则ch.p的Cookie时,才会转发到用户微服务            # 如Cookie满足条件,则访问http://localhost:8887/** -> user-center/**            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - Cookie=somecookie, ch.p

Header

spring:  cloud:    gateway:      routes:        - id: header_route          uri: lb://user-center          predicates:            # 当且仅当带有名为X-Request-Id,并且值符合正则d+的Header时,才会转发到用户微服务            # 如Header满足条件,则访问http://localhost:8887/** -> user-center/**            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - Header=X-Request-Id, d+

Host

spring:  cloud:    gateway:      routes:        - id: host_route          uri: lb://user-center          predicates:            # 当且仅当名为Host的Header符合**.somehost.org或**.anotherhost.org时,才会转发用户微服务            # 如Host满足条件,则访问http://localhost:8887/** -> user-center/**            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - Host=**.somehost.org,**.anotherhost.org

Method

spring:  cloud:    gateway:      routes:        - id: method_route          uri: lb://user-center          predicates:            # 当且仅当HTTP请求方法是GET时,才会转发用户微服务            # 如请求方法满足条件,访问http://localhost:8887/** -> user-center/**            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - Method=GET

Path

spring:  cloud:    gateway:      routes:        - id: path_route          uri: lb://user-center          predicates:            # 当且仅当访问路径是/users/*或者/some-path/**,才会转发用户微服务            # segment是一个特殊的占位符,单层路径匹配            # eg. 访问http://localhost:8887/users/1 -> user-center/users/1            - Path=/users/{segment},/some-path/**

Query
示例1:

spring:  cloud:    gateway:      routes:        - id: query_route          uri: lb://user-center          predicates:            # 当且仅当请求带有baz的参数,才会转发到用户微服务            # eg. 访问http://localhost:8887/users/1?baz=xx -> user-center的/users/1            - Query=baz

示例2:

spring:  cloud:    gateway:      routes:        - id: query_route          uri: lb://user-center          predicates:            # 当且仅当请求带有名为foo的参数,且参数值符合正则ba.,才会转发到用户微服务            # eg. 访问http://localhost:8887/users/1?baz=baz -> user-center的/users/1?baz=baz            - Query=foo, ba.

RemoteAddr
示例:

spring:  cloud:    gateway:      routes:        - id: remoteaddr_route          uri: lb://user-center          predicates:            # 当且仅当请求IP是192.168.1.1/24网段,例如192.168.1.10,才会转发到用户微服务            # eg. 访问http://localhost:8887/users/1 -> user-center的/users/1            - RemoteAddr=192.168.1.1/24

TIPS

建议大家看下这一部分的官方文档,有个小编程技巧。比较简单,留个印象。

https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/single/spring-cloud.html#_remoteaddr_route_predicate_factory

五、Gateway限流

Spring Cloud Gatway内置的 RequestRateLimiterGatewayFilterFactory 提供限流的能力,基于令牌桶算法实现。目前,它内置的 RedisRateLimiter ,依赖Redis存储限流配置,以及统计数据。当然你也可以实现自己的RateLimiter,只需实现 org.springframework.cloud.gateway.filter.ratelimit.RateLimiter 接口,或者继承 org.springframework.cloud.gateway.filter.ratelimit.AbstractRateLimiter 。

令牌桶算法

系统按照恒定间隔向水桶里加入令牌(Token),如果桶满了的话,就不加了。每个请求来的时候,会拿走1个令牌,如果没有令牌可拿,那么就拒绝服务。

1、加依赖

org.springframework.boot    spring-boot-starter-data-redis-reactive

2、写配置

spring:  cloud:    gateway:      routes:        - id: after_route          uri: lb://user-center          predicates:            - TimeBetween=上午0:00,下午11:59          filters:            - AddRequestHeader=X-Request-Foo, Bar            - name: RequestRateLimiter              args:                # 令牌桶每秒填充平均速率                redis-rate-limiter.replenishRate: 1                # 令牌桶的上限                redis-rate-limiter.burstCapacity: 2                # 使用SpEL表达式从Spring容器中获取Bean对象                key-resolver: "#{@pathKeyResolver}"  redis:    host: 127.0.0.1    port: 6379

3、写代码

@Configurationpublic class Raonfiguration {    /**     * 按照Path限流     *     * @return key     */    @Bean    public KeyResolver pathKeyResolver() {        return exchange -> Mono.just(            exchange.getRequest()                .getPath()                .toString()        );    }}

这样,限流规则即可作用在路径上。

例如:

# 访问:http://${GATEWAY_URL}/users/1,对于这个路径,它的redis-rate-limiter.replenishRate = 1,redis-rate-limiter.burstCapacity = 2;# 访问:http://${GATEWAY_URL}/shares/1,对这个路径,它的redis-rate-limiter.replenishRate = 1,redis-rate-limiter.burstCapacity = 2;

测试
持续高速访问某个路径,速度过快时,返回 HTTP ERROR 429 。

好了,网关的学习就到这里了,篇幅较长,建议大家收藏,以后用到了可以对照着参考。

喜欢的小伙伴请给我点赞加关注吧,阿七将会非常开心。

gateway网关_公司要把网关Zuul换成Gateway,再难也得顶上相关推荐

  1. ip地址 默认网关_如何查找默认网关IP地址?

    ip地址 默认网关 The default gateway is a network term used to specify a special host that is used to acces ...

  2. 仅仅有人物没背景的图片怎么弄_怎么把人物的背景换成另一张图

    1. 想要把一张图片的背景换成另一个图片,怎么做 可以使用电脑端的美图秀秀更换背景,步骤如下: 所需材料:原图.美图秀秀.电脑. 一.首先打开美图秀秀点击右上角的"打开",然后选择 ...

  3. gateway动态路由_微服务与网关技术(SIA-GateWay)

    一.背景 软件架构,总是在不断的演进中... 把时间退回到二十年之前,当时企业级领域研发主要推崇的还是C/S模式,PB.Delphi这样的开发软件是企业应用开发的主流.随着时间的推移,基于浏览器的B/ ...

  4. spring cloud gateway 网关_微服务网关Spring Cloud Gateway全搞定

    一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...

  5. python 微服务 网关_微服务中的 API 网关(API Gateway)

    我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些小系统通常以提供 Rest Api ...

  6. Spring Cloud Gateway(一)为什么用网关、能做什么、为什么选择Gateway、谓词工厂、过滤器配置

    1.为什么用网关?能做什么?为什么选择Gateway? 1.1.为什么用网关 网关api:封装了系统内部架构,为每个客户端提供一个定制的 API.在微服务架构中,服务网关的核心要点是,所有的客户端和消 ...

  7. 支付网关和api网关_将您的钱放在鼠标所在的位置:已审查6个支付网关

    支付网关和api网关 So you're starting your own ecommerce Website? Good for you! But you have many decisions ...

  8. centos同网段双网关_学习笔记之初识网关

    网关这个名词对于很多人来说应该是个很耳熟的名词吧.在设置电脑的IP时就经常会看到默认网关这个名词,如下图所示: 那么网关到底是个什么东西呢?从名字上来看网关是一个关口,网关就是从一个网络到另一个网络的 ...

  9. 微服务认证模式_微服务之“网关模式”

    定义 API网关是一个服务器,它是系统中的单个入口点,用户对API网关进行单一呼叫,然后API网关调用每个相关的微服务器.它类似于面向对象设计的Facade模式.API网关封装内部系统架构,并提供针对 ...

  10. 获取网关_阿里二面问了这道题:如何设计一个微服务网关系统

    有一天隔壁组的小王灰头土脸的跑过来,问我说:"李哥,你会设计微服务网关系统吗?".我一愣,小王怎么突然问这么抽象的问题,关键是我们最近也没有这样的需求.吃午饭的时候,在我旁敲侧击的 ...

最新文章

  1. Android---Service(生命周期、启动方式、服务通信、实战演练、思维导图、高级音乐播放器-源码)
  2. wxWidgets:wxArrayString类用法
  3. 【转】使用命令行方式创建和启动android模拟器
  4. Python3——文件与异常
  5. 【转载保存】ExecutorService中submit和execute的区别
  6. log解析工具 px4_console.log(console.log) = ?
  7. 路由器-路由器以及×××-Client之间的×××
  8. dede产生.php,怎么加快织梦dedeCMS内容生成速度
  9. linux定时重启脚本
  10. 带你快速入门计算机网络模型与5G协议!!
  11. WebSocket connection to ‘ws://localhost:8081/ws‘ failed: Invalid frame header
  12. HP LaserJet P1108驱动安装
  13. vue 实现数字滚动卡片
  14. Linux兄弟连学习
  15. 第一单元 用python学习微积分(三) 求导四则运算及三角函数(上)- 三角函数
  16. 小白的python学习之路-turtle画不同大小的五角星
  17. 解决mac右键谷歌翻译失效
  18. 985学霸总结的《优雅的Python》火了,完整版开放下载!
  19. java se拖动插件_JQuery之拖拽插件实现代码
  20. 传阿里巴巴集团推迟上市至2015年底

热门文章

  1. 因社会不公大学生找不到工作
  2. pg库使用dblink连接mysql_PG-跨库操作-dblink
  3. 计算机一级b考试电子表格,计算机等级考试一级B第1-50套题
  4. Java基础,双色球系统实现,完整版本,没有BUG,完整代码版
  5. php 执行任务,php多进程执行任务的说明
  6. 矩阵连乘备忘录算法java_矩阵连乘(备忘录方法:自顶向下递归)
  7. csv逗号分隔符转换_文件系统(02):基于SpringBoot管理Xml和CSV
  8. Async和Await如何简化异步编程,几个实例让你彻底明白!
  9. 【洛谷 SP8093】 JZPGYZ - Sevenk Love Oimaster(后缀自动机)
  10. WPF Bitmap转成Imagesource的性能优化