天天看点

springcloud zuulZuul 简介

Zuul 简介

Zuul是Netflix开源的微服务网关, 它可以和Eureka、Ribbon, Hystrix等组件配合使用。

Zuul的核心是一系列的过滤器, 这些过滤器可以完成以下功能。

  • .身份认证与安全: 识别每个资源的验证要求, 并拒绝那些与要求不符的请求。
  • 审查与监控: 在边缘位置追踪有意义的数据和统计结果, 从而带来精确的生产视图。
  • 动态路由: 动态地将请求路由到不同的后端集群。
  • 压力测试: 逐渐增加指向集群的流量, 以了解性能。
  • 负载分配: 为每一种负载类型分配对应容量, 并弃用超出限定值的请求。
  •  静态响应处理: 在边缘位置直接建立部分响应, 从而避免其转发到内部集群。
  • 多区域弹性: 跨越AWS Region进行请求路由, 旨在实现ELB (Elastic Load Balancing)
  • 使用的多样化, 以及让系统的边缘更贴近系统的使用者

优点

  1. 易于监控,可在微服务网关收集监控数据并将其推送到外部系统进行分析。
  2. 易于认证,可在微服务网关上进行认证, 然后再将请求转发到后端的微服务, 而无须在每个微服务中进行认证。
  3. 减少了客户端与各个微服务之间的交互次数

使用

// pom引入组件依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

//修改配置文件
spring:
  application:
    name: exam-gateway
eureka:
  client:
      service-url:
        defaultZone: http://localweb1:8092/eureka,http://localweb1:8091/eureka
server:
  port: 8070
  servlet:
    context-path: /api


// 启动类增加注解
//@EnableZuulProxy简单理解为@EnableZuulServer的增强版,当Zuul与Eureka、Ribbon等组件配合使用时,我们使用@EnableZuulProxy
@EnableZuulProxy
@SpringBootApplication
public class ExamGatewayApplication {
	public static void main(String[] args) {
		SpringApplication.run(ExamGatewayApplication.class, args);
	}

}
           

说明:默认情况下, Zuul会代理所有注册到Eureka Server的微服务, 并且Zuul的路由规则如下:

http://ZUUL_HOST:ZUUL_PORT/微服务serviceld/** 会被转发到 serviceld对应的微服务

上面的访问地址应该是http://localhost:8070/api/exam/exam/hello ,其中exam是我的服务名,并配置了context-path:exam,访问上面地址会默认转发到相应服务,它融合了熔断器和负载均衡

路由配置详解

