Spring Cloud 学习(1)--- Gateway知识

一、API网关

1、什么是API网关

    API网关作用就是把各个服务对外提供的API汇聚起来,让外界看起来是一个统一的接口。同时也可在网关中提供额外的功能。

    总结:网关就是所有请求的统一入口

2、网关的组成

    网关 = 路由转发 + 过滤器(编写额外的功能)

    2.1、路由转发

    接收外界请求,通过网关的路由转发,转发到后端的服务上。

    如果只有这个一个功能看起来和之前学习的Nginx反向代理服务器很像,外界访问nginx,由nginx做负载均衡,后把请求转发到对应服务器上。

    2.2、过滤器

    网关非常重要的功能就是过滤器。

    过滤器中默认提供了25内置功能还自持额外的自定义功能。

    对于我们来说比较常用的功能有网关的容错、限流以及请求及相应的额外处理。

3、Spring Cloud中提供的网关解决方案

    3.1、Spring Cloud Netflix Zuul

    属于Spring Cloud Netflix下一个组件,具有灵活、简单的特点。在早期Spring Cloud中使用的比较多。

    其版本更新都依赖于Netflix Zuul。

    3.2、Spring Cloud Gateway

    由Spring 自己推出的网关产品,完全依赖Spring自家产品。符合Spring战略意义,其更新版本等都由Spring自己把控。

    目前很多项目中都是使用Gateway替代Zuul。

    在本套课程中讲解的也是Gateway

二、Spring Cloud Gateway介绍

1、简介

    Spring Cloud Gateway是Spring Cloud 的二级子项目,提供了微服务网关功能,包含:权限安全、监控/指标等功能。

2、名词解释

    2.1、Route

    Route中文称为路由,Gateway里面的Route是主要学习内容,一个Gateway项目可以包含多个Route。

    一个路由包含ID、URI、Predicate集合、Filter集合。

    在Route中ID是自定的,URI就是一个地址。剩下的Predicate和Filter看明白了,Route就学习清楚了。

    2.2、Predicate

    中文:谓词。

    谓词时是Gateway比较重要的一点,简单点理解谓词就是一些附加条件和内容。

    2.3、Filter

    所有生效的Filter都是GatewayFilter的实例。在Gateway运行过程中Filter负责在代理服务“之前”或“之后”去做一些事情。

    2.4、流程

    Gateway Client  -> Gateway Handler Mapping -> Gateway Web Handler -> Filter ..... -> Proxy Filter -> Proxy Service

    文字解释:

    网关客户端访问Gateway网关Gateway中Handler Mapping对请求URL进行处理。处理完成后交换Web Handler,Web Handler 会被Filter进行过滤。Filter中前半部分代码是处理请求的代码。处理完成后调用真实被代理的服务。被代理服务响应结果,结果会被Filter中后半部分代码进行操作,操作完成后把结果返回给Web Hanlder,在返回给Handler Mapping,最终响应给客户端。

三、网关基本配置文件(不是零基础直接撸的资料)

谓词中Path一般会给每个项目前面起一个无意义的别名。

