概述

Spring Cloud Zuul 是 Spring Cloud Netflix 子项目的核心组件之一,可以作为微服务架构中的 API 网关使用,有以下用途:

  • 鉴权:对于访问每个服务的请求进行鉴权,拒绝鉴权失败的请求
  • 监控:对系统的请求进行监控,记录请求响应日志,实时统计当前系统的访问量以及监控状态
  • 压力测试:帮助对集群进行可控的压力测试
  • 灰度测试:灰度发布可以保证整体系统的稳定,在初始灰度时就可以发现问题并进行调整
  • 动态路由:基于请求路径,将请求分发到指定的客户端
  • 负载控制:统一控制客户端请求压力,超过压力的请求直接拒绝
  • 静态响应处理:在边缘位置直接建立部分响应,避免其流入内部集群

构建 Zuul 网关

创建 zuul-service 项目,引入依赖,本项目基于 SpringBoot 2.3.1,SpringCloud Hoxton.SR12

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

在 application.yml 配置文件中添加如下配置:

server:
port: 9080 # 指定运行端口 spring:
application:
name: zuul-service # 指定服务名称 zuul:
routes:
blog:
path: /baidu/**
url: https://www.baidu.com # url用于配置符合path的请求路径路由到的服务地址

在启动类中添加 @EnableZuulProxy 注解

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

Spring Cloud Netflix Zuul 提供了许多过滤器,具体取决于启用的 Zuul 的注解,@EnableZuulProxy@EnableZuulServer 的超集,包含 @EnableZuulServer 安装的所有过滤器

启动项目,在浏览器中输入访问地址 http://localhost:9080/baidu,发现请求被路由到百度界面,Zuul 服务搭建成功

Zuul 路由配置

上一节,我们使用路径的方式匹配路由规则,path 的结构如下

# 其中customName 为用户自定义名称
zuul:
routes:
customName:
# 可使用的通配符有以下几种:
# ?:单个字符
# *:任意多个字符,不包含多级路径
# **:任意多个字符,包含多级路径
path: xxx

对于 url 路径匹配,还可以使用服务名称匹配

zuul:
routes:
# users为用户自定义名称
users:
path: /users/**
# serviceId用于配置符合path的请求路径路由到的服务名称
serviceId: users-service

服务名称匹配也可以使用简化的配置

zuul:
routes:
service-provider:
path: /users/**

如果只配置 path 不配置 serviceld,则 customName 相当于服务名称,即 service-provider 会被当作服务名称,使用 serviceId 要将 zuul 服务注册到注册中心使用,比如 Eureka,从而拉取注册服务列表名称完成调用

如果想排查配置,可以使用 ignored-services

zuul:
ignoredServices: "*"
routes:
users:
path: /users/**

ignored-services 可以配置不被 zuul 管理的服务列表,多个服务名称使用号分隔,配置的的务将不被 Zuul代理,在上面的实例中,除了用户服务外,所有的服务均被忽略

可以通过 zuul.prefix 配置路由前缀,例如:

zuul:
prefix: /api
routes:
users:
path: /users/**

配置请求路径前缀,所有基于此前缀的请求都由 Zuul 网关提供代理

Zuul 过滤器

Zuul 定义过滤器用来过滤代理请求,提供额外功能逻辑,如权限验证、日志记录等,filter 与 filter 之间不直接通信,在请求线程中会通过 RequestContext 来共享状态,它内部是用 ThreadLocal 实现的

Zuul 过滤器分为前置过滤、路由后过滤、后置过滤以及异常过滤:

  • 前置过滤:在请求进入 Zuul 后,立刻执行的过滤逻辑
  • 路由后过滤:在请求进入 Zuul 后,Zuul 实现请求路由,并在远程服务调用之前执行过滤逻辑
  • 后置过滤:远程服务调用结束后执行过滤逻辑
  • 异常过滤:任意一个过滤器发生异常或远程服务调用无结果反馈时(调用超时)执行过滤逻辑

ZuulFilter 类及其父类 IZuulFilter 共提供了四种抽象方法:

  • filterType:返回字符串数据,代表当前过滤器的类型,可选值有:

    • pre:前置过滤器,在请求被路由前执行,通常用于处理身份认证、日志记录等
    • route:在路由执行后,服务调用前被调用
    • error:任意一个 filter 发生异常或远程服务调用没有反馈时执行(超时),通常用于处理异

    • post:在 route 或 error 执行后被调用,一般用于收集服务信息、统计服务性能指标等,也可以对 response 结果做特殊处理
  • filterOrder:返回 int 数据,用于为同一种 filterType 的多个过滤器定制执行顺序,返回值越小,执行顺序越优先
  • shouldFilter:返回 boolean 数据,代表当前 filter 是否生效
  • run:具体的过滤执行逻辑

具体实例如下:

@Component
public class tokenFilter extends ZuulFilter { @Override
public String filterType() {
//定义过滤器的类型,pre 表示在请求被路由前执行
return "pre";
} @Override
public int filterOrder() {
//返回int 数据,用于为同一种 filterType 的多个过滤器定制执行顺序
//返回值越小,执行顺序越优先
return 0;
} @Override
public boolean shouldFilter() {
//判断过滤器是否生效,true 代表生效
return true;
} @Override
public Object run() throws ZuulException {
//获取上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//获取 request 对象
HttpServletRequest request = currentContext.getRequest();
//从请求头获取 token 的参数
String userToken = request.getParameter("token");
if (StringUtils.isEmpty(userToken)) {
//返回错误提示
//false:表示不会继续往下执行,不会调用服务接口,直接响应给客户
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("token is null");
currentContext.setResponseStatusCode(401);
return null;
}
//否则正常执行,调用服务接口...
return null;
}
}

微服务网关 —— SpringCloud Netflix Zuul的更多相关文章

  1. 第二章 微服务网关基础组件 - zuul入门

    一.zuul简介 1.作用 zuul使用一系列的filter实现以下功能 认证和安全 - 对每一个resource进行身份认证 追踪和监控 - 实时观察后端微服务的TPS.响应时间,失败数量等准确的信 ...

  2. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  3. 8. 使用Zuul构建微服务网关

                    使用Zuul构建微服务网关 8.1. 为什么要使用微服务网关 8.2. Zuul简介 8.3. 编写Zuul微服务网关 8.4. Zuul的路由端点 8.5. Zuul ...

  4. springcloud使用Zuul构建微服务网关入门

    为什么要使用微服务网关 不同的微服务一般会经过不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求. 如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会多次请求不同的微 ...

  5. springcloud(十四):搭建Zuul微服务网关

    springcloud(十四):搭建Zuul微服务网关 1. 2. 3. 4.

  6. springcloud(十)-Zuul微服务网关

    为什么要使用微服务网关 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服 ...

  7. 小D课堂 - 新版本微服务springcloud+Docker教程_6-06 zuul微服务网关集群搭建

    笔记 6.Zuul微服务网关集群搭建     简介:微服务网关Zull集群搭建 1.nginx+lvs+keepalive      https://www.cnblogs.com/liuyisai/ ...

  8. 微服务网关哪家强?一文看懂Zuul, Nginx, Spring Cloud, Linkerd性能差异

      导语:API Gateway是实现微服务重要的组件之一.面对诸多的开源API Gateway,如何进行选择也是架构师需要关注的焦点.本文作者对几个较大的开源API Gateway进行了压力测试,对 ...

  9. SpringCloud Gateway微服务网关实战与源码分析-上

    概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...

  10. 小D课堂 - 新版本微服务springcloud+Docker教程_6-01 微服务网关介绍和使用场景

    笔记 第六章 微服务网关zuul开发实战 1.微服务网关介绍和使用场景     简介:讲解网关的作用和使用场景 (画图)          1)什么是网关         API Gateway,是系 ...

随机推荐

  1. rust程序设计(5)结构体相关练习题| 附带解答

    题目 基础结构体练习: 创建一个名为Person的结构体,包含name(字符串类型)和age(整数类型)两个字段. 写一个函数,接收一个Person实例作为参数,并打印出这个人的名字和年龄. 结构体方 ...

  2. Numpy理解

    目录 什么是numpy numpy的安装 numpy数组 定义numpy数组 numpy数组的相关功能 基本操作 0数组和1数组 随机数组 二维数组 numpy的数组操作 我们再平常学习python和 ...

  3. Markdown 跳转到本文章标题

    一.只可以在Markdown文件中跳转 1.因为 Markdown 文件标题就是 Markdown 一种锚点 任何级别的标题可以直接作为锚点目标.如果标题比较固定(不是经常改来改去),可以直接使用标题 ...

  4. Hive数据库数据表元数据导出脚本

    表结构导出 ## @Title Hive库表元数据导出脚本 ## @Author changxy #!/bin/bash ##############注意修改Hive连接信息############# ...

  5. video和表单组件(不常用 类型太少)

    h5不能自动播放,只有在静音的前提下才能 button:(种类太少 不能满足需求) <button size="mini" type="primary" ...

  6. 18、defer

    1.defer是什么? 字面意思来看,defer是延迟,推迟的意思 在go语言中,使用defer关键字来延迟一个函数或者方法的执行 2.defer能干嘛? 对象.close(),临时文件的删除 文件. ...

  7. keystone和beaengine的编译

    编译Keystone 根据github的文档编译不出来,所以还是用CMake项目转成Visual Studio的项目来编译 1.下载源码 https://github.com/keystone-eng ...

  8. String与StringBuilder的互相转换

    String与StringBuilder的互相转换 String转StringBulider StringBuilder sb = new StringBuilder(); sb.append(use ...

  9. 文心一言 VS 讯飞星火 VS chatgpt (167)-- 算法导论13.1 7题

    七.用go语言,试描述一棵含有 n 个关键字的红黑树,使其红色内部结点个数与黑色内部结点个数的比值最大.这个比值是多少? 该比值最小的树又是怎样呢?比值是多少? 文心一言: 红黑树是一种自平衡的二叉查 ...

  10. MinIO客户端之head

    MinIO提供了一个命令行程序mc用于协助用户完成日常的维护.管理类工作. 官方资料 mc head 查看对象的前N行内容,N默认为10,命令如下: ./mc head local1/bkt1/doc ...