1.自定义指定微服务的访问路径。
配置zuul.routes.指定微服务的serviceld =指定路径即可。 例如:
zuul:
    routes:
        microservice-provider-user: /user/**
所有匹配/user/** URL的都将被转发到microservice-provider-user
例如:
zuul:
  routes:
    exam:
      path: /ex/**
访问 http://localhost:8070/api/ex/exam/hello 等同于访问http://localhost:8070/api/exam/exam/hello
ex后面多出的部分会追加到映射的服务后面

2.忽略指定微服务。
忽略服务非常简单, 可以使用zuul.ignored-services配置需要忽略的服务, 多个用逗
号分隔。 例如:
zuul:
    ignored-services: microservice-provider-user,microservice-consumer-movie
这样就可让 Zuul 忽略 microservice-provider-user 和 microservice-consumer-movie 微月艮
务, 只代理其他微服务。

3. 忽略所有微服务, 只路由指定微服务。
很多场景下, 可能只想要让Zuul代理指定的微服务, 此时可以将zuul. ignored-services
设为*。
zuul:
    ignored-services: #使用可忽略所有微服务
    routes:
        microservice-provider-user: /user/**
这样就可以让Zuul只路由microservice-provider-user微服务。

4. 同时指定微服务的serviceld和对应路径。 例如:
zuul:
routes:
    user-route: 
    //井该配置方式中, user-route只是给路由一个名称, 可以任意起名。
        service-id: provider-microservice-user
        path: /user/**     //# service-id对应的路径
本例配置的效果同示例lo

5. 同时指定path和URL,例如:
zuul:
    routes:
        user-route: #该配置方式中, user-route只是给路由一个名称, 可以任意起名。
        url: http://localhost:8000/ # 指定的url
        path: /user/** # url对应的路径。
这样就可以将Vuser/** 映射至(Jhttp://localhost:8000/**。
需要注意的是, 使用这种方式配置的路由不会作为HystrixCommand执行, 同时也
不能使用Ribbon来负载均衡多个URL0例6可解决该问题。

6. 同时指定path和URL,并且不破坏Zuul的Hystrix、Ribbon特,性。
zuul:
    routes:
        user-route:
            path: /user/**
            service-id: microservice-provider-user
ribbon:
    eureka:
        enabled: false //# 为Ribbon禁用Eureka
        microservice-provider-user:
            ribbon:
                listOfServers: localhost:8000,localhost:8001
这样就可以既指定path与URL,又不破坏Zuul的Hystrix与Ribbon特性了。

7.使用正则表达式指定Zuul的路由匹配规则
借助PatternServiceRouteMapper,实现从微服务到映射路由的正则配置。 例如:
@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
// 调用构造函^PatternServiceRouteMapper(String servicePattern, String routePattern)
// servicePattern指定微月艮务的正则
// routePattern指定路由正则

    return new PatternServiceRouteMapper("(?<name>A.+)-(?<version>v.+$)", "${
version}/${name}");
}
通过这段代码即可实现将诸如microservice-provider-user-vl这个微服务, 映射到/vl/
microservice-provider-user/** 这个路径。
&路由前缀
示例1:
zuul:
    prefix: /api
    strip-prefix: false
    routes:
        microservice-provider-user: /user/**
这样, 访问Zuul的/api/microservice-provider-user/1路径, 请求将会被转发到microservice-provider-user 白勺/api/1

示例2:
zuul:
    routes:
    microservice-provider-user:
        path: /user/**
        strip-prefix: false
这样访问Zuul的/user/1路径,请求将会被转发到microservice-provider-user的/user/l

9 •可参考该 Issue 辅助理解: https://github.com/spring-cloud/spring-cloudnetflix/issues/1365O
e 该特性可能有 Bug,相关 Issue: https://github.com/spring-cloud/springcloud-netflix/issues/15140
9•忽略某些路径
上文讲解了如何忽略微服务, 但有时还需要更细粒度的路由控制。 例如, 想让Zuul
代理某个微服务, 同时又想保护该微服务的某些敏感路径。 此时, 可使用ignoredPatterns,指定忽略的正则。 例如:
zuul:
    ignoredPatterns: /**/admin/** # 忽略所有包含/admin/的路径
    routes:
        microservice-provider-user: /user/**
这样就可将microservice-provider-user微服务映射到/user/**路径, 但会忽略该微服务中
所有包含/admin/的路径
           

zuul过滤器分类

  • PRE Filters(前置过滤器) :当请求会路由转发到具体后端服务器前执行的过滤器,比如鉴权过滤器,日志过滤器,还有路由选择过滤器
  • ROUTING Filters (路由过滤器):该过滤器作用是把请求具体转发到后端服务器上,一般是通过Apache HttpClient 或者 Netflix Ribbon把请求发送到具体的后端服务器上
  • POST Filters(后置过滤器):当把请求路由到具体后端服务器后执行的过滤器;场景有添加标准http 响应头,收集一些统计数据(比如请求耗时等),写入请求结果到请求方等。
  • ERROR Filters(错误过滤器):当上面任何一个类型过滤器执行出错时候执行该过滤器

路由请求的生命周期

springcloud zuulZuul 简介

从上图中我们可以看到,当外部HTTP请求到达API网关服务的时候,

首先它会进入 第一个阶段pre,在这里它会被pre类型的过滤器进行处理,该类型过滤器的主要目的是 在进行请求路由之前做一些前置加工,比如请求的校验等。

在完成了 pre类型的过滤器处 理之后,请求进入第二个阶段routing,也就是之前说的路由请求转发阶段,请求将会被 routing类型过滤器处理。这里的具体处理内容就是将外部请求转发到具体服务实例上去 的过程,当服务实例将请求结果都返回之后,routing阶段完成。

请求进入第三个阶段 post此时请求将会被post类型的过滤器处理,这些过滤器在处理的时候不仅可以获取 到请求信息,还能获取到服务实例的返回信息,所以在post类型的过滤器中,我们可以 对处理结果进行一些加工或转换等内容。

另外,还有一个特殊的阶段error,该阶段只有 在上述三个阶段中发生异常的时候才会触发,但是它的最后流向还是post类型的过滤器, 因为它需要通过post过滤器将最终结果返回给请求客户端

核心原理

Zuul网关的核心是一系列的过滤器,zuul的过滤器分为四种,前置过滤器,路由过滤器,后置过滤器,错误过滤器。当外部HTTP请求到达API网关服务的时候被拦截掉,依次经过前置过滤器、路由过滤器、后置过滤器,每种类型的过滤器是由一些列过滤器组成,这些过滤器是使用责任链方式顺序对请求或者响应结果进行处理的,过滤器之间通过RequestContext参数共享数据,若过滤器处理期间发生异常就会触发特殊过滤器error过滤器,然后将最终结果返回给请求客户端

继续阅读