如Path = /abc/** 当看到abc是知道路由转发到项目abc,后面的内容才是真实要访问abc的内容

如Path=/jqk/** 表示需要转发到jqk项目。

要明白:uri中第一部分就是为了防止各个项目中出现重名路径导致路由转发失败。

四、谓词

    谓词:当满足条件在进行路由转发。

    在Spring Cloud Gateway中谓词实现GatewayPredicate接口。其中类名符合:XXXRoutepredicateFactory,其中XXX就是在配置文件中谓词名称。在上面示例中Path=/demo/** 实际上使用的就是PathRoutePredicateFactory


    所有的谓词都设置在predicates属性中,当设置多个谓词时取逻辑与条件,且一个谓词只能设置一组条件,如果需要有个多条件,添加多个相同谓词。

1、谓词所有

    1.1、设置必须包含的参数名。

    下面两种写法等效。都表示路径满足/demo/**同时包含参数abc。

    Path和Query是谓词。abc是请求参数名称。

    predicates: Path=/demo/**,Query=abc

    predicates:   

        - Path=/demo/**  

        - Query=abc

    1.2、设置参数值

    abc请求参数名称。jqk. 是abc的值,是一个正则表达式。在正则表达式中点(.)表示匹配任意一个字符。所以当请求参数abc=jqka或abc=jqkw能满足谓词条件。

    在谓词中赋值使用逗号(,)赋值因为Query后面已经有等号,在值内容中在出现等号语法说不过去了。

    predicates: Path=/demo/**,Query=abc

    predicates:

        - Path=/demo/**  

        - Query=abc,jqk.

2、RemoteAddr  

     检查你的客户端ip地址是否符合要求

     要注意使用127.0.0.1而不要使用localhost。

    predicates:

        - Path=/demo/**  

        - RemoteAddr=127.0.0.1

3、Cookie      

    检查cookie必须包含你设置的cookie

    Cookie必须有两个值,第一个Cookie包含的参数名,第二个表示参数对应的值,正则表达式。不支持一个参数写法。

    predicates:    

        - Path=/demo/**  

        - Cookie=age,.*

4、Between  

     在这时间区间内可以访问时间格式  yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai],yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai]

    predicates:

        - Path=/demo/**  

        - Between=yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai],yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai]

5、Before    

    在这时间之前访问不到,这个时间之后才可以访问 yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai]

    predicates:

        - Path=/demo/**  

        - Before=yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai]

6、After    

    在这时间之后不可以访问,在这之前才可以访问 yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai]

    predicates:

        - Path=/demo/**  

        - After=yyyy-MM-ddTHH:mm:ss.sss+08:00[Asia/Shanghai]

7、Weight  

     配置负载均衡也叫配置权重,在请求服务名字不一样功能一样就会根据组的后面的数组来选择哪个服务响应,一般用户版本发布不一样来要求做负载均衡

   语法:Weight=组名,负载均衡权重

在Eureka中注册两个服务,这个服务(项目)是相同的,应用程序名分别叫做demo-one和demo-two。

    Gateway在路由匹配时demo-one将占20%,demo-two将占80%

    routes:

        -id: suiyi

            uri: lb://demo-one

            predicates:

                - Path=/demo/**

                - Weight=group,2

            filters: StripPrefix=1

        -id: suiyi2

            uri: lb://demo-two

            predicates:

                - Path=/demo/**

                - Weight=group,8

            filters: StripPrefix=1

8、Host  

 检验请求头里面的Host里面的值是不是匹配的

? 匹配一个字符

* 匹配0个或多个字符

** 匹配0个或多个目录

predicates:

        - Path=/demo/**  

        - Host=127.0.0.1:9000

9、Header

    表示请求头中必须包含的内容。

    注意:

        参数名和参数值之间依然使用逗号

        参数值要使用正则表达式

    如果Header只有一个值表示请求头中必须包含的参数。如果有两个值,第一个表示请求头必须包含的参数名,第二个表示请求头参数对应值。

    predicates:

        - Path=/demo/**  

        - Query=abc,jqk.

        - Header=Connection,keep-alive

    如果设定请求头中需要包含多个参数及值。设置多个Header。在此处演示多个相同谓词配置,其他谓词中就不在强调可以配置多个谓词。

    predicates:

        - Path=/demo/**  

        - Query=abc,jqk.

        - Header=Connection,keep-alive

        - Header=Cache-Control,max-age=0

10、Method

    Method表示请求方式。支持多个值,使用逗号分隔,多个值之间为or条件。

    predicates:

        - Path=/demo/**  

        - Method = GET,POST

五、Filter

    Filter作用:在路由转发到代理服务之前和代理服务返回结果之后额外做的事情。Filter执行了说明谓词条件通过了。

    在Spring Cloud Gateway的路由中Filter分为:

        内置Filter,都是GatewayFilter实现类

        自定义GlobalFilter

1、内置Filte

    之前使用StripPrefix就是内置Filter,所有内置Filter都实现GatewayFilter接口。使用时filters属性中过滤器名为XXXGatewayFilterFactory的类对应的名称为XXX。

    当过滤器包含参数


下面所有Filter基本都是支持单个值,如果需要设置多个,需要写多个对应Filter

1.1、AddRequestHeader

    添加请求头参数,参数和值之间使用逗号分隔

    filters:  

        - StripPrefix=1  

        - AddRequestHeader=MyHeader,jqk

1.2、AddRequestParameter

    添加请求表单参数,多个参数需要有多个过滤器。

    filters:

        - AddRequestParameter=name,bjsxt 

         - AddRequestParameter=age,123

1.3、AddResponseHeader

    添加响应头

1.4 DedupeResponseHeader

    对指定响应头去重复。

    语法:DedupeResponseHeader=响应头参数  响应头参数,strategy

    可选参数strategy可取值:

        RETAIN_FIRST 默认值,保留第一个

        RETAIN_LAST 保留最后一个

        RETAIN_UNIQUE 保留唯一的,出现重复的属性值,会保留一个。例如有两个My:bbb的属性,最后会只留一个。

    - DedupeResponseHeader=My Content-Type,RETAIN_UNIQUE


1.5 CircuitBreaker

实现熔断时使用,支持CircuitBreaker和Hystrix两种

1.6 FallbackHeaders

可以添加降级时的异常信息

1.7 PrefixPath

匹配所有前缀满足条件的URI

1.8 RequestRateLimiter

限流过滤器。

1.9 RedirectTo 

重定向。有两个参数,status和url。其中status应该300系列重定向状态码

1.10 RemoveRequestHeader

删除请求头参数

1.11 RemoveResponseHeader 

删除响应头参数

1.12 RemoveRequestParameter 

删除请求参数

1.13 RewritePath 

重写请求路径

1.14 RewriteResponseHeader 

重写响应头参数

1.15 SaveSession 

如果项目中使用Spring Security和Spring Session整合时,此属性特别重要

1.16 SecureHeaders 

具有权限验证时,建议的头信息内容。

1.17 SetPath 

功能和StripPrefix有点类似。语法更贴近restful

当前请求路径为/red/blue时会将/blue发送给下游。

spring: 

        cloud:

            gateway:

                routes:

                    - id: setpath_route

                      uri: https://example.org

                       predicates:

                            - Path=/red/{segment}

                        filters:

                            - SetPath=/{segment}

1.18 SetRequestHeader 

替换请求参数头数。不是添加

1.19 SetResponseHeader 

替换响应头参数

1.20 SetStatus 

设置响应状态码

1.21 StripPrefix 

跳过路由uri中前几段后发送给下游

1.22 Retry 

设置重试次数

1.23 RequestSize 

请求最大大小。包含maxSize参数,可以有单位“KB”或“MB”默认为“B”

1.24 ModifyRequestBody 

修改请求体内容

1.25 ModifyResponseBody 

修改响应体

六、使用Gateway实现限流

    可以利用Gateway中RequestRateLimiter实现限流。

1 常见的限流算法

1.1 计数器算法

以QPS(每秒查询率Queries-per-second)为100举例。

从第一个请求开始计时。每个请求让计数器加一。当到达100以后,其他的请求都拒绝。

如果1秒钟内前200ms请求数量已经到达了100,后面800ms中500次请求都被拒绝了,这种情况称为“突刺现象”

1.2 漏桶算法

漏桶算法可以解决突刺现象。

和生活中漏桶一样,有一个水桶,下面有一个”漏眼”往出漏水,不管桶里有多少水,漏水的速率都是一样的。但是既然是一个桶,桶里装的水都是有上限的。当到达了上限新进来的水就装不了(主要出现在突然倒进来大量水的情况)。

1.3 令牌桶算法

令牌桶算法可以说是对漏桶算法的一种改进。

在桶中放令牌,请求获取令牌后才能继续执行。如果桶中没有令牌,请求可以选择进行等待或者直接拒绝。

由于桶中令牌是按照一定速率放置的,所以可以一定程度解决突发访问。如果桶中令牌最多有100个,qps最大为100

2、Gateway中限流

   参数说明:

        key-resolver: 使用SpEL获取Spring容器中实例。

        replenishRate:每秒放入令牌的数量。

        burstCapacity:容量


- name: RequestRateLimiter#限流 下面实现是令牌桶

  args:

        keyResolver:'#{@myKeyResolver}'              #使用springEL表达式,从spring容器中找对象,并赋值。'#{@beanName}' 这里面的值是创建的组件首字母转小写

        redis-rate-limiter.replenishRate: 1#每秒生产的令牌

        redis-rate-limiter.burstCapacity: 5#令牌桶  可以存入多少令牌

myKeyResolver:自己创建的类然而实现KeyResolver 把这个类变为组件@Component

实现:

七、使用Gateway实现服务降级

    实现原理:当连接超时时,使用Gateway自己的一个降级接口返回托底数据,保证程序继续运行,也要导入服务降级的包hystrix,还有像上面一样创建一个类变为组件,RequestMapping的请求地址要放在配置文件一致。

    -name: Hystrix#容错    

      args:#下面的/downgradw是一个controller的地址

            name: fallbackcmd# 给个名字就是分组

            fallbackUri: forward:/downgradw#远程服务错误的时候,Gateway工程中的哪一个控制器逻辑,返回降级结果

八、GlobalFilter

    全局过滤器不需要工厂,也不需要配置,直接对所有的路由都生效。

    可以使用GlobalFilter实现统一的权限验证、日志记录等希望对所有代理的项目都生效的内容都可以配置在全局过滤器中。

    且在项目中可以配置多个GlobalFilter的实现类。都可以自动执行


九、自定义FilterFactory

    可以定义针对于Router的Filter。

    注意:

        1、类名必须叫做XXXGatewayFilterFactory.注入到Spring容器后使用时的名称就叫做XXX。

        2、类必须继承AbstractGatewayFilterFactory

        3、所有需要传递进来的参数都配置到当前类的内部类Config中

总结:使用可以参照gateway那些已经写好了的

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

推荐阅读更多精彩内容