gateway_gateway启动报错 - CSDN
gateway 订阅
Gateway是一家1985年成立于美国爱荷华州的公司,现成长为美国知名的PC品牌,2007年10月被Acer宏碁以7.1亿美元收购该公司。Gateway公司的品牌产品已经通过主要零售商、电子零售商和渠道合作伙伴进入美国、墨西哥、加拿大、日本、中国以及越来越多的亚太地区市场。 展开全文
Gateway是一家1985年成立于美国爱荷华州的公司,现成长为美国知名的PC品牌,2007年10月被Acer宏碁以7.1亿美元收购该公司。Gateway公司的品牌产品已经通过主要零售商、电子零售商和渠道合作伙伴进入美国、墨西哥、加拿大、日本、中国以及越来越多的亚太地区市场。
信息
成立时间
1985年
公司名称
捷威
总部地点
美国南加利福尼亚州
公司类型
股份公司
外文名称
Gateway
经营范围
IT产品
Gateway电脑品牌
Gateway (中文商标:捷威)于 1985 年在美国中西部的一间农舍里创立,已经成长为世界最知名的技术品牌之一,拥有数百万满意的客户。公司创始人泰德-温特(Ted Waitt) 以他祖母向银行担保的 10,000 美元贷款、一台租赁的计算机和一份三页的经营计划起家,将 Gateway 发展成了一个具有革命性意义的公司,它的创新改变了技术产业的面貌。1991 年,公司(原名 Gateway 2000)推出了彰显其牧场起家背景的别具一格的奶牛花斑盒状商标,获得了全国消费者的认可。1993 年,它进入财富 500 强并在 纳斯达克(NASDAQ)上市,随后,在 1997 年转到纽约证券交易所。第二年,Gateway 将其总部从南达科他州的 North Sioux City 迁到了南加利福尼亚州。2004 年 3 月,Gateway 收购了世界上成长最快、效率最高的 PC 制造商之一eMachines。eMachines 是美国第二大个人计算机零售品牌,以低价PC 为主营业务,其技术支持和质量屡获殊荣。 2004年9月,公司将总部迁至加州Irvine。Gateway在中国大陆的昵称为花斑奶牛。 [1]  在创业初期, Gateway开创了业内多个第一。它是第一个提供彩色显示器系统的PC公司,也是第一个提供三年质保的公司,同时也是第一个整合PC和电视功能的厂商。它是直销知名电子消费品并获得成功的公司之一。Gateway是美国第二大PC厂商,居世界前10名。公司的eMachines品牌由国内的著名零售巨头独家销售,而 Gateway的增值产品则通过电话、网络以及直销力量向主要的零售厂商提供。Gateway尊重客户,关注于服务品质和价值的提升。在客户忠诚度方面,其连续多年居于业内之首。2007 年 10 月,Gateway 被总部设在台湾的宏碁公司 (Acer Inc.) 收购,收购后的联合实体现已成为世界第三大 PC 公司。 [2]  2008年,Gateway团队操盘宏碁全球台式机业务,宏碁对台式机业务有更高的期望值,Gateway团队对台式机又有较强的研发及市场经验,因此,决定由GateWay公司的团队操盘其全球台式机业务。Gateway 始终致力追求让客户在购买、拥有和使用 PC 时感到方便无忧这一境界。在 Gateway 向新市场迈进的过程中,公司将继续坚持其最初的目标:通过技术帮助人们提高生活品质。Gateway 产品由指定零售合作伙伴销售。上海市黄浦区西藏中路168号都市总部大厦3楼(200001)2010Gateway 品牌 品牌 电脑报 5月 最佳服务奖Gateway 笔记本 NV49C 中国电脑教育报 6月28日 暑期档最佳产品Gateway 笔记本 NV49C 微型计算机 11月 BUST SHOPPING Gateway产品(4张) Gateway 笔记本 NV49C83C 电脑报 12月20日 2010年度推荐奖Gateway 笔记本 NV4435c 中关村在线 12月 2010年度推荐产品Gateway 台式机 FX6840-000C 中关村在线 12月 2010年度推荐产品Gateway 笔记本 NV59C PConline 12月27日 最佳外观奖Gateway 笔记本 EC39C PConline 12月27日 最佳外观奖Gateway 超便携笔记本 LT3115c PConline 12月27日 编辑选择奖Gateway 笔记本 EC39C PCPOP 12月30日 最佳设计奖Gateway 笔记本 ID49C IT168 1月5日 2010年度产品奖Gateway 笔记本 EC39C 6月 台北国际计算机展2010创新设计奖Gateway 笔记本 EC39C 10月 2010日本优良设计奖Gateway 显示器 FHD2303L 10月 2010日本优良设计奖Gateway 显示器 FHD2303L 12月 iF Product Design Award 产品设计奖Packard Bell笔记本 EasyNote Butterfly 12月 iF Product Design Award 产品设计奖 GTW EC39C与其同样模具Gateway 台式机 FX系列 12月 2011年CES创新与工程设计大奖
收起全文
精华内容
参与话题
  • Gateway网关简介及使用

    万次阅读 多人点赞 2019-10-09 20:54:32
    Gateway网关简介及使用 1. 什么是 API 网关(API Gateway) 分布式服务架构、微服务架构与 API 网关 在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计、开发、测试、部署和管理。这时,各个...

    Gateway网关简介及使用

    1. 什么是 API 网关(API Gateway)

    分布式服务架构、微服务架构与 API 网关

    在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计、开发、测试、部署和管理。这时,各个独立部署单元可以用不同的开发测试团队维护,可以使用不同的编程语言和技术平台进行设计,这就要求必须使用一种语言和平 台无关的服务协议作为各个单元间的通讯方式。

    API 网关的定义

    网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。

    API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。

    API 网关的职能

    API 网关的分类与功能

    2. Gateway是什么

    Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

    3. 为什么用Gateway

    Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。
    Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。
    比如内置了 10 种 Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。
    比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便。

    最重要的几个概念

    4. Gateway怎么用

    说白了 Predicate 就是为了实现一组匹配规则,方便让请求过来找到对应的 Route 进行处理,接下来我们接下 Spring Cloud GateWay 内置几种 Predicate 的使用。

    通过时间匹配

    Predicate 支持设置一个时间,在请求进行转发的时候,可以通过判断在这个时间之前或者之后进行转发。比如我们现在设置只有在 2019 年 1 月 1 日才会转发到我的网站,在这之前不进行转发,我就可以这样配置:

    spring:
      cloud:
        gateway:
          routes:
           - id: time_route
            uri: http://ityouknow.com
            predicates:
             - After=2018-01-20T06:06:06+08:00[Asia/Shanghai]
    
    
    

    Spring 是通过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai

    After Route Predicate 是指在这个时间之后的请求都转发到目标地址。上面的示例是指,请求时间在 2018 年 1 月 20 日 6 点 6 分 6 秒之后的所有请求都转发到地址http://ityouknow.com+08:00是指时间和 UTC 时间相差八个小时,时间地区为Asia/Shanghai

    添加完路由规则之后,访问地址http://localhost:8080会自动转发到http://ityouknow.com

    Before Route Predicate 刚好相反,在某个时间之前的请求的请求都进行转发。我们把上面路由规则中的 After 改为 Before,如下:

    spring:
      cloud:
        gateway:
          routes:
           - id: after_route
            uri: http://ityouknow.com
            predicates:
             - Before=2018-01-20T06:06:06+08:00[Asia/Shanghai]
    
    
    

    就表示在这个时间之前可以进行路由,在这时间之后停止路由,修改完之后重启项目再次访问地址http://localhost:8080,页面会报 404 没有找到地址。

    除过在时间之前或者之后外,Gateway 还支持限制路由请求在某一个时间段范围内,可以使用 Between Route Predicate 来实现。

    spring:
      cloud:
        gateway:
          routes:
           - id: after_route
            uri: http://ityouknow.com
            predicates:
             - Between=2018-01-20T06:06:06+08:00[Asia/Shanghai], 2019-01-20T06:06:06+08:00[Asia/Shanghai]
    
    
    

    这样设置就意味着在这个时间段内可以匹配到此路由,超过这个时间段范围则不会进行匹配。通过时间匹配路由的功能很酷,可以用在限时抢购的一些场景中。

    通过 Cookie 匹配

    Cookie Route Predicate 可以接收两个参数,一个是 Cookie name , 一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。

    spring:
      cloud:
        gateway:
          routes:
           - id: cookie_route
             uri: http://ityouknow.com
             predicates:
             - Cookie=ityouknow, kee.e
    
    
    

    使用 curl 测试,命令行输入:

    curl http://localhost:8080 --cookie "ityouknow=kee.e"
    
    
    

    则会返回页面代码,如果去掉--cookie "ityouknow=kee.e",后台汇报 404 错误。

    Header Route Predicate 和 Cookie Route Predicate 一样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。

    spring:
      cloud:
        gateway:
          routes:
          - id: header_route
            uri: http://ityouknow.com
            predicates:
            - Header=X-Request-Id, \d+
    
    
    

    使用 curl 测试,命令行输入:

    curl http://localhost:8080  -H "X-Request-Id:666666" 
    
    
    

    则返回页面代码证明匹配成功。将参数-H "X-Request-Id:666666"改为-H "X-Request-Id:neo"再次执行时返回 404 证明没有匹配。

    通过 Host 匹配

    Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则。

    spring:
      cloud:
        gateway:
          routes:
          - id: host_route
            uri: http://ityouknow.com
            predicates:
            - Host=**.ityouknow.com
    
    
    

    使用 curl 测试,命令行输入:

    curl http://localhost:8080  -H "Host: www.ityouknow.com" 
    curl http://localhost:8080  -H "Host: md.ityouknow.com" 
    
    
    

    经测试以上两种 host 均可匹配到 host_route 路由,去掉 host 参数则会报 404 错误。

    通过请求方式匹配

    可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由。

    spring:
      cloud:
        gateway:
          routes:
          - id: method_route
            uri: http://ityouknow.com
            predicates:
            - Method=GET
    
    
    

    使用 curl 测试,命令行输入:

    # curl 默认是以 GET 的方式去请求
    curl http://localhost:8080
    
    
    

    测试返回页面代码,证明匹配到路由,我们再以 POST 的方式请求测试。

    # curl 默认是以 GET 的方式去请求
    curl -X POST http://localhost:8080
    
    
    

    返回 404 没有找到,证明没有匹配上路由

    通过请求路径匹配

    Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。

    spring:
      cloud:
        gateway:
          routes:
          - id: host_route
            uri: http://ityouknow.com
            predicates:
            - Path=/foo/{segment}
    
    
    

    如果请求路径符合要求,则此路由将匹配,例如:/foo/1 或者 /foo/bar。

    使用 curl 测试,命令行输入:

    curl http://localhost:8080/foo/1
    curl http://localhost:8080/foo/xx
    curl http://localhost:8080/boo/xx
    
    
    

    经过测试第一和第二条命令可以正常获取到页面返回值,最后一个命令报 404,证明路由是通过指定路由来匹配。

    通过请求参数匹配

    Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。

    spring:
      cloud:
        gateway:
          routes:
          - id: query_route
            uri: http://ityouknow.com
            predicates:
            - Query=smile
    
    
    

    这样配置,只要请求中包含 smile 属性的参数即可匹配路由。

    使用 curl 测试,命令行输入:

    curl localhost:8080?smile=x&id=2
    
    
    

    经过测试发现只要请求汇总带有 smile 参数即会匹配路由,不带 smile 参数则不会匹配。

    还可以将 Query 的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由。

    spring:
      cloud:
        gateway:
          routes:
          - id: query_route
            uri: http://ityouknow.com
            predicates:
            - Query=keep, pu.
    
    
    
    

    这样只要当请求中包含 keep 属性并且参数值是以 pu 开头的长度为三位的字符串才会进行匹配和路由。

    使用 curl 测试,命令行输入:

    curl localhost:8080?keep=pub
    
    
    
    

    测试可以返回页面代码,将 keep 的属性值改为 pubx 再次访问就会报 404, 证明路由需要匹配正则表达式才会进行路由。

    通过请求 ip 地址进行匹配

    Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号 (IPv4 或 IPv6) 字符串的列表(最小大小为 1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。

    spring:
      cloud:
        gateway:
          routes:
          - id: remoteaddr_route
            uri: http://ityouknow.com
            predicates:
            - RemoteAddr=192.168.1.1/24
    
    
    

    可以将此地址设置为本机的 ip 地址进行测试。

    果请求的远程地址是 192.168.1.10,则此路由将匹配。

    组合使用

    上面为了演示各个 Predicate 的使用,我们是单个单个进行配置测试,其实可以将各种 Predicate 组合起来一起使用。

    例如:

    spring:
      cloud:
        gateway:
          routes:
           - id: host_foo_path_headers_to_httpbin
            uri: http://ityouknow.com
            predicates:
            - Host=**.foo.org
            - Path=/headers
            - Method=GET
            - Header=X-Request-Id, \d+
            - Query=foo, ba.
            - Query=baz
            - Cookie=chocolate, ch.p
            - After=2018-01-20T06:06:06+08:00[Asia/Shanghai]
    
    
    

    各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。

    一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发

    展开全文
  • 微服务gateway 简单总结

    千次阅读 2019-10-17 18:06:26
    API 网关(API Gateway)主要负责服务请求路由、组合及协议转换。下面是大家的总结: 一、最佳回答 网关的技术选型 SpringCloud-Zuul : 社区活跃,基于 SrpingCloud 完整生态, 是构建微服务体系前置网关服务的...

    用 Spring Cloud 微服务实战中,大家都知道用 Zuul 作为智能网关。API 网关(API Gateway)主要负责服务请求路由、组合及协议转换。下面是大家的总结:

    一、最佳回答

    网关的技术选型

    1. SpringCloud-Zuul :

      社区活跃,基于 SrpingCloud 完整生态, 是构建微服务体系前置网关服务的最佳选型.

    2. Kong : 基于OpenResty的 API 网关服务和网关服务管理层.

    3. 自建网关服务: 如 谈谈基于 OpenResty 的接口网关设计

    网关的设计要素

    系统级别

    • 高可用性
    • 均衡负载: 容错,防止雪崩.
    • 并发控制 : 错峰流控
    • 动态路由制定和修改

    应用级别

    • 监控统计
    • 版本控制
    • 认证 鉴权
    • 数据安全: 防篡改,参数脱敏…
    • 协议转换: 如 HTTP => RPC协议.

    其他(个人 YY)

    • 基于机器学习, 预测流量高峰.

    二、此时此刻的总结

    1. 网关(API Gateway)技术选型

      • zuul
      • kong
      • nginx+lua
    2. 网关(API Gateway)的设计要素

      • 限流:实现微服务访问流量计算,基于流量计算分析进行限流,可以定义多种限流规则。
      • 缓存:数据缓存。
      • 日志:日志记录。
      • 监控:记录请求响应数据,api耗时分析,性能监控。
      • 鉴权:权限身份认证。
      • 灰度:线上灰度部署,可以减小风险。
      • 路由:路由是API网关很核心的模块功能,此模块实现根据请求,锁定目标微服务并将请求进行转发。
    3. 简单介绍下你的网关实施方案

      • 开发语言:java + groovy,groovy的好处是网关服务不需要重启就可以动态的添加filter来实现一些功能;
      • 微服务基础框架:springboot;
      • 网关基础组件:netflix zuul;
      • 服务注册中心:consul;
      • 权限校验:jwt;
      • API监控:prometheus + grafana;
      • API统一日志收集:logback + ELK;
      • 压力测试:Jmeter;

    比如限流 你需要缓存一些限流的策略,主要是缓存网关功能用到的一些数据,不涉及业务数据。 路由主要是做转发

    三、IronCity 的总结

    目前,我们业务代码是多语言的环境,网关则是用go写的,目前主要是做到了对于HTTP和Thrift的业务服务的转发(HTTP利用了fasthttp,Thrift用的网关启动客户端调用业务服务端的形式)过滤器是环绕的,系统统一的过滤和针对API级别的过滤。虽然用了go比较轻巧,但是目前功能还很值得完善

    四、XuChuangfeng 的总结

    设计要素:#1,高可用非常重要;#2,网关需要支持动态修改路由规则;#3,与服务注册中心整合,通过注册中心实现路由转发;#4,过滤器链适配不同的路由。

    五、fudali113 的总结

    选型

    • 所使用的网关架构必须灵活,因为我们可能需要很多与我们业务相关的定制话的东西
    • 有平台背书,获取有足够的证据证明他是一个能抗的住我们需求的并发的性能
    • 根据需求选择最好的方案

      设计要素

    • 结构必须灵活,方便扩展
    • 基础的功能应该由框架提供或者抽象,比如动态路由,权限校验,限流

      我的

      我们使用zuul作为网关并对他进行了一定定制化的开发,因为我们使用springcloud技术栈,同时zuul基于filter来处理一切的结构也是非常灵活的,并且由netflix背书。我们在网关利用filter加入权限校验,统一访问日志记录,访问异常请求记录,聚合请求处理器等相关功能

    负载均衡可以通过在之前加入一个nginx或者dns解析来做,高可用可以通过keepalived加虚拟ip与nginx结合或者直接与zuul结合来做

    六、Ascend 总结

    1. 能处理一些公共的逻辑,比如获取token
    2. 能支持动态的修改路由规则
    3. 对各服务结果和异常进行统一处理后返给调用方
      目前实施了几套方案,自己封装的gateway层,准备用zuul进行替代

    七、曼陀罗 总结

    网关的技术选型

    1. SpringCloud-Zuul :社区活跃,基于 SrpingCloud 完整生态, 是构建微服务体系前置网关服务的最佳选型.
    2. Kong : 基于OpenResty的 API 网关服务和网关服务管理层.
    3. Nginx+Lua:成熟度也算可以
    4. 自建网关:成本较高

    网关(API Gateway)的设计要素(高可用,安全)

    • 性能:API高可用,负载均衡,容错机制。
    • 安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
    • 日志:日志记录(spainid,traceid)一旦涉及分布式,全链路跟踪必不可少。
    • 缓存:数据缓存。
    • 监控:记录请求响应数据,api耗时分析,性能监控。
    • 限流:流量控制,错峰流控,目前有漏桶算法、令牌桶算法也可以定制限流规则。
    • 灰度:线上灰度部署,可以减小风险。
    • 路由:动态路由规则。
    • 静态:代理

    简单介绍下你的网关实施方案

    • 微服务基础框架:springboot;
    • 网关基础组件:zuul;
    • 服务注册中心:consul;
    • API监控:prometheus + grafana or 自建;
    • API统一日志收集:时序db + ELK;
    • 压力测试:Jmeter,AB,阿里压测;

     

    展开全文
  • Spring Cloud Gateway初体验

    万次阅读 多人点赞 2019-09-30 17:54:33
    https://www.fangzhipeng.com/springcloud/2018/11/06/sc-f-gateway1/ 本文出自方志朋的博客 这篇文章讲述了如何简单地使用Spring Cloud Gateway,来源于Spring Cloud官方案例,地址...

    转载请标明出处:
    http://blog.csdn.net/forezp/article/details/83792388
    本文出自方志朋的博客

    点击获取SpringCloud 、Spring Boot视频

    这篇文章讲述了如何简单地使用Spring Cloud Gateway,来源于Spring Cloud官方案例,地址https://spring.io/guides/gs/gateway 。

    简介

    Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。本文首先用官方的案例带领大家来体验下Spring Cloud的一些简单的功能,在后续文章我会使用详细的案例和源码解析来详细讲解Spring Cloud Gateway.

    创建工程

    本案例的的源码下载于官方案例,也可以在我的Github上下载。工程使用的Spring Boot版本为2.0.5.RELEASE,Spring Cloud版本为Finchley.SR1。

    新建一个工程,取名为sc-f-gateway-first-sight在工程的pom文件引用工程所需的依赖,包括spring boot和spring cloud,以及gateway的起步依赖spring-cloud-starter-gateway,代码如下:

       <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.5.RELEASE</version>
        </parent>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
     <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    

    ** 注:详细的pom文件依赖,可以见源码。**

    创建一个简单的路由

    在spring cloud gateway中使用RouteLocator的Bean进行路由转发,将请求进行处理,最后转发到目标的下游服务。在本案例中,会将请求转发到http://httpbin.org:80这个地址上。代码如下:

    
    @SpringBootApplication
    @RestController
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
        @Bean
        public RouteLocator myRoutes(RouteLocatorBuilder builder) {
           return builder.routes()
            .route(p -> p
                .path("/get")
                .filters(f -> f.addRequestHeader("Hello", "World"))
                .uri("http://httpbin.org:80"))
            .build();
        }
        
        }
    

    在上面的myRoutes方法中,使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路由RouteLocatorBuilder可以让你添加各种predicatesfilters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的route去处理,filters是各种过滤器,用来对请求做各种判断和修改。

    上面创建的route可以让请求“/get”请求都转发到“http://httpbin.org/get”。在route配置上,我们添加了一个filter,该filter会将请求添加一个header,key为hello,value为world。

    启动springboot项目,在浏览器上http://localhost:8080/get,浏览器显示如下:

    {
      "args": {}, 
      "headers": {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", 
        "Accept-Encoding": "gzip, deflate, br", 
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", 
        "Cache-Control": "max-age=0", 
        "Connection": "close", 
        "Cookie": "_ga=GA1.1.412536205.1526967566; JSESSIONID.667921df=node01oc1cdl4mcjdx1mku2ef1l440q1.node0; screenResolution=1920x1200", 
        "Forwarded": "proto=http;host=\"localhost:8080\";for=\"0:0:0:0:0:0:0:1:60036\"", 
        "Hello": "World", 
        "Host": "httpbin.org", 
        "Upgrade-Insecure-Requests": "1", 
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36", 
        "X-Forwarded-Host": "localhost:8080"
      }, 
      "origin": "0:0:0:0:0:0:0:1, 210.22.21.66", 
      "url": "http://localhost:8080/get"
    }
    
    

    可见当我们向gateway工程请求“/get”,gateway会将工程的请求转发到“http://httpbin.org/get”,并且在转发之前,加上一个filter,该filter会将请求添加一个header,key为hello,value为world。

    注意HTTPBin展示了请求的header hello和值world。

    使用Hystrix

    在spring cloud gateway中可以使用Hystrix。Hystrix是 spring cloud中一个服务熔断降级的组件,在微服务系统有着十分重要的作用。
    Hystrix是 spring cloud gateway中是以filter的形式使用的,代码如下:

       @Bean
        public RouteLocator myRoutes(RouteLocatorBuilder builder) {
            String httpUri = "http://httpbin.org:80";
            return builder.routes()
                .route(p -> p
                    .path("/get")
                    .filters(f -> f.addRequestHeader("Hello", "World"))
                    .uri(httpUri))
                .route(p -> p
                    .host("*.hystrix.com")
                    .filters(f -> f
                        .hystrix(config -> config
                            .setName("mycmd")
                            .setFallbackUri("forward:/fallback")))
                    .uri(httpUri))
                .build();
        }
    
    

    在上面的代码中,我们使用了另外一个router,该router使用host去断言请求是否进入该路由,当请求的host有“*.hystrix.com”,都会进入该router,该router中有一个hystrix的filter,该filter可以配置名称、和指向性fallback的逻辑的地址,比如本案例中重定向到了“/fallback”。

    现在写的一个“/fallback”的l逻辑:

    
     @RequestMapping("/fallback")
        public Mono<String> fallback() {
            return Mono.just("fallback");
        }
    
    

    Mono是一个Reactive stream,对外输出一个“fallback”字符串。

    使用curl执行以下命令:

     curl --dump-header - --header 'Host: www.hystrix.com' http://localhost:8080/delay/3
    
    

    返回的响应为:

    fallback
    

    可见,带hostwww.hystrix.com的请求执行了hystrix的fallback的逻辑。

    总结

    本文通过官方的一个简单的案例,来讲解了spring cloud gateway的简单用法,在spring cloud gateway中有2个重要的概念predicatesfilters,它们个将会在后续文章讲解。敬请期待。

    源码下载

    https://github.com/forezp/SpringCloudLearning/tree/master/sc-f-gateway-first-sight

    更多阅读

    史上最简单的 SpringCloud 教程汇总

    SpringBoot教程汇总

    Java面试题系列汇总


    扫码关注公众号有惊喜

    (转载本站文章请注明作者和出处 方志朋的博客

    展开全文
  • SpringCloud之服务网关Gateway

    万次阅读 多人点赞 2020-03-15 17:19:57
    Spring Cloud Gateway 是 Spring Cloud 新推出的网关框架,之前是Netflix Zuul。网关通常在项目中为了简化 前端的调用逻辑,同时也简化内部服务之间互相调用的复杂度;具体作用就是转发服务,接收并转发所有内外 ...

    前言

      SpringCloud 是微服务中的翘楚,最佳的落地方案。

      Spring Cloud Gateway 是 Spring Cloud 新推出的网关框架,之前是 Netflix Zuul。网关通常在项目中为了简化

      前端的调用逻辑,同时也简化内部服务之间互相调用的复杂度;具体作用就是转发服务,接收并转发所有内外

      部的客户端调用;其他常见的功能还有权限认证,限流控制等等。

      本博客会提到网关的基本转发功能熔断功能限流功能以及功能的综合使用

    源码

      GitHub地址:https://github.com/intomylife/SpringCloud

    环境

    • JDK 1.8.0 +
    • Maven 3.0 +
    • SpringBoot 2.0.3
    • SpringCloud Finchley.RELEASE
    • Redis 3.0 +

    开发工具

    • IntelliJ IDEA

    正文

    commons 工程

    commons 工程 - POM 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <!-- 三坐标 -->
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-gateway-commons</artifactId>
        <version>1.0</version>
    
        <!-- 工程名称和描述 -->
        <name>springcloud-gateway-commons</name>
        <description>公用工程</description>
    
        <!-- 打包方式 -->
        <packaging>jar</packaging>
    
        <!-- 在 properties 下声明相应的版本信息,然后在 dependency 下引用的时候用 ${} 就可以引入该版本 jar 包了 -->
        <properties>
            <!-- 编码 -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!-- jdk -->
            <java.version>1.8</java.version>
    
            <!-- SpringBoot -->
            <platform-bom.version>Cairo-SR3</platform-bom.version>
    
            <!-- SpringCloud -->
            <spring-cloud-dependencies.version>Finchley.RELEASE</spring-cloud-dependencies.version>
        </properties>
    
        <!-- 加入依赖 -->
        <dependencies>
    
        </dependencies>
    
        <!-- 依赖 jar 包版本管理的管理器 -->
        <!-- 如果 dependencies 里的 dependency 自己没有声明 version 元素,那么 maven 就此处来找版本声明。 -->
        <!-- 如果有,就会继承它;如果没有就会报错,告诉你没有版本信息 -->
        <!-- 优先级:如果 dependencies 里的 dependency 已经声明了版本信息,就不会生效此处的版本信息了 -->
        <dependencyManagement>
            <dependencies>
                <!-- SpringBoot -->
                <dependency>
                    <groupId>io.spring.platform</groupId>
                    <artifactId>platform-bom</artifactId>
                    <version>${platform-bom.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!-- SpringCloud -->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud-dependencies.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <!-- 插件依赖 -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    • 配置一些共用依赖

    commons 工程 - 项目结构

     

    service 工程

      ① 此工程下有四个模块:一个注册中心,一个网关以及两个提供者

      ② 两个提供者除端口不一致以外,其他代码基本一致

     

    registry-service(注册中心)

    registry-service - POM 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <!-- 继承父 -->
        <parent>
            <groupId>com.zwc</groupId>
            <artifactId>springcloud-gateway-service</artifactId>
            <version>1.0</version>
        </parent>
    
        <!-- 三坐标 -->
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-gateway-registry-service</artifactId>
        <version>1.0</version>
    
        <!-- 工程名称描述 -->
        <name>springcloud-gateway-registry-service</name>
        <description>注册中心</description>
    
        <!-- 打包方式 -->
        <packaging>jar</packaging>
    
        <!-- 在 properties下声明相应的版本信息,然后在dependency下引用的时候用 ${} 就可以引入该版本jar包了 -->
        <properties>
    
        </properties>
    
        <!-- 加入依赖 -->
        <dependencies>
            <!-- 服务注册中心 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    
        <!-- 插件依赖 -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    • 主要加入 spring-cloud-starter-netflix-eureka-server 依赖

    registry-service - application.yml 配置文件

    # 端口
    server:
      port: 8761
    
    # 应用名称
    spring:
      application:
        name: eureka-server
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        # 是否向注册中心注册自己
        registerWithEureka: false
        # 是否向注册中心获取注册信息
        fetchRegistry: false
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    • 这里使用了默认的 8761 端口,当然也可以更改,不过在发现调用服务端的注册中心地址端口要与它一致

    registry-service - 启动类

    package com.zwc;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class SpringcloudGatewayRegistryServiceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringcloudGatewayRegistryServiceApplication.class, args);
        }
    
    }
    
    • 在启动类中添加 @EnableEurekaServer 注解表示此工程是注册中心

    registry-service - 启动项目

      1. 项目启动成功后访问 http://localhost:8761/ 即可看到 eureka-server 主页面

     

      注:由于服务工程 A 和服务工程 B 除端口不一致以外,其他代码基本一致,所以服务工程 B 不再赘述

    a-service(服务工程 A)

    a-service - POM 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <!-- 继承父 -->
        <parent>
            <groupId>com.zwc</groupId>
            <artifactId>springcloud-gateway-a-service</artifactId>
            <version>1.0</version>
        </parent>
    
        <!-- 三坐标 -->
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-gateway-a-service-core</artifactId>
        <version>1.0</version>
    
        <!-- 工程名称描述 -->
        <name>springcloud-gateway-a-service-core</name>
        <description>服务工程 - A 核心</description>
    
        <!-- 打包方式 -->
        <packaging>jar</packaging>
    
        <!-- 在 properties下声明相应的版本信息,然后在dependency下引用的时候用 ${} 就可以引入该版本jar包了 -->
        <properties>
    
        </properties>
    
        <!-- 加入依赖 -->
        <dependencies>
            <!-- commons工程 依赖 -->
            <dependency>
                <groupId>com.zwc</groupId>
                <artifactId>springcloud-gateway-commons</artifactId>
                <version>1.0</version>
            </dependency>
    
            <!-- api工程 依赖 -->
            <dependency>
                <groupId>com.zwc</groupId>
                <artifactId>springcloud-gateway-a-service-api</artifactId>
                <version>1.0</version>
            </dependency>
    
            <!-- springboot web 依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- 提供者消费者 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
        </dependencies>
    
        <!-- 插件依赖 -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    • 加入 spring-cloud-starter-netflix-eureka-client 依赖

    a-service - application.yml 配置文件

    # 端口
    server:
      port: 9000
    
    # 应用名称
    spring:
      application:
        name: gateway-service
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    • 注意此处配置注册中心地址的端口为 8761 也就是上面注册中心工程配置的端口

    a-service - controller 前端控制器(提供服务)

    package com.zwc.a.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /*
     * @ClassName ASayHelloController
     * @Desc TODO   Say Hello
     * @Date 2019/5/20 23:24
     * @Version 1.0
     */
    @RestController
    public class ASayHelloController {
    
        /*
         * @ClassName ASayHelloController
         * @Desc TODO   读取配置文件中的端口
         * @Date 2019/5/20 23:24
         * @Version 1.0
         */
        @Value("${server.port}")
        private String port;
    
        /*
         * @ClassName ASayHelloController
         * @Desc TODO   Say Hello
         * @Date 2019/5/20 23:24
         * @Version 1.0
         */
        @RequestMapping("/hello")
        public String hello(){
            return "Hello!I'm a. port:" + port;
        }
    
        /*
         * @ClassName ASayHelloController
         * @Desc TODO   接收从网关传入的参数
         * @Date 2019/6/23 16:28
         * @Version 1.0
         */
        @RequestMapping("/name")
        public String name(String name){
            return "My name is " + name + ". aaa";
        }
    
        /*
         * @ClassName ASayHelloController
         * @Desc TODO   接收从网关传入的参数
         * @Date 2019/6/23 16:52
         * @Version 1.0
         */
        @RequestMapping("/age")
        public String age(String age){
            return "I am " + age + " years old this year. aaa";
        }
    
        /*
         * @ClassName ASayHelloController
         * @Desc TODO   接收从网关传入的参数
         * @Date 2019/6/29 22:00
         * @Version 1.0
         */
        @RequestMapping("/routeAll")
        public String routeAll(String pass) {
            return "Can I pass? " + pass + "! port:" + port;
        }
    
    }
    
    • 提供输出字符串服务,供网关调用

    a-service - 启动类

    package com.zwc;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class SpringcloudGatewayAServiceCoreApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringcloudGatewayAServiceCoreApplication.class, args);
        }
    
    }
    
    • 添加 @EnableEurekaClient 注解表示此工程可以向注册中心提供服务

    a-service - 启动项目

      1. 刷新 http://localhost:8761/(注册中心)可以看到服务已经被注册进来了

      2. 项目启动成功后访问:http://localhost:9000/hello

      3. 输出内容:'Hello!I'm a. port:9000'

      4. 同样启动服务工程 B后,刷新 http://localhost:8761/(注册中心)

      5. 项目启动成功后访问:http://localhost:9001/hello

      6. 输出内容:'Hello!I'm b. port:9001'

      7. 其他接口是下面网关服务启动后转发调用的,也是本博客的重头戏

     

    master-service(网关)

    master-service - POM 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <!-- 继承父 -->
        <parent>
            <groupId>com.zwc</groupId>
            <artifactId>springcloud-gateway-service</artifactId>
            <version>1.0</version>
        </parent>
    
        <!-- 三坐标 -->
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-gateway-master-service</artifactId>
        <version>1.0</version>
    
        <!-- 工程名称描述 -->
        <name>springcloud-gateway-master-service</name>
        <description>Spring Cloud Gateway 服务网关</description>
    
        <!-- 打包方式 -->
        <packaging>jar</packaging>
    
        <!-- 在 properties下声明相应的版本信息,然后在 dependency 下引用的时候用 ${} 就可以引入该版本 jar 包了 -->
        <properties>
            <!-- ali json -->
            <fastjson.version>1.2.47</fastjson.version>
        </properties>
    
        <!-- 加入依赖 -->
        <dependencies>
            <!-- 提供者消费者 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <!-- gateway -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    
            <!-- redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
            </dependency>
    
            <!-- hystrix -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
    
            <!-- ali json依赖 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
        </dependencies>
    
        <!-- 插件依赖 -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    • 加入 spring-cloud-starter-netflix-eureka-client 依赖:提供和注册服务
    • 加入 spring-cloud-starter-gateway 依赖:gateway
    • 加入 spring-boot-starter-data-redis-reactive 依赖:结合 Redis 限流
    • 加入 spring-cloud-starter-netflix-hystrix 依赖:熔断器

    master-service - application.yml 配置文件

    # 端口
    server:
      port: 8000
    
    spring:
      profiles:
        # 指定配置
        # route_simple:简单尝试
        # route_stripPrefix:截取请求
        # route_uri:转发指定地址并传入参数
        # route_addRequestParameter:转发指定服务并传入参数
        # route_hystrix:熔断
        # route_requestRateLimiter:限流
        # route_all:综合
        active: route_simple
    
    ---
    
    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 简单尝试
      profiles: route_simple
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   简单尝试
          - id: route_simple
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: https://www.zouwencong.com
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 转发地址格式为 uri/archive
            - Path=/archive
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    
    ---
    
    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 截取请求
      profiles: route_stripPrefix
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   截取请求
          - id: route_simple
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: https://www.zouwencong.com
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 转发地址格式为 uri/archive,/str 部分会被下面的过滤器给截取掉
            - Path=/str/archive
            filters:
            ## 截取路径位数
            - StripPrefix=1
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    
    ---
    
    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 转发指定地址并传入参数
      profiles: route_uri
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   转发指定地址并传入参数
          - id: route_uri
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: http://localhost:9000
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=name, zwc
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    
    ---
    
    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 转发指定服务并传入参数
      profiles: route_addRequestParameter
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   转发指定服务并传入参数
          - id: route_addRequestParameter
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=age, three
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    
    ---
    
    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 熔断
      profiles: route_hystrix
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   熔断
          - id: route_hystrix
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=age, three
            ## 熔断
            - name: Hystrix
              args:
                name: fallbackcmd
                ### fallback 时调用的方法 http://localhost:8000/fallback
                fallbackUri: forward:/fallback
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    
    ---
    
    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 限流
      profiles: route_requestRateLimiter
      redis:
        host: localhost
        port: 6379
        database: 0
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   限流
          - id: route_requestRateLimiter
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=age, three
            ## 限流
            - name: RequestRateLimiter
              args:
                ### 限流过滤器的 Bean 名称
                key-resolver: '#{@uriKeyResolver}'
                ### 希望允许用户每秒处理多少个请求
                redis-rate-limiter.replenishRate: 1
                ### 用户允许在一秒钟内完成的最大请求数
                redis-rate-limiter.burstCapacity: 3
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    
    ---
    
    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 综合
      profiles: route_all
      redis:
        host: localhost
        port: 6379
        database: 0
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   综合
          - id: route_all
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 转发地址格式为 uri/routeAll,/all 部分会被下面的过滤器给截取掉
            - Path=/all/routeAll
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 截取路径位数
            - StripPrefix=1
            ## 添加指定参数
            - AddRequestParameter=pass, yes
            ## 熔断
            - name: Hystrix
              args:
                name: fallbackcmd
                ### fallback 时调用的方法 http://localhost:8000/fallback
                fallbackUri: forward:/fallback
            ## 限流
            - name: RequestRateLimiter
              args:
                ### 限流过滤器的 Bean 名称
                key-resolver: '#{@uriKeyResolver}'
                ### 希望允许用户每秒处理多少个请求
                redis-rate-limiter.replenishRate: 1
                ### 用户允许在一秒钟内完成的最大请求数
                redis-rate-limiter.burstCapacity: 3
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    • 注意配置注册中心地址的端口都为 8761 也就是上面注册中心工程配置的端口
    • 每一对 '---' 符号中的配置文件都是单独的,使用 spring.profiles.active 指定
    • 每一对 '---' 符号中的配置文件都只配置了一个 route(路由)
    • route(路由)由四部分组成,其中 filters 不是必须参数
    • 唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)

     

    master-service - 简单尝试

    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 简单尝试
      profiles: route_simple
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   简单尝试
          - id: route_simple
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: https://www.zouwencong.com
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 转发地址格式为 uri/archive
            - Path=/archive

      1. 停止注册中心工程(registry-service)、服务工程 A 和服务工程 B

      2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_simple

      3. 上面配置文件内容意思是当访问 http://localhost:8000/archive (网关地址/archive)

          会被转发到 https://www.zouwencong.com/archive/ (uri/archive)

      4. 启动注册中心工程(registry-service)和网关工程(master-service)

      5. 项目启动成功后访问:http://localhost:8000/archive

      6. 发现页面会自动被跳转到:https://www.zouwencong.com/archive/

      7. 证明服务转发成功

     

    master-service - 截取请求

    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 截取请求
      profiles: route_stripPrefix
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   截取请求
          - id: route_simple
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: https://www.zouwencong.com
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 转发地址格式为 uri/archive,/str 部分会被下面的过滤器给截取掉
            - Path=/str/archive
            filters:
            ## 截取路径位数
            - StripPrefix=1
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug
    

      1. 停止注册中心工程(registry-service)和网关工程(master-service)

      2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_stripPrefix

      3. 上面配置文件内容意思是访问的路径 http://localhost:8000/str/archive (网关地址/str/archive)截取 /str 部分,

          截取后被转发到 https://www.zouwencong.com/archive/ (uri/archive)

      4. 启动注册中心工程(registry-service)和网关工程(master-service)

      5. 项目启动成功后访问:http://localhost:8000/str/archive

      6. 发现页面会自动被跳转到:https://www.zouwencong.com/archive/

      7. 证明路径被截取并服务转发成功

     

    master-service - 转发指定地址并传入参数

    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 转发指定地址并传入参数
      profiles: route_uri
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   转发指定地址并传入参数
          - id: route_uri
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: http://localhost:9000
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=name, zwc
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug

      1. 停止注册中心工程(registry-service)和网关工程(master-service)

      2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_uri

      3. 上面配置文件内容意思是访问的路径 http://localhost:8000/name (网关地址/name)

          会被转发到 http://localhost:9000/name(uri/name),并传入 'name=zwc' 参数(注意为 Get 请求)

      4. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A(a-service)

      5. 项目启动成功后访问:http://localhost:8000/name

      6. 输出内容:'My name is zwc. aaa'(通过网关转发 - 参数有值)

      7. 打开新页面访问:http://localhost:9000/name

      8. 输出内容:'My name is null. aaa'(直接访问 - 参数没有值)

      9. 证明转发指定地址并传入参数成功

     

    master-service - 转发指定服务并传入参数

    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 转发指定服务并传入参数
      profiles: route_addRequestParameter
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   转发指定服务并传入参数
          - id: route_addRequestParameter
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=age, three
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug

      1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A(a-service)

      2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值

          更改为 route_addRequestParameter

      3. 上面配置文件内容意思是访问的路径 http://localhost:8000/age (网关地址/age)

          会被转发到 http://gateway-service/age(uri/age),并传入 'age=three' 参数(注意为 Get 请求)

      4. 注意此处的配置 uri: lb://gateway-service 与之前都有所不同,之前都是指定了明确的转发地址,可以满足

          单个服务转发的需求,但是一般情况都会有多个服务,所以这里是指定的服务名称,格式为:lb://应用注册

          服务名。

      5. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)

      6. 项目启动成功后访问:http://localhost:8000/age

      7. 这时可能会报错 500.错误信息为 'Unable to find instance for gateway-service'

      8. 这种情况不要慌张,只是服务还没有被注册到注册中心,稍等片刻再访问

      9. 多次访问:http://localhost:8000/age

     10. 轮流输出内容:'I am three years old this year. aaa'  'I am three years old this year. bbb'

     11. 此时还通过网关达到了负载均衡的效果

     12. 证明转发指定服务并传入参数成功

     

    master-service - 熔断

    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 熔断
      profiles: route_hystrix
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   熔断
          - id: route_hystrix
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=age, three
            ## 熔断
            - name: Hystrix
              args:
                name: fallbackcmd
                ### fallback 时调用的方法 http://localhost:8000/fallback
                fallbackUri: forward:/fallback
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug

      1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)

      2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_hystrix

      3. 上面配置文件内容意思是访问的路径 http://localhost:8000/age (网关地址/age)

          会被转发到 http://gateway-service/age(uri/age),并传入 'age=three' 参数(注意为 Get 请求)

      4. 注意此处的配置 uri: lb://gateway-service 与之前都有所不同,之前都是指定了明确的转发地址,可以满足

          单个服务转发的需求,但是一般情况都会有多个服务,所以这里是指定的服务名称,格式为:lb://应用注册

          服务名。

      5. 此处还多配置了一个过滤器 '- name: Hystrix'(熔断)

      6. 当请求服务出错时,会调用 fallback,路径为:http://localhost:8000/fallback (网关地址/fallback)

      7. 此时就需要如下前端控制器

    master-service - 熔断 - controller

    package com.zwc.gateway.hystrix;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @ClassName FallbackController
     * @Desc TODO   网关断路器
     * @Date 2019/6/23 19:33
     * @Version 1.0
     */
    @RestController
    public class FallbackController {
    
        /*
         * @ClassName FallbackController
         * @Desc TODO   网关断路器
         * @Date 2019/6/23 19:35
         * @Version 1.0
         */
        @RequestMapping("/fallback")
        public String fallback() {
            return "I'm Spring Cloud Gateway fallback.";
        }
    
    }
    

      8. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)

      9. 项目启动成功后访问:http://localhost:8000/age

     10. 输出内容:'I'm Spring Cloud Gateway fallback.'

     11. 证明熔断成功

     

    master-service - 限流(重点,解决不生效问题)

    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 限流
      profiles: route_requestRateLimiter
      redis:
        host: localhost
        port: 6379
        database: 0
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   限流
          - id: route_requestRateLimiter
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 添加指定参数
            - AddRequestParameter=age, three
            ## 限流
            - name: RequestRateLimiter
              args:
                ### 限流过滤器的 Bean 名称
                key-resolver: '#{@uriKeyResolver}'
                ### 希望允许用户每秒处理多少个请求
                redis-rate-limiter.replenishRate: 1
                ### 用户允许在一秒钟内完成的最大请求数
                redis-rate-limiter.burstCapacity: 3
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug

      1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)

      2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值

          更改为 route_requestRateLimiter

      3. 上面配置文件内容意思是访问的路径 http://localhost:8000/age (网关地址/age)

          会被转发到 http://gateway-service/age(uri/age),并传入 'age=three' 参数(注意为 Get 请求)

      4. 注意此处还需要配置 redis 的连接信息

      5. 注意此处是结合 redis 实现的限流,所以 filter 过滤器的 name 必须为 RequestRateLimiter

      6. 并且通过实现 KeyResolver 类来自定义限流策略,如下

    master-service - 限流 - 策略

    package com.zwc.gateway.config.filters;
    
    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    /**
     * @ClassName UriKeyResolver
     * @Desc TODO   Spring Cloud Gateway 网关限流过滤器
     * @Date 2019/6/23 17:59
     * @Version 1.0
     */
    public class UriKeyResolver implements KeyResolver {
    
        /*
         * @ClassName UriKeyResolver
         * @Desc TODO   根据请求的 uri 限流
         * @Date 2019/6/29 17:25
         * @Version 1.0
         */
        @Override
        public Mono<String> resolve(ServerWebExchange exchange) {
            return Mono.just(exchange.getRequest().getURI().getPath());
        }
    
    }
    

      7. 启动本地 redis(redis-server.exe) 服务

      8. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)

      9. 项目启动成功后访问:http://localhost:8000/age

     10. 此时限流却无论如何都不生效,原因有如下两点

    ① redis-server 版本过低!我 Windows 本地是 redis-2.4.2 版本的,要用 3 以上的版本!!!

    ② 数据在 redis 中存储的时间只有几秒,所以得使用 monitor 指令来动态的观察!!!

     11. 打开 redis-cli.exe,输入命令 monitor 

     12. 快速刷新地址:http://localhost:8000/age

     13. 页面上会出现 429,redis-cli.exe 中会出现很多数据交互(request_rate_limiter.xxx 开头的 key)

     14. 证明限流成功

     

    master-service - 综合

    spring:
      # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。
      ## 综合
      profiles: route_all
      redis:
        host: localhost
        port: 6379
        database: 0
      application:
        # 应用名称
        name: gateway-master
      cloud:
        gateway:
          discovery:
            locator:
              # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
              enabled: true
          # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
          routes:
          # 路由标识(id:标识,具有唯一性)   综合
          - id: route_all
            # 目标服务地址(uri:地址,请求转发后的地址)
            uri: lb://gateway-service
            # 路由条件(predicates:断言,匹配 HTTP 请求内容)
            predicates:
            ## 转发地址格式为 uri/routeAll,/all 部分会被下面的过滤器给截取掉
            - Path=/all/routeAll
            ## 匹配 GET 请求
            - Method=GET
            # 过滤器(filters:过滤器,过滤规则)
            filters:
            ## 截取路径位数
            - StripPrefix=1
            ## 添加指定参数
            - AddRequestParameter=pass, yes
            ## 熔断
            - name: Hystrix
              args:
                name: fallbackcmd
                ### fallback 时调用的方法 http://localhost:8000/fallback
                fallbackUri: forward:/fallback
            ## 限流
            - name: RequestRateLimiter
              args:
                ### 限流过滤器的 Bean 名称
                key-resolver: '#{@uriKeyResolver}'
                ### 希望允许用户每秒处理多少个请求
                redis-rate-limiter.replenishRate: 1
                ### 用户允许在一秒钟内完成的最大请求数
                redis-rate-limiter.burstCapacity: 3
    
    eureka:
      instance:
        # 使用 ip 代替实例名
        prefer-ip-address: true
        # 实例的主机名
        hostname: ${spring.cloud.client.ip-address}
        # 实例的 ID 规则
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      client:
        serviceUrl:
          # 注册中心地址
          defaultZone: http://${eureka.instance.hostname}:8761/eureka/
    
    logging:
      level:
        # log 级别
        org.springframework.cloud.gateway: debug

      1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)

      2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_all

      3. 上面配置文件内容意思是访问的路径 http://localhost:8000/all/routeAll (网关地址/all/routeAll)截取 /all 部分,

          会被转发到 http://gateway-service/routeAll(uri/routeAll),并传入 'pass=yes' 参数(注意为 Get 请求)

      4. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)

      5. 项目启动成功后访问:http://localhost:8000/all/routeAll

      6. 首先会返回 'I'm Spring Cloud Gateway fallback.',因为服务还未被注册到注册中心

      7. 然后会返回 '{"msg":"缺少凭证","code":-1}',因为配置了全局过滤器,如下

    package com.zwc.gateway.config.filters;
    
    import com.alibaba.fastjson.JSONObject;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.server.reactive.ServerHttpRequest;
    import org.springframework.http.server.reactive.ServerHttpResponse;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    import org.springframework.core.io.buffer.DataBuffer;
    
    import java.net.InetSocketAddress;
    import java.nio.charset.StandardCharsets;
    
    /**
     * @ClassName TokenFilter
     * @Desc TODO   请求认证过滤器
     * @Date 2019/6/29 17:49
     * @Version 1.0
     */
    public class TokenFilter implements GlobalFilter{
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 请求对象
            ServerHttpRequest request = exchange.getRequest();
            // 响应对象
            ServerHttpResponse response = exchange.getResponse();
    
            // 只有综合路由才添加这个全局过滤器(routesId:route_all)
            // 如果请求路径中不存在 routeAll 字符串
            if(request.getURI().toString().indexOf("routeAll") == -1){
                System.out.println("filter -> return");
                // 直接跳出
                return chain.filter(exchange);
            }
    
            // 从请求中获取 token 参数
            String token = exchange.getRequest().getQueryParams().getFirst("token");
            // 如果为空,那么将返回 401
            if (token == null || token.isEmpty()) {
    
                // 响应消息内容对象
                JSONObject message = new JSONObject();
                // 响应状态
                message.put("code", -1);
                // 响应内容
                message.put("msg", "缺少凭证");
                // 转换响应消息内容对象为字节
                byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(bits);
                // 设置响应对象状态码 401
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                // 设置响应对象内容并且指定编码,否则在浏览器中会中文乱码
                response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
                // 返回响应对象
                return response.writeWith(Mono.just(buffer));
            }
            // 获取请求地址
            String beforePath = request.getPath().pathWithinApplication().value();
            // 获取响应状态码
            HttpStatus beforeStatusCode = response.getStatusCode();
            System.out.println("响应码:" + beforeStatusCode + ",请求路径:" + beforePath);
            // 请求前
            System.out.println("filter -> before");
            // 如果不为空,就通过
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // 获取请求地址
                String afterPath = request.getPath().pathWithinApplication().value();
                // 获取响应状态码
                HttpStatus afterStatusCode = response.getStatusCode();
                System.out.println("响应码:" + afterStatusCode + ",请求路径:" + afterPath);
                // 响应后
                System.out.println("filter -> after");
            }));
        }
    
    }
    

      8. 全局过滤器,不需要配置在配置文件中,作用于所有路由;只是这里在处理前做了判断,只有路径中存在

          routeAll 字符串才到后续处理;并且处理分为请求前的处理,和响应后的处理

      9. 此时在地址:http://localhost:8000/all/routeAll 中添加 token 参数

     10. 访问:http://localhost:8000/all/routeAll?token=123

     11. 轮流输出内容:'Can I pass? yes! port:9000' 和 'Can I pass? yes! port:9001'

     12. 观察 gateway 工程的控制台,会有如下内容输出

    响应码:null,请求路径:/routeAll
    filter -> before
    响应码:200,请求路径:/routeAll
    filter -> after

     13. 证明全局过滤器过滤成功

     

    service 工程 - 项目结构

     

    把多工程项目使用 IntelliJ IDEA 打开

    1. 把项目从 GitHub 中下载到你的本地
    2. 打开 IntelliJ IDEA 
    3. 点击 File -> Open
    4. 打开你下载到本地的项目目录
    5. springcloud-gateway -> springcloud-gateway-service(选择打开此工程)
    6. 打开 service 工程后
    7. 再次点击 File -> Project Structrue
    8. 选择 Modules,点击 '+' 符号
    9. 点击 Import  Module
    10. 还是打开你下载到本地的项目目录
    11. springcloud-gateway -> springcloud-gateway-commons -> pom.xml
    12. 点击 OK
    13. 点击 Next,Finish
    14. 点击 Apply,OK

     


     

    希望能够帮助到你

    over

     

     

     

    展开全文
  • GateWay三大核心概念:断言(Predicate),路由(Route),过滤(Filter) 路由,断言配置 server: port: 9527 spring: application: name: cloud-gateway cloud: gateway: discovery: locator: enabled: true ...
  • 服务网关(Gateway) 搭建网关服务 本案例中使用spring boot的版本为2.0.3.RELEASE,spring cloud版本为Finchley.RELEASE。在中涉及到了三个工程, 分别为注册中心eureka-server、服务提供者service-hi、 服务网关...
  • Gateway--概述

    2020-03-18 20:16:59
    Gateway Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用Zuul网关。但是在2.x版本中,zuul的升级一直跳票,SpringCloud最后自己研发了一个网关代替Zuul,就是SpringCloud Gatewaygateway就是原zuul1....
  • Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断,限流,重试等 ——概念 Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty...
  • 微服务gateway介绍

    万次阅读 2018-04-15 17:35:25
    API 网关(API Gateway)主要负责服务请求路由、组合及协议转换。下面是大家的总结:一、最佳回答网关的技术选型SpringCloud-Zuul :社区活跃,基于 SrpingCloud 完整生态, 是构建微服务体系前置网关服务的最佳选型....
  • gateway官网解读(四)

    2020-09-10 16:22:27
    这是最后一块了, 要吐了......读官网真的不是一件人干的事情啊,尤其是我这种四级都是磕磕绊绊的人. 读完之后我会产出一篇总结.算是对我, 主要是对我老大有个交代. 9. TLS and SSL 我现百度了一下 ...
  • This application has no explicit mapping for /error, so you are seeing this as a fallback. Tue Jan 22 15:55:26 CST 2019 There was an unexpected error (type=Not Found, status=404). ...
  • 折腾了两小时没搞清楚怎么回事, 其实原因很简单,下图中红色框里的这行代码加上去就OK了 #### 看到一篇关于gateway路由的文章介绍: https://www.jianshu.com/p/5e40bbc95eb9 ...
  • Spring Cloud Gateway基于服务发现的默认路由规则

    万次阅读 热门讨论 2018-06-21 18:33:28
    1.Spring Gateway概述1.1 什么是Spring Cloud Gateway Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而...
  • Go语言实现的API-Gateway

    万次阅读 2017-02-13 14:10:35
    Gateway是一个使用go实现的基于HTTP的API 网关。 特性: API 聚合 流控 熔断 负载均衡 健康检查 监控 消息路由 后端管理WebUI 能做什么: 规划更友好的URL给调用者。 聚合多个API的结果返回给API调用者...
  • 微服务中如何如何把所有请求都转向API Gateway, 禁止直接访问原有的微服务,必须通过API Gateway进行二次转发,也就是所有请求只接受来自API Gateway的请求
  • springcloud使用gateway访问项目接口404

    千次阅读 2019-11-28 16:40:55
    使用gateway/服务名/接口 访问接口一直404,折腾了半天终于发现是自己在项目配置里边加入了server.servlet.context-path!!!。切记,如果加入了项目名称则用gateway访问必须是 gateway/服务名称/项目名/接口。在此...
  • springCloud Gateway 网关的配置详解

    万次阅读 2019-04-22 17:31:05
    项目用到了Gateway 作为网关,网关的相关使用场景很值得了解,还有路由配置。今天就来记录一下。 开启基于注册中心的路由表。gateway可以通过开启以下配置来打开根据服务的serviceId来匹配路由,默认是大写: cloud:...
  • 502 bad gateway是什么意思

    万次阅读 2012-04-23 17:05:45
    通俗解释一下 ... 简单来说 502 是报错类型代码 bad gateway 错误的网关 2.产生错误的原因 连接超时 我们向服务器器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错
  • springcloud之gateway的- Path匹配多个路径 答 先看以下配置: spring: application: name: gateway cloud: gateway: discovery: locator: enabled: true routes: #服务...
  • nginx 502 Bad Gateway解决办法

    万次阅读 2018-09-06 11:40:59
    我的解决方式比较小白, 第一次报这个错(nginx 502 Bad Gateway).网上找了一大圈都是PHP什么的,但是好像都不适用. 于是问了之前的一个同事,他说是不是我的tomcat关闭了,我恍然大悟,去看了下,果然是的. 然后启动...
1 2 3 4 5 ... 20
收藏数 209,302
精华内容 83,720
关键字:

gateway