Skip to content

Zuul 1 路由

Yasin Shaw edited this page Aug 23, 2018 · 1 revision

微服务网关

什么是微服务网关?

微服务网关位于一个微服务系统的边缘,用于外部系统访问微服务。大概结构如图:

为什么要使用微服务网关?

在一个微服务系统中,如果不使用网关,则会有许多问题:

  • 客户端会多次请求不同的微服务,增加了客户端的复杂性
  • 可能需要对每个微服务处理跨域请求
  • 可能对每个微服务需要进行安全方面的独立认证
  • 难以重构,一旦后端微服务设计发生更改,客户端也需要更改
  • 某些微服务可能使用了防火墙、浏览器不友好的协议,不方便外部直接访问

微服务网关有什么好处?

  • 易于监控
  • 易于认证
  • 减少客户端和各个微服务之间的交互次数

Zuul简介

Zuul是Netflix开源的微服务网关。它可以和Eureka, Ribbon, Hystrix等组件集成,配合使用。Zuul的核心是一系列的过滤器

Zuul有以下功能:

  • 身份认证与安全
  • 审查与监控
  • 动态路由
  • 压力测试
  • 负责分配
  • 静态响应处理
  • 多区域弹性(跨AWS Region)

Zuul路由

Zuul默认的路由转发规则是:

/微服务id/路径

比如:/user-service/users/1会被转发到id为user-service/users/1路径下。

用户也可以手动配置路由转发规则:

 zuul:
  ignoredServices: '*' # 不转发所有的服务
  routes:
    users: /myusers/** # 转发id为users的服务

在上面的配置里,/myusers/1会被转发到id为users的微服务下的/1路径。

也可以覆盖默认配置:

 zuul:
  routes:
    users: /myusers/**

还有另一种写法:

 zuul:
  routes:
    users: # 在这里就只是一个名字,没有其它作用
      path: /myusers/**
      serviceId: users_service

PS: /* 只匹配下面一级路径,而/**可以匹配下面所有路径。

你也可以不用“服务的id”而用“服务的路径”:

 zuul:
  routes:
    users:
      path: /myusers/**
      url: http://example.com/users_service

但这样的话, 就没法使用Hystrix服务追踪了,也没法使用Ribbon进行负载均衡。可以通过下面的方式来达到又使用url,又能用服务追踪和负载均衡的目的。

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

还有一种方式是使用“微服务的id”和URL来进行负载均衡。但这需要在Ribbon中配置关闭基于Eureka的负载均衡。因为此时你需要的是自己配置的URL,而不是从Eureka那里根据微服务id取出来的URL。

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

ribbon:
  eureka:
    enabled: false

users:
  ribbon:
    listOfServers: example.com,google.com

可以通过配置serviceRouteMapper来实现自定义的路径规则。比如:

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

第一个参数是匹配service的,第二个参数是匹配路由的。按照上述代码这样配置的话,如果你的微服务id为myusers-v1,那么它的路由就会匹配到/v1/myusers/**,而不是默认的/myusers-v1/**

而此时如果找不到一个匹配的service,那就还是会按照默认的规则来。比如此时我输入路径/user-service/users/1,它还是会被转发到user-service服务的/users/1路径下。

zuul:
  prefix: /api

默认情况下,/api/user-service/123会被转发到user-service微服务下面的/123路径。而如果你这样配置:

zuul:
  prefix: /api
  strip-prefix: false

此时/api/user-service/123就会被转发到user-service微服务下面的/api/123路径。

可以使用zuul.prefix属性配置路径的前缀。这里配置的前缀是通用的前缀,也就是说所有微服务的路径都需要使用这个前缀。

也可以设置某一个微服务的前缀:

可以如下配置:

zuul:
  routes:
      user-service:
        path: /users/**
        strip-prefix: false

此时,/users/123就会被转发到user-service微服务下面的/usrs/123路径。

其实zuul.routes配置会被绑定到一个叫ZuulProperties的类。你会看到这个类里面有这个属性:

private Boolean retryable = false;

如果把它设置为trueRibbon客户端在调用失败后就会自动重试。当你需要修改Ribbon客户端的重试配置参数时,你也可以把它设置成true

默认情况下,X-Forwarded-Host在请求转发的时候被加进去。如果你想关掉它,可以设置zuul.addProxyHeaders = false

默认情况下,URL的前缀会被去掉,比如/user-service/users/123会被转发到user-service微服务下的/users/123。Zuul会在转发请求的时候加上X-Forwarded-Prefix请求头。这里的值是/user-service

可以配置某些路由不被转发:

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

这样的话,/myusers/123会被转发到users微服务下的/123路径。然而/admin/等路径不会被解析和转发。

如果你想要你的路由有优先级的话,那就需要使用YAML文件。比如:

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

这种情况必须把legacy配置在users后,否则的话,/**会覆盖/myusers/**,会导致users微服务的路径匹配不到。

Sidebar

Clone this wiki locally