SpringCloud gateway入门

什么是微服务网关

​ 在微服务众多的服务的治理过程中,服务网关的作用在微服务框架中可以提供统一入口鉴权校验动态路由降低耦合度的功能,关于springcloud的网关有三个,分别是zuul、zuul2和gateway,其中zuul/zuul2是Netflix公司开发的,但是因为zuul的性能不够好,zuul2的开发内部有歧义,所以springcloud便自研了一套网关——gateway。

组件名称 所属公司 组件简介
zuul Netflix 停更进维
zuul2 Netflix 由于zuul核心开发人员离职了3人,神仙打架,出路不明
gateway springcloud springcloud自研的一套非阻塞的网络异步网关

关于Gateway

Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,,Spring Boot 2Project Reactor等技术。Gateway旨在提供-种简单而有效的方式来对API进行路由, 以及提供一些强大的过滤器功能, 例如: 熔断、限流、重试等。

SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty

Spring Cloud Gateway的目标提供统-的路由方式且基于 Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。Spring Cloud Gateway的目标提供统-的路由方式且基于 Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

zuul 和 gateway

基本对比

zuul zuul2 Gateway
所属公司 Netflix Netflix springcloud
springboot版本 springcloud 1.x Springcloud 2.x Springcloud 2.x
架构 基于Servlet 2.5,使用阻塞架构,不支持任何长连接 基于Netty非阻塞 基于webFlux非阻塞
长连接 不支持任何长连接 支持 支持
性能 已过时 较好 较好

webflux

webflux是一个非阻塞的web框架,类似springmvc。传统的Web框架,比如说: struts2, springmvc等都是基于Servlet APIServlet容器基础之上运行的。但是在Senv/let3.1之后有了导步非阻塞的支持。而WebFlux是-个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器 上。非阻塞式+函数式编程(Spring5必须让你使用java8)Spring WebFlux是Spring 5.0引入的新的响应式框架,区别于Spring MVC, 它不需要依赖Servlet API, 它是完全异步非阻塞的,并且基于Reactor来实现响应式流规范。

gateway原理

三要素

  • Route(路由)

    路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由

  • Predicate(断言)

    判断请求的转发条件

  • Filter(过滤)

    指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

工作原理

gateway 工作原理
  1. 客户端向Spring Cloud Gateway发出请求,然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway web hander

  2. Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前( "pre" )或之后( "post" )执行业务逻辑。

  3. Filter在"pre” 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在"post"类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。

搭建gateway

注意事项

  • gateway 需要注册到注册中心,这里我使用的是Eureka,其他注册中心也可。
  • gateway项目不能同时依赖spring-boot-starter-web

依赖

    <!--gateway-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

配置路由

gateway项目需要先把需要转发的路由先配置到项目中去,他支持两种方式配置路由:yml文件配置和注入RouteLocator的方式。每个路由中都包含了predicatefilter、实际的转发主机uri以及设定的一个id(不能重复)。

其中:

  • predicate包含多种类型,可以一起使用,具体类型查看 官网

    包含有afterbeforebetweencookiesheaderhostmethodpathqueryremoteaddrweigth

    Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理。

  • Filter也包含许多种可选类型,可以一起使用,具体类型查看 官网

    包含有AddRequestHeaderAddRequestParameterAddResponseHeaderDedupeResponseHeaderHystrixCircuitBreakerFallbackHeadersMapRequestHeaderPrefixPathPreserveHostHeaderRequestRateLimiterRedirectToRemoveHopByHopHeadersFilterRemoveRequestHeaderRemoveResponseHeaderRemoveRequestParameterRewritePathRewriteLocationResponseHeaderRewriteResponseHeaderSaveSessionSecureHeadersSetPathSetRequestHeaderSetResponseHeaderSetStatusStripPrefixRetryRequestSize

yml 方式示例

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

上面这个配置的意思是,访问gateway-host/red/xxx或者gateway-host/blue/xxx的话,这个请求会转发到https://example.org,相当于https://example.org/red/xxxhttps://example.org/blue/xxx,实现了一个转发的功能。我们还可以用硬编码的方式来实现上面的配置。

注入RouteLocator的方式示例

@Configuration
public class GatewayConfiguration {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("host_route",r->r.path("/red/{segment},/blue/{segment}").uri("https://example.org")).build();
        return routes.build();
    }
}

这样的方式就需要注入routeLocator来实现网关服务的配置。两种方式的效果都一样的,个人建议使用yml配置的方式。

通过微服务名动态路由

上面两种方式我们都是在uri上绑定了服务的主机地址来实现转发的,但是如果服务地址变了,网关就得修改其配置,这样就显得很麻烦。那我们能不能通过微服务名来调用服务呢?答案是肯定的。

修改配置

需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能。

spring:
  application:
    name: cloud-springcloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能
      routes:
        - id: userinfo_user
          uri: lb://cloud-eureka-provide-userinfo-service # lb协议表示启用负载均衡功能,然后后面跟着微服务名称
          predicates:
            - Path=/user/**

上面只是演示了Predicates中的Path的用法,还有许多其他非常高级的用法,可以自己查询官网文档去学习下哈~

过滤器

路由过滤器可以用于修改进入的http请求和返回的http响应,路由过滤器只能指定路由使用。官网提供了两类过滤器GatewayFilterGlobalFilter过滤器,具体可以参考官网。

自定义过滤器

@Component
public class CustomFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /**
         * 从请求中获取是否有token参数
         */
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (token==null){
            /**
             * 直接拒绝
             */
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        /**
         * 通过这个过滤器,进入过滤链中的下一个过滤器
         */
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

发现需要添加token参数的请求才能访问成功,否则会报406错误。

总结

springcloud的gateway还是非常强大的,这边笔记只能说做了简单的了解,要发掘其强大的功能依然建议查阅 官网
在我学习过程中觉得美中不足的地方就是这些服务只能通过配置的方式来加入,而不能像添加到数据库中这么方便,是否每次有服务变动了就需要更改网关(配置)呢?后面会学习到springcloud的配置中心,应该可以解决这个问题。不过用起来和我之前用到的kong网关还是各有优劣吧。

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