Netflix-Zuul网关说明文档

Netflix-Zuul

一. 简介

路由是微服务架构中的一个组成部分。
例如【/】可能是你映射到web应用的路径,【/api/user】可能是你映射到user服务的路径,【/api/shop】可能是
映射到shop服务的路径。
Zuul是一款出自于Netflix基于JVM的服务器端的负载均衡器。

Netflix在用Zuul做这些事情:

  • 身份验证(Authentication)
  • Insights
  • 压力测试(Stress Testing)
  • 金丝雀测试(Canary Testing)
  • 动态路由(Dynamic Routing)
  • 服务迁移(Service Migration)
  • 减载(Load Shedding)
  • 安全(Security)
  • 静态响应处理(Static Response handling)
  • 流量控制(Active/Active traffic management)

二. 集成Zuul反向代理

  • Spring Cloud 已经建立了Zuul代理,用来适用前端应用程序想要通过代理来访问一个或者多个后端服务。
    这个特点对于用户接口代理访问到后端服务非常有用。避免了跨域问题并且可以使认证独立于后端服务。

  • 如果要启用Zuul反向代理,可以在Spring Boot应用程序的主类中添加注解@EnableZuulProxy。 这样做
    可以使本地的调用请求路由到相应的服务。按照惯例,一个users服务从代理那里接收/users(使用前缀剥离服务)
    的请求Zuul代理使用Ribbon通过服务发现来定位具体的服务。所有的请求在hystrix command中执行,所以失败
    的请求可以在Hystrix监控中获取到。一旦断路器打开,Zuul代理将不会尝试连接该服务。

    注:Zuul starter 没有包含服务发现客户端,因此,为了实现基于服务id的路由,最好提供服务发现的客户端
    (Eureka是其中之一的选择)

  • 如果服务要跳过Zuul的反向代理,可在属性【zuul.ignored-services】中设置跳过的服务ID列表。
    如果某个服务和需要跳过的服务列表匹配,但是又明确的设置在了路由map中,该服务将不会跳过Zuul的代理。
    下述例子就是这样的效果:
    application.yml

      zuul:
        ignoredServices: '*'
        routes:
          users: /myusers/**
    

    上述例子中,所有的服务都将跳过Zuul的代理,除了users服务。

  • 如果要添加或者改变代理路由,可以将配置信息配置成如下所示:
    application.yml

      zuul:
        routes:
          users: /myusers/**
    

    上述配置意味着如果HTTP请求/myusers将会转发到users服务(例:/myusers/101将会转发到users服务的/101)

  • 如果想要通过路由获取到更好的粒度控制,则可以独立的指定path和serviceId,配置如下:
    application.yml

     zuul:
      routes:
        users:
          path: /myusers/**
          serviceId: users_service
    

    上述配置意味着如果HTTP请求/myusers将会转发到serviceId为users_service的服务中去。
    此场景中必须指定ant-style风格的格式。所以/myusers/*只匹配一级路径,/myusers/**可匹配多级路径。

  • 后台服务的位置可以通过serviceId(通过服务发现获取)指定,也可以通过url指定,配置如下:
    application.yml

      zuul:
        routes:
          users:
            path: /myusers/**
            url: http://example.com/users_service
    
  • 上述所有的这些路由例子都不会以HystrixCommand的方式执行,有多个url的时候也不会使用Ribbon做负载均衡。
    如果要实现这些目标,可以指定一个静态服务的list,配置如下:
    application.yml

      zuul:
        routes:
          echo:
            path: /myusers/**
            serviceId: myusers-service
            stripPrefix: true
      
      hystrix:
        command:
          myusers-service:
            execution:
              isolation:
                thread:
                  timeoutInMilliseconds: ...
      
      myusers-service:
        ribbon:
          NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
          listOfServers: http://example1.com,http://example2.com
          ConnectTimeout: 1000
          ReadTimeout: 3000
          MaxTotalHttpConnections: 500
          MaxConnectionsPerHost: 100
    

    另一种方式是指定一个服务路由并且为serviceId配置一个Ribbon客户端(这样做需要在Ribbon中禁止Eureka的支持),配置如下:
    application.yml

      zuul:
        routes:
          users:
            path: /myusers/**
            serviceId: users
      
      ribbon:
        eureka:
          enabled: false
      
      users:
        ribbon:
          listOfServers: example.com,google.com
    
  • 也可以使用正则表达式在serviceId和如路由之间指定一个规则。从serviceId中提取变量并且将它们注入到路由中,进而使用有规律的表达式来定义groups。例子如下:
    ApplicationConfiguration.java

      @Bean
      public PatternServiceRouteMapper serviceRouteMapper() {
         
          return new PatternServiceRouteMapper(
              "(?<name>^.+)-(?<version>v.+$)",
              "${version}/${name}");
      }
    

    上述例子意味着serviceId为myusers-v1的服务将指向地址/v1/myusers/**.任何正则表达式都可被接受,但是任何被命名的groups必须存在于servicePattern和routePattern中。如果servicePattern不能匹配serviceId,将使用默认的操作。上述例子中,myusers的serviceId映射到了/myusers/**的路由中(没有检测到版本号)。这个功能默认是禁用的,只有在服务被发现时才有这个功能。

  • 增加一个映射的前缀,可以设置zuul.prefix属性值,例如/api。默认情况下,Zuul在请求转发前会将这个前缀丢弃(可以通过设置zuul.stripPrefix=false来关掉这个功能)。也可以在个别的路由中特定服务中关掉丢弃映射前缀的功能。例如:
    application.yml

     zuul:
      routes:
        users:
          path: /myusers/**
          stripPrefix: false
    

    注:zuul.stripPrefix只有在设置了zuul.prefix时才会起作用。它不会对路由中设置的path产生任何影响。
    在上述例子中,请求/myusers/101将转发到users服务的/myusers/101路径中。

  • 事实上,zuul.routes中的属性会绑定到ZuulProperties的对象中。如果你去看那个对象的属性,里面有一个retryable的标志。如果设置那个标志为true,则Ribbon的客户端会自动重试失败的请求。当你需要修改Ribbon客户端的重试参数配置时你也可以将这个标记设置为true。
    默认情况下,X-Forward-Host头部属性会加到转发的请求中。如果要关闭这个属性,可设置zuul.addProxyHeaders=false.
    默认情况下,前缀路径在转发时将丢弃,并且后台请求中会增加X-Forward-Prefix头部属性(如上述例子中的/myusers)。

  • 如果设置默认的路由路径(/),被@EnableZuulProxy注解的应用程序将类似一个独立的服务器。例如,zuul.route.home:/将会路由home服务的/**路径。

  • 如果需要将忽略路径控制到更好的颗粒度,可以指定一些特别的pattern。这些pattern将会在处理路由位置开始时处理,这意味着前缀应该包含在pattenr中以保证匹配。忽略的模式跨越所有服务并取代任何其他路由规范。下面的例子将展示如何创建一个忽略pattern:
    application.yml

     zuul:
      ignoredPatterns: /**/admin/**
      routes:
        users: /myusers/**
    

    上面的例子意味着请求如/myusers/101将转发到users服务的/101路径中,然而如果请求路径中包含/admin/将不会被转发。

  • 如果你需要保证路由的顺序,你需要使用YAML文件。使用properties文件将丢失顺序访问的功能。下面的例子就是这样一个YAML文件:
    application.yml

       zuul:
        routes:
          users:
            path: /myusers/**
          legacy:
            path: /**  
    

    如果使用properties文件,legacy的路径有可能变成优先于users的路径处理,最后导致users服务不可达。

三. Zuul Http Client

Zuul默认使用的HTTP client是 Apache HTTP client而不是丢弃的Ribbon的RestClient。如果要使用RestClient或者okhttp3.OkHttpClient,分别设置 ribbon.restclient.enabled=true 或者 ribbon.okhttp.enabled=true即可。如果你想自定义Apache HTTP client或者OK HTTP client,则需要提供ClosableHttpClient或者OkHttpClient的bean类型。

四. Cookies和敏感头部信息

  • 在同一个系统的不同服务之间你可以共享头部信息,但是可能你不想将某些敏感头部信息泄露给下游的外部服务器。这种情况下可以指定忽略的头部信息作为路由配置的一部分。Cookies扮演了一个特殊的角色,因为它们能在浏览器中很好的定义语义,并且经常当做处理过的敏感信息使用。如果你的代理的消费者是浏览器,对于用户来说给下游服务使用的Cookies可能是个问题,因为它们都被搞得乱七八糟(所有的下游服务认为Cookies都是来自于一个地方)。

  • 如果你充分的设计了你的服务(比如,只有一个下游服务设置了Cookies),你也许可以使他们从后端服务一直流转到调用者。当然,如果你的代理设置了Cookies并且你所有的后端服务都是同一个系统的一部分,可以很自然和简单的共享他们(例如使用Spring Session让他们维持在共享的状态)。除此之外, 对于调用者来说,下游服务队任何cookie的get和set操作似乎都没有多大用处,所以推荐至少将Set-Cookie和Cookie放入属于域的一部分的路由的敏感头部中。即使该路由属于域的一部分,在让cookie流转与服务和代理之前,请仔细考虑那将意味着什么。

    每个路由的敏感头部可以通过逗号隔开字符串来设置,下面的例子就是这样一个YAML文件:
    application.yml

       zuul:
        routes:
          users:
            path: /myusers/**
            sensitiveHeaders: Cookie,Set-Cookie,Authorization
            url: https://downstream
    

    这个是sensitive

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值