spring cloud 服务网关ZULL

spring cloud 服务网关ZUUL

路由是微服务架构中不可或缺的一部分。比如,/ 可能需要映射到你的web应用, /api/users 映射到用户服务, /api/shop 映射到商城服务. Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。

可以通过Zuul实现下列业务:

  • 认证和安全
  • 测试监控
  • 动态路由
  • 限流
  • 静态响应处理

反向代理

在Spring Boot main函数上通过注解 @EnableZuulProxy 来开启. 根据请求URL匹配,Ribbon从注册中心Eureka获取服务ID做负载均衡,请求都在Hystrix的command中执行。

路由规则可以在配置文件中指定,可以像nginx一样根据URL正则匹配请求。 示例 application.yml

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

这个意味着HTTP请求"/users"开头的URL,会被转发到"users_service"服务. 路由必须配置一个可以被指定为ant风格表达式的"path", /users/*只能匹配一个层级, 但/users/**可以匹配多级。后端的配置既可以是"serviceId"(对于服务发现中的服务而言), 也可以是"url"(对于物理地址)

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

“/users/101"的请求会跳转到"users"服务的”/101", 但包含"/admin/“的请求将不被处理.

动态绑定 可以通过regexmapper提供serviceId和routes之间的绑定. 它使用正则表达式组来从serviceId提取变量, 然后注入到路由表达式中。示例: ApplicationConfiguration.java

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

这个意思是说"users-v1"将会匹配路由”/v1/users/",任何正则表达式都可以, 但是所有组必须存在于servicePattern和routePattern之中. 如果servicePattern不匹配服务ID,则使用默认行为,这个功能默认是关闭的,并且仅适用于服务注册的服务。 前缀 如果api中有前缀如/v2/user/, /api/user/**,可以设置zuul.prefix,通过zuul.stripPrefix=false关闭。

REST API 动态获取和修改: 如果你使用 @EnableZuulProxy 同时引入了Spring Boot Actuator, 你将默认增加一个endpoint, 提供http服务的 /routes. 一个GET请求将返回路由匹配列表. 一个POST请求将强制刷新已存在的路由。

Cookies和敏感HTTP头

X-Forwarded-Host默认在跳转是自动添加,可以通过zuul.addProxyHeaders = false 关闭。 如果希望某些HTTP HEADER不泄露到下游服务,可以配置为敏感头。

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

可以这样对不同服务设置不同敏感头,也可以设置全局默认敏感头:zuul.sensitiveHeaders =

窒息模式和本地跳转

旧接口迁移到新接口的过程,可以如下,把一部分接口用老接口,一部分迁移的方式。有点像rewrite。

zuul:
  routes:
    first:
      path: /first/**
      url: http://first.example.com
    second:
      path: /second/**
      url: forward:/second
    third:
      path: /third/**
      url: forward:/3rd
    legacy:
      path: /**
      url: http://legacy.example.com

通过Zuul上传文件

如果使用 @EnableZuulProxy , 可以使用代理路径上传文件, 对于小文件可以正常使用即可, 对于大文件,还有可选路径”/zuul/,通过它绕过Spring DispatcherServlet (避免处理multipart). 比如对于 zuul.routes.customers=/customers/* ,使用 /zuul/customers/*去上传大文件. Servlet路径通过 zuul.servletPath 指定. 如果使用Ribbon负载均衡器的代理路由, 在 处理非常大的文件时, 仍然需要提高超时配置。

application.yml
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:
  ConnectTimeout: 3000
  ReadTimeout: 60000

注意: 对于大文件的上传流, 你应该在请求中使用块编码. (有些浏览器默认不这么做). 比如在命令行中:

$ curl -v -H "Transfer-Encoding: chunked" \
-F "file=@mylarge.iso" localhost:9999/zuul/simple/file
CONTENTS