Spring Cloud入门-Zuul服务网关(Hoxton版本)
-
- 在pom.xml中添加相关依赖
在application.yml中进行配置
在启动类上添加@EnableZuulProxy注解来启用Zuul的API网关功能
常用功能
-
- 启动相关服务
配置路由规则
默认路由规则
负载均衡功能
配置访问前缀
Header过滤及重定向添加Host
查看路由信息
过滤器
-
- 过滤器类型
过滤器的生命周期
自定义过滤器
-
- 添加PreLogFilter类继承ZuulFilter
过滤器功能演示
核心过滤器
禁用过滤器
Ribbon和Hystrix的支持
常用配置
使用到的模块
项目源码地址
项目使用的Spring Cloud为Hoxton版本,Spring Boot为2.2.2.RELEASE版本
|序号|内容|链接地址|
|—|—|—|
深入学习 | 10分钟掌握 Spring Cloud 入门知识 | [
|2|Spring Cloud入门-Eureka服务注册与发现机制(版本号为Hoxton)|[()*
3|Spring Cloud入门-采用Hoxton框架构建的Ribbon服务消费者
|4|Spring Cloud入门-Hystrid(Hxton Version)|[()
|5|Spring Cloud入门概述:Hystrix Dashboard功能介绍与基于Turbine的断路器监控(Hoxton版本)|[()
|6|Spring Cloud入门-OpenFeign服务消费者(Hoxton版本)|[()|
|7|Spring Cloud入门-Zuul服务网关(Hoxton版本)|[)]|
序号为8的文章介绍了Spring Cloud的配置中心功能
- Spring Cloud入门-Bus消息总线(Hoxton版本) | 官方文档
10|Spring Cloud入门-Sleuth服务路径追踪(Hoxton版本)|[()
项目编号为11的文章详细介绍了如何在开发过程中实现服务注册、发现以及配置管理的相关操作(HOTON系列版本),连接地址:连接地址
了解Spring Cloud基础:基于Hoxton版本的网络服务中间件介绍
Spring Cloud基础学习:Admin服务监控管理模块(Hoxton版本)
-
Spring Cloud入门 - Oauth2的应用 (Hoxton版本)
-
Spring Cloud入门 - Oauth2的应用 (Hoxton版本)
|15|Spring Cloud入门——OAuth 2.0认证流程之JSON Web Token集成(Hoxton版本)|[()
Spring Cloud入门——Oauth2认证之通过JWT技术实现了一体化的身份认证流程(HOTON版本)
说明
第18章 Spring Cloud入门:采用Spring Cloud SentinEL技术实现服务的流量控制、熔断机制以及降级保护(Hoxton版本)
19|Spring Cloud入门——Seata解决方案:HT-Cloud Hoxton Edition用于分布式事务处理|
第20项|Spring Cloud入门-综述版(Hoxton系列版本)|[
作为Spring Cloud Netflix子项目的 key module之一,在 微服务 架构中可充当API门户角色,并具备动态路由与过滤功能的能力。本文旨在深入探讨其工作原理及应用场景。
API网关作为微服务架构的服务提供者,在提供统一入口方面发挥着关键作用
这里我们创建一个zuul-proxy模块来演示zuul的常用功能。
在pom.xml中添加相关依赖
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-netflix-zuul
在application.yml中进行配置
server:
port: 8801
spring:
application:
name: zuul-proxy
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8001/eureka/
在启动类上添加@EnableZuulProxy注解来启用Zuul的API网关功能
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ZuulProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulProxyApplication.class, args);
}
}
启动相关服务
此处我们通过启用人脑服务、两个User-Service实例、一个Feign-Service实例和一个Zuul-Proxy组件来演示Zuul系统的常见功能,在服务启动后系统管理界面将展示以下界面

配置路由规则
我们可以通过调整application.yml中的相关参数来实现网络路径的精确分配,在此处设置中,默认将所有访问带有(application.yml)标签的行为导向(user-service)服务,并且对于那些不带(application.yml)标签但带有(feignService)标签的行为,默认会将它们导向(feign-service)服务。
zuul:
routes:
给服务配置路由
user-service:
path: /userService/**
feign-service:
path: /feignService/**
在查看[http://localhost:7545/api/users/4]时会发现该请求被路由到users上
访问该 URL 后可以看到该请求被路由到 feign-service 上。
默认路由规则
结合使用Zuul与Eureka的方式能够完成路由自动化配置,并且自动生成的路由基于服务名称进行路径匹配。这等同于以下配置设置。
默认路由规则
zuul:
routes:
给服务配置路由
user-service:
path: /user-service/**
feign-service:
path: /feign-service/**
通过访问http://localhost:8801/user-service/user/1实现了对user-service的路由成功。
可进入[http://localhost:8801/feign-service/user/1]同样也被路由至feign-service上
如果不想使用默认的路由规则,可以添加以下配置来忽略默认路由配置:
zuul:
#关闭默认路由配置
ignored-services: user-service,feign-service
负载均衡功能
反复调用该URL用于测试,在运行8201和8202的user-service服务时可以看到这些服务会交替输出相关信息。
当前时间为:current\ time时的日志记录为:
INFO级别的日志编号为:
[nio-8202-exec-1]
类名为:
c.j.s.controller.UserController
根据用户ID获取相关信息,
其中用户的名称为:
\user\_name
2019-12-27 21:31:43.262 INFO 13164 — [nio-8202-exec-2] c.j.s.controller.UserController : 通过指定用户的ID获取相关信息, 其用户名为: jourwon
配置访问前缀
通过配置设置可以实现网关路径的前后缀管理,在该处增加了/proxy前缀字段;这样可以让客户端通过[http://localhost:8080/proxy/user-service/user/1]直接访问该服务
zuul:
#给网关路由添加前缀
prefix: /proxy
Header过滤及重定向添加Host
在处理请求路由时,默认情况下Zuul会过滤一些敏感的头部信息。配置项可确保路由过程中不会丢失Cookie或Authorization头信息。
在处理请求路由时,默认情况下Zuul会过滤一些敏感的头部信息。配置项可确保不会丢失Cookie或Authorization头信息。
zuul:
#配置过滤敏感的请求头信息,设置为空就不会过滤
sensitive-headers: Cookie,Set-Cookie,Authorization
Zuul在请求路由时,不会设置最初的host头信息,以下配置可以解决:
zuul:
#设置为true重定向是会添加host请求头
add-host-header: true
查看路由信息
我们可以通过SpringBoot Actuator来查看Zuul中的路由信息。
在pom.xml中添加相关依赖:
org.springframework.boot
spring-boot-starter-actuator
修改application.yaml配置文件,开启查看路由的端点:
management:
endpoints:
web:
exposure:
include: ‘routes’
通过访问http://localhost:8801/actuator/routes查看简单路由信息:

通过访问http://localhost:8801/actuator/routes/details查看详细路由信息:

Zuul的核心组件包括路由系统和过滤机制,
该路由功能的主要职责是将外部网络流量转发至指定的服务实例。
构成了统一访问入口的基本架构。该过滤功能的主要作用是对 incoming 请求进行预处理。
构成了基于安全校验和资源聚合的关键基础。
过滤器类型
Zuul中有以下几种典型的过滤器类型。
pre:在请求被路由到目标服务前执行,比如权限校验、打印日志等功能;
routing:当请求需要被路由至目标服务时进行处理;这表明Apache HttpClient或Netflix Ribbon所采用的机制来构建并发送原始HTTP请求数字。
post:当请求被路由至目标服务后执行时会触发相关操作例如向目标服务的响应中添加元数据的同时也会进行数据统计等统计记录功能
error:请求在其他阶段发生错误时执行。
过滤器的生命周期
此图表展示了HTTP请求经过API网关后的流转路径,在不同类型的过滤器下进行详细说明

自定义过滤器
接下来我们自定义一个过滤器来演示下过滤器的作用。
添加PreLogFilter类继承ZuulFilter
这是一个前置过滤器,用于在请求路由到目标服务前打印请求日志。
@Component
public class PreLogFilter extends ZuulFilter {
The static final Logger instance named LOGGER is obtained from the LoggerFactory and assigned to the PreLogFilter class.
/**
- 过滤器类型,有pre、routing、post、error四种。
*/
@Override
public String filterType() {
return “pre”;
}
/**
- 过滤器执行顺序,数值越小优先级越高。
*/
@Override
public int filterOrder() {
return 0;
}
/**
- 是否进行过滤,返回true会执行过滤。
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
- 自定义的过滤器逻辑,当shouldFilter()返回true时会执行。
*/
@Override
public Object run() throws ZuulException {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String remoteHost = request.getRemoteHost();
String method = request.getMethod();
String requestURI = request.getRequestURI();
LOGGER.info(“Remote host:{},method:{},uri:{}”, remoteHost, method, requestURI);
return null;
}
}
过滤器功能演示
在引入过滤器后,在执行以下操作:访问[http://localhost:8080/user-service/user/1]请求,并生成相应的日志记录。
日期:2019年十二月二十七日 时间:二十一时四十五分四十四秒 微秒值:四十四十五
核心过滤器
|过滤器名称|过滤类型|优先级|过滤器的作用|
|:--|:--|:--|:--|
识别当前请求是通过DispatcherServlet处理还是由ZuulServlet处理。
|Servlet30WrapperFilter|pre|-2|对原始的HttpServletRequest进行包装。|
FormBodyWrapperFilter|pre|-1|将Content-Type为application/x-www-form-urlencoded或multipart/form-data的请求数封装成FormBodyRequestWrapper对象
由 zuul.debug.request 配置决定是否输出 debug 日志信息
|PreDecorationFilter|route|5|对当前请求进行预处理以便执行后续操作。|
利用Ribbon和Hystrix向服务实例发送请求,并返回结果
|SimpleHostRoutingFilter|route|100|仅处理请求上下文中带有routeHost参数的部分,并将流量直接发送至routeHost对应的物理IP地址
SendForwardFilter|route|500|仅当请求上下文中有forward.to参数时会触发特定的本地跳转方式
SendErrorFilter|post|0|在其他过滤器内部发生异常时,该会由其进行处理,并会产生错误响应.
SendResponseFilter|post|1000|根据请求上下文中的响应信息以某种方式组织成功响应的内容。
禁用过滤器
我们可以对过滤器进行禁用的配置,配置格式如下:
