zuul是什么?

  • front door. API Gateway.Zuul is a JVM based router and server side load balancer by Netflix.
  • 所有请求的入口。
  • As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security. 作为边界应用服务,zuul能实现动态路由、监控、弹性与安全性。
  • 用groovy编写。

Netflix uses Zuul for the following:

Authentication 认证
Insights 洞察力
Stress Testing 压力测试
Canary Testing 金丝雀测试
Dynamic Routing 动态路由
Service Migration 服务迁移
Load Shedding 减载
Security 安全
Static Response handling 静态响应处理
Active/Active traffic management

如果以后想设计网关,可按照上面进行対飚设计。

zuul 请求处理过程:

使用注意事项

  1. If you need your routes to have their order preserved you need to use a YAML file as the ordering will be lost using a properties file.如果你希望按照书写顺序来执行路由规则,则必须使用YAML文件,不能使用properties

Embedded Zuul Reverse Proxy

使用代理,方便前端调用后端服务,避免CORS(跨域资源访问)和权限问题,

  • @EnableZuulProxy
  • The proxy uses Ribbon to locate an instance to forward to via discovery, and all requests are executed in a hystrix command, so failures will show up in Hystrix metrics, and once the circuit is open the proxy will not try to contact the service.代理通过服务发现调用服务,通过ribbon定位实例,所有请求通过hystrix命令模式来执行。失败信息都会在收集在hystrix指标体系中,一旦进入熔断模式,代理将无法访问服务。
  • 至少需要集成discovery client,如eureka

Zuul Http Client

The default HTTP client used by zuul is now backed by the Apache HTTP Client instead of the deprecated Ribbon RestClient.

To use RestClient or to use the okhttp3.OkHttpClient set
ribbon.restclient.enabled=true
or
ribbon.okhttp.enabled=true

现在默认使用apache client.

Cookies and Sensitive Headers

对cookie和headers敏感,就是说可以制定headers的规则来过滤请求。Spring Cloud Netflix 1.1 以上版本才有此功能。

 zuul:
