关于spring:SpringCloud-第十二篇-Zuul概念及原理一

28次阅读

共计 4960 个字符,预计需要花费 13 分钟才能阅读完成。

1:Zuul 是什么

Zuul 是 Netflix 开源的 API 网关。
API 网关,相似于面向对象设计模式中的 Facade 模式,它的存在就像是整个微服务架构零碎的门面一样,所有的内部客户端拜访都须要通过它来进行调度和过滤,它除了要实现申请路由,负载平衡,起源合法性检测,权限校验,反爬虫等性能之外,还须要更多能力,比方与服务治理框架的联合,申请转发时的熔断机制,服务的聚合等一系列的高级性能。
官网:https://github.com/Netflix/zuul/

2:Zuul 能干什么

  • 身份验证和平安 – 辨认每个资源的身份验证要求,并回绝不满足的申请
  • 审查和监测 – 跟踪边缘的有意义的数据和统计数据,以便咱们精确地理解生产运行状况
  • 动静路由 – 依据须要将申请动静路由到不同的后端集群
  • 压力测试 – 逐步减少到集群的流量,以掂量性能
  • 负载调配 – 为每种类型的申请调配容量并删除超出限度的申请
  • 动态响应解决 – 间接在边缘构建一些响应,而不是将它们转发到外部集群

3: 流程图

4:Zuul 有什么

Zuul 蕴含了对申请的路由和过滤两个最次要的性能:

其中路由性能负责将内部申请转发到具体的微服务实例上,是实现内部拜访对立入口的根底
而过滤器性能则负责对申请的处理过程进行干涉,是实现申请校验、服务聚合等性能的根底
然而实际上,路由性能在真正运行时,它的路由映射和申请转发都是由几个不同的过滤器实现的。其中,路由映射次要通过 pre 类型的过滤器实现,它将申请门路与配置的路由规定进行匹配,以找到须要转发的指标地址;而申请转发的局部则是由 route 类型的过滤器来实现,对 pre 类型过滤器取得的路由地址进行转发

5:HelloWorder

  • 退出依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
  • 配置示例,留神 serviceId 须要全小写
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
server.port=8780
spring.application.name=service-zuul

