服务网关Zuul的概念
服务网关Zuul是Netflix开源的一个用于构建微服务架构的组件,它主要用于解决微服务架构中的路由、负载均衡、安全认证、流量控制等问题。Zuul可以作为一个API网关,接收来自客户端的请求,将请求转发给后端的服务。在请求转发过程中,Zuul提供了多种路由策略,包括基于URL路由、基于服务路由等。此外,Zuul还可以通过过滤器来实现对请求的预处理和后处理,如鉴权、流量控制等操作。Zuul能够有效地解决微服务架构中的服务治理问题,提高了系统的可扩展性、可维护性和安全性。
以下是一个简单的 Spring Cloud 服务网关 Zuul 的图例示例:
在这个示例中,Zuul 作为服务网关位于所有服务和客户端之间。它可以对所有进出系统的请求进行控制和过滤,并将请求转发到不同的微服务。
客户端发送请求到 Zuul,Zuul 根据请求的 URL 和规则将请求路由到不同的微服务。每个微服务都注册在 Eureka 服务注册中心中,Zuul 可以通过 Eureka 服务发现来定位相应的微服务。
简单理解
服务网关相当于介于客户端与服务端之间的中间层,所有的外部请求都会先经过服务网关进行调度和过滤。服务网关除了能实现路由,负载均衡,过滤等功能之外,还能实现服务的请求熔断等。
路由配置规则
1、zuul.routes.serviceId.path
2、zuul.routes.<路由服务名>.path与路由zuul.routes.<路由服务名>.serviceId
serviceId-指定路由的具体服务名,path-配置请求的映射地址(网关通过serviceid调用微服务)
默认情况下Zuul会为Eureka注册中心中所用的服务实例创建映射关系,类似2路由配置规则
默认路由配置规则可通过zuul.ignored-services='*' 来取消
路径匹配
zuul路径配置支持ant风格
Ant 风格的路径匹配规则
?
匹配任意单字符*
匹配任意多个字符- ** 匹配任意数量的的字符或者路径
路由前缀的配置
zuul:
prefix: /api
说明:这个配置将使得所有经过 Zuul 代理的请求的路由前缀被设置为 /api。例如,一个发往 http://localhost:8765/user-service/user/1 的请求将会被重定向到 http://localhost:8080/user/1,其中 /user-service 将会被替换成 /api。
简单实践
搭建由Zuul进行路由转发的微服务
这里只对网关服务进行配置(server,provider,customer的搭建不在这里说明了)
1、使用Spring Initialiar方式创建一个名称为gateway-zuul的服务网关项目,添加Zuul,Eureka Client,Web依赖
2、关于Zuul依赖的问题,高版本的Springboot依赖不支持某些版本Zuul依赖,可降低springboot依赖,如下:
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.duhong</groupId>
<artifactId>gateway-zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway-zuul</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-zuul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.2.10.RELEASE</version>
<!-- <version>2.1.3.RELEASE</version>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、配置yml文件并添加网关映射
server:
port: 8835
spring:
application:
name: gateway-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka
main:
allow-circular-references: true#解决循环依赖问题
zuul: #默认下,zuul会将注册中心所用的服务配置创建映射关系,类似如下
routes:
hystrix-provider: /hystrix-provider/** #serviceId: path
启动类中添加
@SpringBootApplication @EnableZuulProxy
实验效果:
我配置中并没有配置hystrix-client的映射关系,原因在于上述标红部分
Zuul的过滤器
Zuul是Netflix开源的一个微服务网关,用于在微服务架构中进行路由、负载均衡、服务过滤等功能。Zuul的过滤器是它的核心功能之一,可以通过过滤器实现请求的路由、日志记录、安全验证、错误处理等。
Zuul的过滤器分为四种类型:
- 前置过滤器(Pre Filters):在请求被路由之前执行,可以进行身份验证、参数校验、请求限流等操作。
- 路由过滤器(Route Filters):用于将请求路由到具体的服务实例上,可以实现负载均衡等功能。
- 后置过滤器(Post Filters):在请求被路由到服务实例之后执行,可以进行响应的格式化、日志记录、统计信息收集等操作。
- 错误过滤器(Error Filters):当在上述过程中发生错误时执行,可以进行异常处理、错误日志记录等操作。
zuul的生命周期
自定义Zuul过滤器
Zuul的过滤器可以通过实现ZuulFilter接口来自定义,或者使用预定义的过滤器。通过配置路由规则和相应的过滤器,可以灵活的控制请求的处理流程。
- filterType()方法:返回一个字符串代表过滤器的类型。在这里写“pre”,表示过滤器为pre过滤器。
- filterOrder()方法:返回一个整数表示过滤器的执行顺序。数值越小,优先级越高。
- shouldFilter()方法:返回一个boolean值,表示该过滤器是否需要执行。可以在这里实现一些条件判断,如果满足条件,返回true,否则返回false。
- run()方法:过滤器的具体逻辑实现。在这里可以对响应内容进行修改或添加头部信息等操做
这里是实现了一个pre过滤器,当然我们可以通过ZuulFilter的filterType方法来设置不同的过滤器类型。
@Component
public class LoginFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
HttpSession session = request.getSession();
Cookie[] cookies = request.getCookies();
// 验证Session和Cookie
if (session == null || cookies == null) {
System.out.println("session为空,或者cookie为空");
// context.setSendZuulResponse(false);
// context.setResponseStatusCode(401);
return null;
}else {
System.out.println("可在这里进行权限校验");
}
return null;
}
}
启动实例,访问其中一个client,网关服务控制台输出如下:
},Server stats: [[Server:10.7.84.3:8002; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@2b941bc3
2023-06-21 15:53:54.169 INFO 23680 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: user-consumer.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
可在这里进行权限校验
Zuul网关服务的其他组件
- 当然Zuul服务网关还有以下组件。
- Route:路由,将请求路由到不同的后端服务上。
- Ribbon:负载均衡器,Zuul 默认使用 Ribbon 进行负载均衡。
- Hystrix:容错处理器,可以实现限流和熔断机制。
好了,先记录到这吧。