Zuul入门实战(完整版)

11 Zuul学习

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

经过上面的学习,微服务架构已经初具雏形,但还有一些问题,不同的微服务一般会有不同的网络地址,而外部客户端(例如手机APP)可能需要调用多个服务的接口才能完成一个业务需求。

例如一个电影购票的手机APP,可能会调用多个微服务的接口,才能完成一次购票的业务流程。

用户请求多个微服务来购票
如果让客户端直接与各个微服务通信,会有以下的问题:

  • 客户端会多次请求不同的微服务,增加了客户端的复杂性。
  • 存在跨域请求,在一定场景下处理相对复杂。
  • 认证复杂,每个服务都需要独立认证。
  • 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。
  • 某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问会有一定的困难。

以上问题可借助微服务网关解决。微服务网关是介于客户端和服务器端之间的中间层, 所有的外部请求都会先经过微服务网关。

使用微服务网关后,架构可演变成下图:

使用微服务网关
如图,微服务网关封装了应用程序的内部结构,客户端只须跟网关交互,而无须直接调 用特定微服务的接口。

这样,开发就可以得到简化。不仅如此,使用微服务网关还有以下优点:

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

11.2 Zuul简介

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

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

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

Spring Cloud对Zuul进行了整合与增强。目前,Zuul使用的默认HTTP客户端是Apache HTTPClient,也可以使用 RestClient 或者okhttp3.OkHttpClient。

如果想要使用 RestClient, 可以设置ribbon.restclient.enabled=true;
想要使用okhttp3.OkHttpClient,可以设置 ribbon .okhttp.enabled= true。

11.3 编写微服务网关

新建一个Maven工程microservice-gateway-zuul,pom.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>edu.xja</groupId>
    <artifactId>microservice-gateway-zuul</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR7</spring-cloud.version>
    </properties>

    <dependencies>
<!--引入网关依赖-->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

    <!--lombok所有的子工程都有,而下面的需要在子工程中手动添加。-->
    <dependencyManagement>
        <dependencies>
            <!--springcloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

edu.xja 下新建启动类,ZuulApplication,代码如下:

@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class,args);
    }
}

代码说明:
在启动类上添加注解@EnableZuulProxy ,声明一个Zuul代理。

该代理使用Ribbon来定位注册在Eureka Server中的微服务;

同时,该代理还整合了 Hystrix,从而实现了容错,所有经过Zuul的请求都会在Hystrix命令中执行。

新建application.yml

server:
  port: 8060
spring:
  application:
    name:  microservice-gateway-zuul
# 网关会注册到注册中心

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

这样,一个简单的微服务网关就编写完成了。

从配置可知,此时仅是添加了Zuul的依赖,并将Zuul注册到Eureka Server上。

测试步骤:
启动项目 注册中心 eureka-server

启用服务提供者 microservice-provider-user

启动服务消费者  microservice-conumser-movie

启动网关 microservice-gateway-zuul

访问http://localhost:8060/user-provider/user/3

访问http://localhost:8060/consumer-movie/user/5

说明默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:
http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka 注册中心上的serviced/** 会被转发到 serviceld 对应的微服务。

11.4 管理端点

当@EnableZuulProxy与Spring Boot Actuator配合使用时,Zuul会暴露两个端点:

一个路由管理端点/actuator/routes和/actuator/filters,借助这两个端点,可以方便、直观地查看以及管理Zuul的路由。

查看端点步骤:
spring-cloud-starter-netflix-zuul已经包含了spring-boot-starter-actuator,因此不需再次引入

11.4.1 查看端点步骤

修改application.yml,暴露端点

management:
  endpoints:
    web:
      exposure:
        include: "*"

重启网关

访问:http://localhost:8060/actuator/hystrix.stream 成功,

说明已经zuul已经整合了hystrix。

11.4.2 查看routes端点

访问:http://localhost:8060/actuator/routes 可以查看路由设置

在这里插入图片描述

11.4.3 查看filters端点

访问:http://localhost:8060/actuator/filters 可以查看过滤器端点

在这里插入图片描述
从SpringCloud Edgware版本开始,Zuul提供了filters端点。

访问该端点即可返回Zuul 中当前所有过滤器的详情,并按照类型分类。上面是filters端点的展示结果,从中,我们可以了解当前Zuul中,error、post、pre、route四种类型的过滤器分别有哪些,每个过滤器的order(执行顺序)是多少,以及是否启用等信息。这对Zul问题的定位很有用

11.5 路由配置详解

前文已经编写了一个简单的Zuul网关,并让该网关代理了所有注册到Eureka Server的 微服务。但在现实中可能只想让Zuul代理部分微服务,又或者需要对URL进行更加精确的控制。

Zuul的路由配置非常灵活、简单,下面通过几个示例,详细讲解Zuul的路由配置。

1.自定义指定微服务的访问路径
配置zul.routes.指定微服务的serviceId=指定路径 即可。例如∶

zuul:
  routes:
    user-provider: /usercenter/**

完成设置后,user-provider微服务就会被映射到/usercenter/*路径。

2.忽略指定微服务

忽略服务非常简单,可以使用zul.ignored-services配置需要忽略的服务,多个服间用逗号分隔。例如∶

zuul:
  ignored-services:  user-provider,consumer-movie

这样就可让Zuul忽略 user-provider和 consumer-movie微服务,只代理其他微服务。

3忽略所有微服务,只路由指定微服务
很多场景下,可能只想要让Zul代理指定的微服务,此时可以将zuul.ignored-services
设为’*’。

zuul:
  ignored-services: '*'  #使用'*'可忽略所有微服务
  routes:
      user-provider: /user/**

这样就可以让Zul只路由user-providerr微服务。

4同时指定微服务的serviceld和对应路径。例如∶

zuul:
  routes:
  #该配置方式中,user-route只是给路由一个名称,可以任意起名。
    user-route:
      service-id: user-provider
      # service-id对应的路径
      path: /user/**

11.6 Zuul的过滤器

过滤器是Zuul的核心组件,下面来学习一下Zuul的过滤器。

11.6.1 过滤器类型与请求生命周期

Zuul大部分功能都是通过过滤器来实现的。Zuul中定义了4种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。

  • PRE:这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
  • ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netflix Ribbon请求微服务。
  • POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header.收集统计信息和指标、将响应从微服务发送给客户端等。
  • ERROR:在其他阶段发生错误时执行该过滤器。
    除了默认的过滤器类型,Zuul还允许创建自定义的过滤器类型。例如,可以定制一种 STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。

Zuul请求的生命周期如下图:

在这里插入图片描述

11.6.2 内置过滤器

Spring Cloud 默认为Zuul编写并启用了一些过滤器,这些过滤器有什么用呢?我们结合
@EnableZuulServer 和@EnableZuulProxy 两个注解来学习。

可将@EnableZuulProxy 简单理解为@EnableZuulServer的增强版。事实上,当Zuul与Eureka、Ribbon等组件配合使用时,@EnableZuulProxy 是我们最常用的注解。

@EnableZuulServer 和@EnableZuulProxy 所启用的过滤器,下面类型的过滤器都有。

  • pre类型过滤器
  • route类型过滤器
  • post类型过滤器
  • error类型过滤器
11.6.3 编写Zuul过滤器

理解过滤器类型和请求生命周期后,来编写一个Zuul过滤器。编写Zuul的过滤器非常简单,只须继承抽象类ZuulFilter,然后实现几个抽象方法就可以了。

下面来编写一个简单的Zuul过滤器,让该过滤器打印请求日志。

1.复制项目microservice-gateway-zuul, 将 Artifactld修改为microservice-gateway-zuul- filter。

2.编写自定义Zuul过滤器。

@Slf4j
public class MyZuulFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        log.info(String.format("send %s request to %s", request.getMethod(), request.getRequestURL().toString()));
        return null;
    }
}

由代码可知,自定义的Zuul Filter需实现以下几个方法。

  • filterType:返回过滤器的类型。有pre、route、post、error等几种取值,分别对应上文的几种过滤器。详细可以参考com.netflix.zuul.ZuulFilter.filterType() 中的注释。
  • filterOrder:返回一个int值来指定过滤器的执行顺序,不同的过滤器允许返回相同的数字。
  • shouldFilter :返回一个boolean值来判断该过滤器是否要执行,true表示执行, false表示不执行。
  • run:过滤器的具体逻辑。本例中让它打印了请求的HTTP方法以及请求的地址。

3。修改启动类,为启动类添加以下内容:


@Bean
public MyZuulFilter preRequestLogFilter() {
 return new MyZuulFilter ();
}
测试步骤

启动注册中心

启动服务提供者

启动microservice-gateway-zuul- filter

访问http://localhost:8050/user-provider/user/1

上面只是演示了一个非常简单的过滤器。事实上,我们可以使用过滤器做很多事情,例如安全认证、灰度发布、限流等。

问题:
1、经过过滤器后,如果是一个非法访问,如果直接返回信息,而不是把请求发到后面的微服务上?

2、自学使用Spring Cloud Gateway 搭建网关。

  • 22
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
"getaway zuul" 是一个网络流行语,原意是指一种通过转移注意力或脱身的方式来逃避困难或尴尬局面。这个短语来源于电影《捍卫者联盟》中一只名叫尤尔的角色,它具有很强的逃避能力。 在生活中,我们经常面临各种挑战和压力,有时候可能会感到束手无策或不知所措。这时候,采用getaway zuul的方式可能会给我们带来一些启示。 getaway zuul提醒我们要学会转移注意力和寻找解决问题的新角度。当我们陷入僵局时,可以试着暂时将焦点从问题上转移到其他事物上,例如参加一项爱好活动、与朋友聚会或者只是简单地放松自己。通过转移注意力,我们的思维可能会得到缓解,从而更容易找到解决问题的新方向。 此外,getaway zuul也提醒我们要有一种适时的“脱身”能力。当我们身陷困境或者面对尴尬场面时,有时候选择适当地离开或者改变环境可能会更加明智。这样可以减少冲突的升级或者尴尬的尺度,更有利于我们保持心态的平衡和保护自己的形象。 然而,getaway zuul并不意味着逃避责任或者逃避困难。在面对挑战时,我们要有勇气正视问题,并采取积极的行动来解决。getaway zuul更倾向于提醒我们要灵活应对情况,用更智慧的方式处理问题,而不是盲目地与问题对抗。 在人生的旅途中,getaway zuul 可以给我们带来新的思维角度,帮助我们更好地应对挑战与压力。我们需要学会寻找平衡点,既不被困扰,也不盲目逃避,而是用更明智的方式面对困难,获得更好的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值