首先有必要了解一下什么是Zuul,它和Spring Cloud有什么关系。

Zuul在Spring Cloud中承担着网关的职责,可以理解为客户端和服务端交互中的唯一通道。所有的客户端请求都会首先发送到网关,而后路由转发到对应的微服务。同时,Zuul还提供了诸如服务聚合、权限校验等,另外也对客户端与服务端的交互起到了解耦的作用。

我们可以通过一个具体的场景来理解一下。假设需要开发一个校园图书管理系统,在客户端可能发起登录、查看图书列表、进行订阅等请求,如下图所示:

而其中,即使是非本校的学生也可以在客户端查询有哪些图书,但是只有登录成功的本校学生才能发起借阅。这时客户端需要做的事情就多了,既要区分不同的请求发往哪个服务,还要判断当前的权限是否可以调用这个服务。另外,在客户端进行权限的控制也存在安全隐患,前后端的职责划分也不够明确。在引入Zuul网关之后的效果是这样:

服务的路由以及权限的校验统统在网关层面完成即可。这样还有一个好处就是后续即使把图书查询服务进行拆分,变成中文图书查询与英文图书查询,或者进行其他的服务合并,对于客户端也基本是无感知了。

了解了Zuul的功能之后,我们来探究一下Zuul的原理。

Zuul的核心是一组过滤器,而Zuul的绝大部分功能也都是通过这一组过滤器实现的。Zuul提供了对这些过滤器进行动态加载、编译以及运行的框架。这一组过滤器包括pre、routing、post、error等,通过一张图片来了解一下这些过滤器分别在一笔请求的哪些环节生效:

从上图中可以看到对应的几类过滤器分别是如下的作用:

PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份认证、在集群中选择具体需要请求的微服务、记录日志信息等。

ROUTING:这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务(题外话:这里也能看出,Ribbon是在客户端实现负载均衡,这一点和Nginx不同)。

POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

ERROR:在其他阶段发生错误时执行该过滤器。

Spring Cloud借助Eureka进行服务注册与发现,微服务的访问通过REST请求。Zuul的访问方式也是REST,其URL地址默认格式为:

http://zuulHostIp:port/要访问的服务名称/服务中的URL

我这里为了方便在一个测试的微服务项目中为Zuul网关添加一个Module(在不在一个项目无所谓,大家通过同一个Eureka服务进行注册发现即可):

pom中需要添加Zuul的相关依赖:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>

application.yml中指定网关服务名、连接的Eureka服务信息等:

server:
port: 10290
spring:
application:
name: spring-cloud-zuul-gateway
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9090/eureka
fetch-registry: true
register-with-eureka: true

接下来我们添加路由配置来验证Zuul的路由转发功能:

zuul:
routes:
spring-cloud-service-provider:
path: /provider/**
url: http://127.0.0.1:10090

spring-cloud-service-provider为路由规则的条目名称。path为向Zuul网关进行请求时紧跟在端口后的服务名称,**表示具体服务下的url。而url项则需要填写目的服务的真实地址端口信息。

创建应用时需要添加自动发现以及Zuul的注解:

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

启动Eureka服务、目的服务以及Zuul网关服务验证一下,没问题:

接下来我们玩一下Zuul的核心,过滤器。可以试着创建一个PRE过滤器,来打印请求的详细信息。

可以看到在继承ZuulFilter类时需要实现如下四个方法:

filterType:表示过滤器类型,值域分别对应不同的生命周期也就是pre、error、post以及route。

filterOrder:同种类(生命周期)过滤器的执行优先级,按照返回值升序进行优先级的确定。

shouldFilter:表示当前过滤器是否生效。

run:过滤器的具体执行逻辑。

补充之后的过滤器代码如下所示:

@Component
public class PreLogFilter extends ZuulFilter { public String filterType() {
return "pre";
} public int filterOrder() {
return 0;
} public boolean shouldFilter() {
return true;
} public Object run() throws ZuulException { RequestContext rc = RequestContext.getCurrentContext();
HttpServletRequest request = rc.getRequest(); System.out.println("PreLogFilter enters with [url=" + request.getRequestURL() + "]...");
return null;
}
}

重新启动Zuul网关服务之后再次进行请求,可以看到控制台打印如下输出:

参考资料:

https://www.cnblogs.com/jing99/p/11696192.html

https://zhuanlan.zhihu.com/p/138943446

https://blog.csdn.net/luckystar_99/article/details/105114198

Spring Cloud Zuul 学习+实践的更多相关文章

  1. Spring Cloud Gateway 学习+实践

    官网上给出的Spring Cloud Gateway特性如下图所示: 翻译过来就是: 基于 Spring Framework 5 ,Project Reactor 以及 Spring Boot 2.0 ...

  2. spring cloud深入学习(十一)-----服务网关zuul

    前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...

  3. 服务网关Spring Cloud Zuul

    Spring Cloud Zuul 开发环境 idea 2019.1.2 jdk1.8.0_201 Spring Boot 2.1.9.RELEASE Spring Cloud Greenwich S ...

  4. Spring Cloud Zuul记录接口响应数据

    系统在生产环境出现问题时,排查问题最好的方式就是查看日志了,日志的记录尽量详细,这样你才能快速定位问题. 如果需要在Zuul中进行详细的日志记录,这两种日志必不可少. API请求信息 API响应信息 ...

  5. API网关服务:Spring Cloud Zuul

    最近在学习Spring Cloud的知识,现将API网关服务:Spring Cloud Zuul 的相关知识笔记整理如下.[采用 oneNote格式排版]

  6. Spring Cloud Zuul 添加 ZuulFilter

    紧接着上篇随笔Spring Cloud Zuul写,添加过滤器,进行权限验证 1.添加过滤器 package com.dzpykj.filter; import java.io.IOException ...

  7. Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。

    时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...

  8. 笔记:Spring Cloud Zuul 快速入门

    Spring Cloud Zuul 实现了路由规则与实例的维护问题,通过 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取了 ...

  9. Spring Cloud Zuul 限流详解(附源码)(转)

    在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法. ...

随机推荐

  1. Android 自定义属性(attrs)、样式(Style)、主题(Theme)

    Android 自定义属性(attrs).样式(Style).主题(Theme) https://www.cnblogs.com/dandre/p/4507024.html https://blog. ...

  2. Tomcat服务器种的HttpServletRequest类

    HttpServletRequest 类有什么作用:             每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Reque ...

  3. mybatis中Oracle及mysql插入时自动生成主键以及返回主键

    mysql的方式: 方式一: useGeneratedKeys="true" keyProperty="id" 方式二: <selectKey keyPr ...

  4. Modify File Descriptor Limit on Linux

    System-wide File Descriptor Limit Get current value: sysctl fs.file-max modify max fd limit: sysctl ...

  5. iOS-block循环引用详解和应用

    Block循环引用 什么情况下block会造成循环引用 ARC 情况下 block为了保证代码块内部对象不被提前释放,会对block中的对象进行强引用,就相当于持有了其中的对象,而如果此时block中 ...

  6. ACL的配置

    一.实验拓扑 实验要求: 二.实验编址 三.实验步骤: 1.启动设备(全选) 2.配置端口IP R1: R2: R3: R4: 2.搭建OSPF网络: R1: R2: R3: R4: 4.配置ACL控 ...

  7. NOIP 模拟 $28\; \rm 割海成路之日$

    题解 \(by\;zj\varphi\) 用两个集合分别表示 \(1\) 边联通块,\(1,2\) 边联通块 . \(\rm son_x\) 表示当前节点通过 \(3\) 类边能到的 \(2\) 联通 ...

  8. MongoDB使用命令创建用户权错误分析--- 权限不够Error:couldn't add user:command createUser requires authentication

    MongoDB使用命令创建用户权错误分析 错误一:权限不够Error:couldn't add user:command createUser requires authentication. 解决方 ...

  9. C#中调用c++的dll具体创建与调用步骤,亲测有效~ (待验证)

    使用的工具是VS2010哦~其他工具暂时还没试过 我新建的工程名是my21dll,所以会生成2个同名文件.接下来需要改动的只有画横线的部分 下面是my21dll.h里面的... 下面的1是自动生成的不 ...

  10. 字符串拷贝函数递归与非递归的C语言实现

    初学递归的时候,觉得很抽象,不好分析,确实如此,尤其是有些时候控制语句不对,导致程序进去无限次的调用,更严重的是栈溢出.既要正确的控制结束语句,又要有正确的进入下次递归的语句,还要有些操作语句.... ...