Netflix Zuul 过滤器介绍

Zuul 是 Netflix 开源的一款基于 JVM 的边缘服务网关,它的核心功能之一是通过一系列的过滤器来处理请求。这些过滤器可以对经过网关的请求和响应进行拦截、修改和转发等操作,从而实现诸如安全认证、流量控制、日志记录等功能。

Zuul 请求生命周期

Zuul 请求生命周期如下图:

5325fb41806633845df35214287d9142_1733391582180-32470896-4d4e-42ee-b531-7eba8035a98e.png

当一个请求到达 Zuul 时,执行步骤如下:

(1)执行“pre”类型的过滤器,包含自定义的过滤器;

(2)执行“routing”类型的过滤器;

(3)调用目标服务;

(4)执行“post”类型的过滤器;

(5)响应请求;

注意:如果在执行 Zuul 中“pre”、“routing”和“post”类型过滤器出现异常,则立即执行“error”类型过滤器,且不再执行后续过滤器。例如,在执行“routing”类型过滤器时异常,则执行“error”类型的过滤器,不再执行“post”类型的过滤器。

过滤器类型

前置过滤器(Pre-filters)

在请求被路由到目标服务之前执行。可以用于身份验证、请求验证、参数校验等操作。例如,检查请求中是否包含合法的用户令牌,或者验证请求的参数是否符合预期的格式。

假设我们有一个微服务系统,其中某些服务需要用户登录才能访问。前置过滤器可以检查请求头中的用户认证令牌是否有效。如果令牌无效,过滤器可以直接返回错误响应,阻止请求进一步流向后端服务。

路由过滤器(Route-filters)

用于将请求路由到目标微服务。它可以根据请求的内容动态地选择目标服务,并且可以对请求进行一些修改,比如添加请求头、修改请求路径等。

在一个电商系统中,根据用户请求的 URL(如 /products 或 /orders),路由过滤器可以将请求路由到对应的产品服务或订单服务。并且在路由过程中,它可以添加一些服务发现相关的请求头,帮助后端服务进行负载均衡等操作。

后置过滤器(Post-filters)

在目标服务返回响应之后执行。主要用于对响应进行处理,如添加响应头、记录响应时间、对响应数据进行格式化等操作。

可以用于在响应头中添加服务器版本信息,或者对响应数据进行加密等操作。如果需要统计每个请求的响应时间,后置过滤器可以记录请求开始时间和结束时间,计算出响应时间并记录下来,用于性能监控。

错误过滤器(Error-filters)

当在其他过滤器或者目标服务出现错误时执行。它可以捕获异常,对错误进行统一处理,如返回友好的错误消息、记录错误日志等。

如果后端服务出现故障,返回了 500 内部错误,错误过滤器可以捕获这个错误,将原始的错误信息进行包装,返回一个更友好的错误消息给客户端,比如 “系统繁忙,请稍后再试”,同时将详细的错误日志记录下来,方便开发人员排查问题。

关键名词(Keyword)

类型(Type)

在 Zuul 1.x 中,过滤器类型决定了过滤器在请求-响应生命周期中的位置。如前面所述,有四种主要类型:前置(Pre)、路由(Route)、后置(Post)和错误(Error)。

执行顺序(Execution Order)

每个过滤器都有一个执行顺序编号,通过 filterOrder 方法定义。这个编号决定了同一类型过滤器之间以及不同类型过滤器之间的执行顺序。

数字越小,过滤器越先执行。例如,如果有两个前置过滤器 A 和 B,A 的 filterOrder 为 1,B 的 filterOrder 为 2,那么 A 会在 B 之前执行。不同类型的过滤器也按照这个顺序执行,一般来说,前置过滤器先执行,然后是路由过滤器,接着是后置过滤器,最后是错误过滤器(只有在出现错误时执行)。

执行顺序的重要性在于它可以确保过滤器按照预期的逻辑顺序处理请求和响应。比如,在进行身份验证的前置过滤器应该在路由过滤器之前执行,这样可以防止未经授权的请求被路由到后端服务。

条件(Condition)

条件用于决定过滤器是否执行。在 Zuul 1.x 中,虽然没有像某些高级规则引擎那样复杂的条件判断机制,但可以在过滤器的 run 方法中添加逻辑来判断是否继续执行过滤器。

例如,一个前置过滤器可能会检查请求头中是否存在某个特定的标记,如果不存在,则不执行后续的路由操作,直接返回错误响应。或者一个后置过滤器可以根据响应的状态码来决定是否进行某些特定的处理,如只有当响应状态码为 200 时才记录响应时间。

这种条件判断机制使得过滤器能够根据实际情况灵活地处理请求和响应,避免不必要的处理开销,同时也可以实现更复杂的业务逻辑,如根据不同的请求来源或用户权限进行差异化处理。

动作(Action)

动作是指过滤器在执行过程中采取的具体操作。对于不同类型的过滤器,动作有不同的体现。

在前置过滤器中,动作可能包括从请求中提取信息(如解析请求头中的用户信息)、验证请求参数(如检查参数是否符合格式要求)、修改请求(如添加或修改请求头中的某些字段)或者直接返回响应(如在身份验证不通过时返回 401 错误响应)。

路由过滤器的动作主要是将请求路由到目标微服务,这可能涉及到根据配置信息查找服务实例、构建请求路径、设置请求头用于负载均衡等操作。

后置过滤器的动作可以是对响应进行修改(如添加响应头、修改响应数据)、记录响应相关的信息(如响应时间、响应状态)或者进行其他的后处理操作。

错误过滤器的动作通常是处理错误,如将错误消息转换为用户友好的格式、记录详细的错误日志、返回适当的错误响应状态码(如将内部错误 500 转换为更合适的外部错误码和消息)。

点击下载/查看本教程相关资料或者源代码。
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号