zuul.routes.api-a.path=/aa/**
zuul.routes.api-a.serviceId=userservice

zuul.routes.api-b.path=/bb/**
zuul.routes.api-b.serviceId=service-feign
  • 启动类退出注解
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication

1:@EnableZuulProxy 开启 Zuul 服务,将本地调用转发到相应的服务,Zuul 应用 Ribbon 来定位一个要转发到的服务实例,并且所有申请都以 hystrix 命令执行
2:留神 @EnableZuulProxy 不包含发现服务的客户端,因而对于基于服务 ID 的路由,还须要提供服务治理(例如 Eureka)
3:应用 @EnableZuulServer 也能够运行不带代理的 Zuul 服务器,差异是它不会主动增加任何代理过滤器,也没有服务发现和代理

  • 测试运行

1:如果配置文件外面没有配置 zuul 的话,zuul 会把 Eureka Server 外面的服务都读取进去,此时运行的时候,须要用各个服务的 serviceId 做为 ContextPath
2:如果配置了 zuul,还能够用配置的前缀代替服务的 serviceId,而后进行拜访
3:如果不心愿间接应用 serviceId 进行拜访,能够配置 ignored-services: ‘’,例如:zuul.ignored-services=’’,当然能够不必 *,而是间接把要禁用的服务的 serviceId 列举进去,用逗号离开

6:传统路由配置

所谓的传统路由配置形式就是在不依赖于服务发现机制的状况下,通过在配置文件中具体制订每个路由表达式实例的映射关系来实现 api 网关对外部申请的路由。

  • 单实例配置:

通过 zuul.routes.<route>.path 与 zuul.routes.<route>.url 参数对的形式进行配置,如:

zuul.routes.cc.path=/cc/**
zuul.routes.cc.url=http://localhost:8769
  • 多实例配置

通过 zuul.routes.<route>.path 与 zuul.routes.<route>.serviceId 参数的形式进行配置,联合 Ribbon 来做负载平衡,且让 Ribbon 敞开和 Eureka 的联合,比方:

zuul.routes.cc.path=/cc/**
#zuul.routes.cc.url=http://localhost:8769
zuul.routes.cc.serviceId=ccservice

ribbon.eureka.enabled=false
ccservice.ribbon.listOfServers=http://localhost:8769/,http://localhost:8768/   

这种简略的 URL 路由不会被执行为 HystrixCommand,也不能应用 Ribbon 对多个 URL 进行负载平衡

7:服务路由配置

spring cloud zuul 整合了 spring cloud eureka,实现了对服务实例的自动化保护,那么应用服务路由配置的时候,不须要像传统路由配置形式那样为 serviceId 指定具体服务实例地址,只须要通过 zuul.routes.<route>.path 与 zuul.routes.<route>.serviceId 参数对的形式进行配置即可。
还能够简化配置,间接设置 <route> 为具体的 serviceId,例如:

zuul.routes.service-feign.path=/dd/**

请记得开启后面示例中敞开的 Ribbon 和 Eureka 的联合。

8:服务路由的默认规定

大部分的路由规定机会都会采纳服务名作为内部申请的前缀,zuul 曾经主动的帮咱们实现以服务名作为前缀的映射,不须要去配置它。
如果不心愿内部能间接拜访,能够应用 zuul.ignored-services 参数来设置一个服务名匹配表达式来定义不主动创立路由的规定。

9:自定义路由映射关系

有时候,为了兼容内部不同版本的客户端程序,咱们须要在微服务接口上定义版本的标记,比方:service-v1、service-v2,而这样在映射的时候不太好治理。
通常的做法是为这些不同版本的微服务利用,生成以版本号作为路由前缀定义规定的路由规定,比方 /v1/userservice/,具体示例如下:

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

门路匹配

在 zuul 中,路由匹配的门路表达式采纳 ant 格调定义:
1:? 匹配任意单个字符
2:* 匹配任意数量的字符
3:** 匹配任意数量的字符,反对多级目录

留神:当存在多个匹配的路由规定时,匹配后果齐全取决于路由规定的定义程序
因为 properties 的配置内容无奈保障有序,所以当呈现这样的状况的时候,为了保障路由的优先程序,须要应用 yml 文件来配置,以实现有序的路由规定

10:cookie 与头信息

默认状况下,spring cloud zuul 在申请路由时,会过滤掉 http 申请头信息中一些敏感信息,避免它们被传递到上游的内部服务器。
默认的敏感头信息通过 zuul.sensitiveHeaders 参数定义,默认包含 cookie,set-Cookie,authorization 三个属性。
这会引发一个常见的问题,应用了 spring security,shiro 等平安框架构建的 web 利用,通过 spring cloud zuul 构建的网关来进行路由时,因为 cookie 信息无奈传递,web 利用将无奈实现登录和鉴权。为了解决这个问题,配置的办法能够为:

1:通过设置全局参数为空来笼罩默认值,如:
zuul.sensitiveHeaders=
不举荐这种做法,范畴太大
2:将指定路由的敏感头设置为空,如:
zuul.routes.userservice.sensitiveHeaders=

11:重定向问题

应用 API 网关的一个重要起因就是将网关作为对立入口,从而不裸露所有外部服务细节。但咱们在利用外部跳转的 url 却是具体 web 利用实例的地址,而不是通过网关的路由地址,该问题的根本原因在于 spring cloud zuul 在路由申请时,并没有将最后的 host 信息设置正确,怎么办呢?
配置 zuul.add-host-header=true 即可

12:路由回退

12.1:Hystrix 和 ribbon 反对

  • Spring Cloud Zuul 默认集成了 Hystrix 和 Ribbon,天然就领有线程隔离和断路器,以及对服务调用的客户端负载平衡性能。须要留神的是,当应用 path 与 url 的映射关系来配置路由规定的时候,对于路由转发的申请不会采纳 hystrixCommand 来包装,所以这类申请没有线程隔离和断路器的爱护,并且也不会有负载平衡的能力。因而,咱们在应用 zuul 的时候尽量应用 path 和 serviceId 的组合来进行配置,这样不仅能够保障 api 网关的强壮和稳固,也能用到 ribbon 的客户端负载平衡性能。
  • 所有路由的默认 Hystrix 隔离模式(ExecutionIsolationStrategy)为 SEMAPHORE

12.2:Hystrix 的路由回退

  • 能够通过创立 ZuulFallbackProvider 类型的 bean 来提供回退响应
  • zuul 首先会去判断是否存在自定义的 zuulFallbackProvider,如果有,那么间接回调你自定义实现类的 fallbackResponse()办法。如果不存在会走 hystrix 的 fallback 逻辑(有可能间接抛出异样)
  • 尽管 Zuul 提供了降级的回调办法 fallbackResponse(),然而这个办法是无参的,也就是说此时尽管你可能给调用端返回一个音讯,然而此时你并不知道产生了什么样的异样(也就是说在这里你是获取不到异样信息的)。

13:申请路由其它配置

  • 路由前缀

zuul.prefix:为路由规定减少前缀,例如:zuul.prefix=/user。
zuul.strip-prefix(默认为 true):这个设置是在转发申请之前,从申请中删除代理前缀

  • 本地跳转

通过在 serviceId 中应用 forward 来指定须要跳转的服务器资源门路,例如:
zuul.routes.api-t.path=/tt/**
zuul.routes.api-t.serviceId=forward:/tt

  • 疏忽表达式

zuul.ignored-patterns:设置不心愿被 api 网关进行路由的 url 表达式。例如:
ignoredPatterns: //products/
留神:它的范畴并不是针对某个路由,而是对所有路由,所以要小心应用。

  • 路由端点

应用 @EnableZuulProxy,将启用 /routes 端点,可返回映射路由的列表。
能够通过将 endpoints.routes.enabled 设置为 false 来禁用此端点

  • 配置属性

zuul.max.host.connections 已被两个新属性 zuul.host.maxTotalConnections 和 zuul.host.maxPerRouteConnections 替换,别离默认为 200 和 20

  • 性能优化

Zuul 外部路由能够了解为应用一个线程池去发送路由申请,所以咱们也须要扩充这个线程池的容量,如:
zuul.host.max-per-route-connections=1000
zuul.host.max-total-connections=1000

正文完
 0