概述

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. mysql insert的特殊用法

    1. 正常的insert语句:插入一条数据如下:INSERT INTO `testdb`.`tb_user` (`id`, `userName`) VALUES (3, '张飞'); 2. inser ...

  2. Go 接口-契约介绍

    Go 接口-契约介绍 目录 Go 接口-契约介绍 一.接口基本介绍 1.1 接口类型介绍 1.2 为什么要使用接口 1.3 面向接口编程 1.4 接口的定义 二.空接口 2.1 空接口的定义 2.2 ...

  3. 【源码解读(二)】EFCORE源码解读之查询都做了什么以及如何自定义批量插入

    引言 书接上回,[源码解读(一)]EFCORE源码解读之创建DBContext查询拦截,在上一篇文章中,主要讲了DBContext的构造函数,以及如何缓存查询方法提升查询性能,还有最重要的拦截查询,托 ...

  4. 简单地聊一聊Spring Boot的构架

    本文由葡萄城技术团队发布.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 本文小编将详细解析Spring Boot框架,并通过代码举例说明每个层的作用 ...

  5. 6k Star!B站、滴滴、小红书都在用的网站防火墙

    你有网站么?你担心网站被黑客攻击么?你知道如何抵御来自黑客的攻击吗? 据称互联网上有 30% 的流量都来自于恶意攻击.做过 Web 开发或者有过建站经验的朋友对 SQL 注入.CC 攻击.XSS.We ...

  6. HarmonyOS 开发入门(二)

    HarmonyOS 开发入门(二) 日常逼逼叨 在HarmonyOS 开发入门(一)中我们描述了 HarmonyOS 开发的语言ArKTs以及Ts简单的入门级语法操作,接下来我们进入第二部分Harmo ...

  7. 【Javaweb】Servlet三|实现Servlet程序的几种方法及Servlet继承体系说明

    GET和POST请求的分发处理 代码如下 注意页面要和index位置一样否则浏览器找不到 注意大小写 HttpServletRequest httpServletRequest = (HttpServ ...

  8. 一文秒懂|Linux字符设备驱动

    1.前言 众所周知,Linux内核主要包括三种驱动模型,字符设备驱动,块设备驱动以及网络设备驱动. 其中,Linux字符设备驱动,可以说是Linux驱动开发中最常见的一种驱动模型. 我们该系列文章,主 ...

  9. IDEA的两个实用插件“汉化”和“翻译”

    1.汉化包插件 Chinese (Simplified) Language Pack EAP 2.翻译插件 translation 3.效果图 这两个不局限这一软件,IntelliJ这一公司旗下都可以 ...

  10. MySQL 分组排序后 → 如何取前N条或倒数N条

    开心一刻 晚上,老婆辅导女儿写语文作业 填空题:春天来了,__绿了 女儿:春天来了,爸爸绿了 老婆一脸不悦地问道:你再说一遍,春天来了,什么玩意绿了? 女儿:春天来了,爸爸绿了呀 老婆很生气,但依旧温 ...