routes:
users:
path: /myusers/**
sensitiveHeaders: Cookie,Set-Cookie,Authorization # blacklist,如果不过滤,则须显式设为空。
url: https://downstream set globally by setting zuul.sensitiveHeaders

Strangulation Patterns and Local Forwards

应用如何由老版本向新版本?

  • 扼杀模式(使其慢慢窒息的方式):一部分调用老应用,一部分调用新应用。
  • hystrix也可以提供控制新老应用的切换

Uploading Files through Zuul

小文件可以通过zuul proxy,大文件通过 Spring DispatcherServlet。

Query String Encoding

The result can be different than the original input if it was encoded using Javascript’s encodeURIComponent() method for example. While this causes no issues in most cases, some web servers can be picky with the encoding of complex query string.

zuul:
forceOriginalQueryStringEncoding: true

Note: This special flag only works with SimpleHostRoutingFilter and you loose the ability to easily override query parameters with RequestContext.getCurrentContext().setRequestQueryParams(someOverriddenParameters) since the query string is now fetched directly on the original HttpServletRequest.

Disable Zuul Filters

默认会使用很多filters,可采用如下方式禁止

set zuul...disable=true.

zuul.SendResponseFilter.post.disable=true

Zuul Timeouts

  • zuul在使用服务发现和路由时,需配置超时参数如下:

  • If Zuul is using service discovery than you need to configure these timeouts via Ribbon properties, ribbon.ReadTimeout and ribbon.SocketTimeout.

  • If you have configured Zuul routes by specifying URLs than you will need to use zuul.host.connect-timeout-millis and zuul.host.socket-timeout-millis.

Rewriting Location header

If Zuul is fronting a web application then there may be a need to re-write the Location header when the web application redirects through a http status code of 3XX。当通过3XX重定向时,需要重写header,否则会重定向到web url而不是zuul url.

重写 filter

import org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilter;
... @Configuration
@EnableZuulProxy
public class ZuulConfig {
@Bean
public LocationRewriteFilter locationRewriteFilter() {
return new LocationRewriteFilter();
}
}

Note:不一定适应所有情况,万一就是要重定向到外部url.

Zuul Developer Guide

The Zuul Servlet

Zuul is implemented as a Servlet. For the general cases, Zuul is embedded into the Spring Dispatch mechanism. This allows Spring MVC to be in control of the routing.

zuul是servlet.zuul嵌入springd的请求转发机制,这样spring mvc由它来控制路由。

zuul一般配置缓存请求,当大文件上传时例外。

by default:/zuul. zuul.servlet-path

Zuul RequestContext

RequestContext

  • 请求数据保存在ThreadLocal中,Information about where to route requests, errors and the actual HttpServletRequest and HttpServletResponse are stored there.
  • RequestContext继承了ConcurrentHashMap

@EnableZuulProxy vs. @EnableZuulServer

@EnableZuulProxy > @EnableZuulServer, 多了路由功能。The additional filters in the "proxy" enable routing functionality.

Filters

How to Write a Route Filter

extends ZuulFilter 继承以下三类过滤器:

  • Pre Filter
  • Route Filter
  • Post Fitler

在run()中,对request、OkHttpClient、response做修改。

How Zuul Errors Work

The SendErrorFilter is only run if RequestContext.getThrowable() is not null.

It then sets specific javax.servlet.error.* attributes in the request and forwards the request to the Spring Boot error page. 如何设置该属性?

ajax请求如何处理?

Zuul Eager Application Context Loading

Ribbon clients are by default lazily loaded up by Spring Cloud on first call.Ribbon clients默认为延迟加载

修改配置,让其在应用启动时加载:

zuul:
ribbon:
eager-load:
enabled: true

practice

通过url映射的方式来实现zull的转发有局限性

stripPrefix默认为true。This means that all calls such as "/myusers/101" will be forwarded to "/101" on the "users" service.

spring.application.name=gateway-service-zuul
server.port=8888
#这里的配置表示,访问/it/** 直接重定向到http://www.ityouknow.com/**
zuul.routes.baidu.path=/it/**
zuul.routes.baidu.url=http://www.ityouknow.com/

通过serviceId(即application name)来转发

zuul:
routes:
producer:
path: /wifi/**
serviceId: wifi-service
strip-prefix: true

zuul高可用

参数优化

  1. 为Spring Cloud Ribbon配置请求重试
zuul.host.connect-timeout-millis
zuul.host.socket-timeout-millis
zuul.eureka.[service id].semaphore.maxSemaphores: 128 spring.cloud.loadbalancer.retry.enabled=true hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000 hello-service.ribbon.ConnectTimeout=250
hello-service.ribbon.ReadTimeout=1000

zuul存在的问题

在实际使用中我们会发现直接使用Zuul会存在诸多问题,包括:

  • 性能问题:当存在大量请求超时后会造成Zuul阻塞,目前只能通过横向扩展Zuul实例实现对高并发的支持;

  • WebSocket的支持问题: Zuul中并不直接提供对WebSocket的支持,需要添加额外的过滤器实现对WebSocket的支持;

  • 缺少请求速率限制功能,已有第三方jar包提供:zuul进行rate limit

性能问题解决方案:集群、高可用

Zuul is just a stateless service with an HTTP endpoint, hence, we can have as many Zuul instances as we need.

  • zuul多个节点启动,自身也可以作为服务,注册到eureka上。

High availability when client is not a Eureka Client. The Zuul instances, in this case, will be running behind a load balancer such as HAProxy, or a hardware load balancer like NetScaler:

高可用负载均衡选型haproxy vs nginx

选择haproxy,理由如下:

  • 从定位上选择,haproxy组件功能单一,只做LB; nginx重点是web服务器,替换的是apache,同时具备lb的作用
  • haproxy有心跳检测,nginx需要集成第三方插件
  • haproxy有监控页面
  • haproxy负载均衡算法更多、更好。
  • 支持虚拟主机

如果担心LB单点问题,可采用keepalived+haproxy.

网站并发达到一定程度之后,为了提高稳定性和转发效率,可以使用LVS、毕竟LVS比Nginx/HAproxy要更稳定,转发效率也更高。不过维护LVS对维护人员的要求也会更高,投入成本也更大。

展望

zuul已经开源几年了,现在已有新的开源项目Spring Cloud Gateway,刚开源不久,还不成熟。从其公布的特性,集成了服务发现、断路器、限流等功能。

Spring Cloud Gateway features:

  • Built on Spring Framework 5, Project Reactor and Spring Boot 2.0
  • Able to match routes on any request attribute.
  • Predicates and filters are specific to routes.
  • Hystrix Circuit Breaker integration.
  • Spring Cloud DiscoveryClient integration
  • Easy to write Predicates and Filters
  • Request Rate Limiting
  • Path Rewriting

参考文献

  1. zull wiki
  2. spring-cloud-netflix官网手册
  3. springcloud(十):服务网关zuul初级篇 ----环境搭建入门参考
  4. Zuul的高可用
  5. API GateWay(网关)那些儿事
  6. zuul 参数调优
  7. zuul进行rate limit

tips:本文属于自己学习和实践过程的记录,很多图和文字都粘贴自网上文章,没有注明引用请包涵!如有任何问题请留言或邮件通知,我会及时回复。

springcloud实践(二)之api网关:zuul的更多相关文章

  1. Spring-cloud微服务实战【八】:API网关zuul

      在前面的文章中,我们先后使用了eureka/ribbon/feign/hystrix搭建了一个看似完美的微服务了,那是否还有值得继续优化的地方呢?答案肯定是有的,如果从整个微服务内部来看,基本已经 ...

  2. 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul

    通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...

  3. 基于spring-cloud的微服务(4)API网关zuul

    API网关是微服务架构中的很重要的一个部分,内部有多个不同的服务提供给外部来使用,API网关可以对外做统一的入口,也可以在网关上做协议转换,权限控制和请求统计和限流等其他的工作 spring-clou ...

  4. springCloud学习05之api网关服务zuul过滤器filter

    前面学习了zuul的反向代理.负载均衡.fallback回退.这张学习写过滤器filter,做java web开发的对filter都不陌生,那就是客户端(如浏览器)发起请求的时候,都先经过过滤器fil ...

  5. Spring Cloud 微服务二:API网关spring cloud zuul

    前言:本章将继续上一章Spring Cloud微服务,本章主要内容是API 网关,相关代码将延续上一章,如需了解请参考:Spring Cloud 微服务一:Consul注册中心 Spring clou ...

  6. 白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理

    前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明.而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等.今天,我们就来了解下 ...

  7. 白话SpringCloud | 第九章:路由网关(Zuul)的使用

    前言 介绍完分布式配置中心,结合前面的文章.我们已经有了一个微服务的框架了,可以对外提供api接口服务了.但现在试想一下,在微服务框架中,每个对外服务都是独立部署的,对外的api或者服务地址都不是不尽 ...

  8. Spring Cloud第十四篇 | Api网关Zuul

    ​ 本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...

  9. SpringCloud实战 | 第四篇:SpringCloud整合Gateway实现API网关

    一. 前言 微服务实战系列是基于开源微服务项目 有来商城youlai-mall 版本升级为背景来开展的,本篇则是讲述API网关使用Gateway替代Zuul,有兴趣的朋友可以进去给个star,非常感谢 ...

  10. Netflix正式开源其API网关Zuul 2

    5 月 21 日,Netflix 在其官方博客上宣布正式开源微服务网关组件 Zuul 2.Netflix 公司是微服务界的楷模,他们有大规模生产级微服务的成功应用案例,也开源了相当多的微服务组件(详见 ...

随机推荐

  1. STL源码剖析——序列式容器#2 List

    list就是链表的实现,链表是什么,我就不再解释了.list的好处就是每次插入或删除一个元素,都是常数的时空复杂度.但遍历或访问就需要O(n)的时间. List本身其实不难理解,难点在于某些功能函数的 ...

  2. IDEA远程DEBUG Tomcat配置

    IDEA远程DEBUG Tomcat配置 IDEA远程DEBUG Tomcat很简单,配置如下: 1.修改tomcat服务器配置 打开tomcat/bin/catalina.sh 在空白处添加如下参数 ...

  3. [LOJ2065] [SDOI2016]模式字符串

    题目链接 洛谷:https://www.luogu.org/problemnew/show/P4075 LOJ:https://loj.ac/problem/2065 Solution 这种题看起来就 ...

  4. [洛谷P5377][THUPC2019]鸽鸽的分割

    题目大意:有一个圆,圆上有$n$个点,将这几个点两两连接,问最多分成几部分 题解:发现这相当于一个平面图,由欧拉公式得($F$为平面分割块数,$E$为平面图边数,$V$为平面图点数):$$F=E-V+ ...

  5. HDU6037 Expectation Division 期望、高维前缀和

    传送门 设\(f_x\)表示答案,那么\(f_x = \frac{\sum\limits_{d \mid x} f_d}{\sigma_0(x)} + 1 = \frac{\sigma_0(x) + ...

  6. System.AccessViolationException处理

    程序出现 System.AccessViolationException异常会终止进程,try catch是无法捕捉的. 有个处理方法在引发异常的发放上面加上 [System.Runtime.Exce ...

  7. 【转载】Java对象的生命周期

    Java对象的生命周期 在Java中,对象的生命周期包括以下几个阶段: 1.      创建阶段(Created) 2.      应用阶段(In Use) 3.      不可见阶段(Invisib ...

  8. node作为前台的项目如何打包静态js和css并生成版本号,loader插件的使用

    一.使用场景: 1.node创建的前台项目需要输入地址展示页面 2.有设置缓存或者cdn的需要在静态文件更改时能使用新的而不是缓存的,需要版本号这里 3.可能需要压缩静态文件的 二.一些参考地址,需要 ...

  9. js 算法,判断一个数组中的数字出现多少次

    let arr = [11, 11, 2, 2, 5, 5, 5, 5, 3]; //创建一个map,把每个数字和其个数相对应 let countObj = {}; for (i = 0; i < ...

  10. Js保存图片到本地

    注:此方法是使用hbuilderx云打包之后才能用,否则在浏览器中会报 plus is not defined 官方文档 http://www.html5plus.org/doc/zh_cn/gall ...