一、介绍
1.1 功能介绍
Zuul是Netflix开发的一款提供动态路由、监控、弹性、安全的网关服务,他可以和Eureka,Ribbon,Hystrix等组件配合使用。还可以通过创建过滤器对校验过滤提供支持,本节主要通过一个实例完成对它的服务转发和过滤功能的介绍。
1.2 项目地址
GitHub地址:
https://github.com/Netflix/zuul
1.3 软件版本
Spring Boot版本:2.3.3RELEASE
Zuul服务网关版本:2.2.4RELEASE
二、环境搭建
Zuul服务网关完成任务的主要方式是在配置文件配置相关数据,下面主要介绍使用配置方法完成服务转发及拦截器。
2.1 配置
2.1.1 Eureka注册中心配置
2.1.1.1 引入pom文件
创建一个Spring Boot Web项目,在项目中引入Eureka Server
相关依赖
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.toj</groupId>
<artifactId>zuul-eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zuul-eureka-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1.1.2 配置yml文件
主要配置了服务名、服务端口及注册中心地址
# 项目端口
server:
port: 9898
# 项目名称
spring:
application:
name: zuul-eureka-server
# Eureka配置
eureka:
client:
# 本服务不注册到Eureka中
register-with-eureka: false
service-url:
defautZone: http://localhost:9898/eureka
2.1.1.3 配置启动类
在启动类添加@EnableEurekaServer
注解,使该服务成为Eureka注册中心服务
package cn.toj.zuuleurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class ZuulEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulEurekaServerApplication.class, args);
}
}
2.1.2 服务提供者配置
创建两个服务提供者,除了名称及部分地址及输出外,两个服务提供者的内容相同,下面以zuul-provider-01
为例。
2.1.2.1 配置pom文件
提供者主要的功能是输出一个Restful风格的字符串信息,内容为服务名和当前端口,与上一节完成的功能相同,除了常规的依赖外,需要添加一个eureka-client
依赖从而使该服务成为Eureka注册中心的客户端
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.toj</groupId>
<artifactId>zuul-provider-01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zuul-provider-01</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1.2.2 配置yml文件
yml文件主要配置了Eureka注册中心的地址等信息
# 项目端口
server:
port: 9098
# 项目名称
spring:
application:
name: zuul-provider-01
# Eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:9898/eureka/
2.1.2.3 配置启动类
启动类添加@EnableEurekaClient
注解使该服务成为Eureka注册中心的客户端
package cn.toj.zuulprovider01;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ZuulProvider01Application {
public static void main(String[] args) {
SpringApplication.run(ZuulProvider01Application.class, args);
}
}
2.1.2.4 控制层
主要功能是对外输出服务名及端口
package cn.toj.zuulprovider01.controller;
import cn.toj.zuulprovider01.dto.ResponseResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Carlos
* @description
* @Date 2020/8/24
*/
@RestController
public class ApolloTestController {
@Value("${server.port}")
private String port;
@GetMapping("/getConfig")
public ResponseResult<String> getConfig() {
return new ResponseResult<>(Integer.valueOf(HttpStatus.OK.value()), HttpStatus.OK.toString(), "Hello, I'm producer-01, I'm in port " + port + ".");
}
}
2.1.3 Zuul网关配置
网关配置为本节的重点,Zuul主要完成了服务转发和拦截两个功能,下面分别介绍这两个功能如何配置
2.1.3.1 服务转发配置
网关配置主要在yml文件完成,以provider-01为例,当Zuul接收到以/getPro01
为开头的url时,Zuul网关自动将该信息转发到在Eureka中注册的、serviceId为zuul-provider-01
的服务完成接下来的工作,服务提供者完成任务后再发回到Zuul服务网关中,再由网关发送到浏览器,整个过程如下图所示。
配置内容如下:
# 服务端口
server:
port: 9899
# 服务名称
spring:
application:
name: zuul-gateway-service
# 网关配置
zuul:
routes:
provider-01:
path: /getPro01/**
serviceId: zuul-provider-01
provider-02:
path: /getPro02/**
serviceId: zuul-provider-02
eureka:
client:
service-url:
defaultZone: http://localhost:9898/eureka/
2.1.3.2 拦截器配置
拦截器使用类进行配置并使用@Configuration
注解进行使用,Zuul网关共有以下4种拦截方式
- “pre” 预过滤器 - 在路由分发一个请求之前调用。
- “post” 后过滤器 - 在路由分发一个请求后调用。
- “route” 路由过滤器 - 用于路由请求分发。
- “error” 错误过滤器 - 在处理请求时发生错误时调用
使用时可根据功能需要进行选择,拦截器类需要实现ZuulFilter
接口,共4个函数,其中filterType
函数返回一个字符串变量,可填入如下pre, post, erro, route
,分别对应上面几种拦截方式;本配置选择'pre'即在分发之前进行拦截
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
ZuulFilter
接口的run方法中配置了拦截内容,本例对accessToken
进行了校验,所有通过网关对服务提供者进行访问的请求,如果accessToken
为空时拦截器将对其进行拦截并返回access token empty
@Override
public Object run() throws ZuulException {
//获取上下文
RequestContext ctx = RequestContext.getCurrentContext();
//获取Request
HttpServletRequest request = ctx.getRequest();
//获取请求参数accessToken
String accessToken = request.getParameter("accessToken");
//使用String工具类
if (StringUtils.isBlank(accessToken)) {
ctx.setSendZuulResponse(false); //进行拦截
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("accessToken is empty");
} catch (Exception ignored) {
}
return null;
}
2.1.3.3 配置启动类
完成网关配置后,需要在启动类添加@EnableZuulProxy
注解使该类成功服务网关
package cn.toj.zuulgatewayservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class ZuulGatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayServiceApplication.class, args);
}
}
三、运行测试
分别启动4个程序,验证启动是否成功
打开http://localhost:9898
,Eureka注册中心启动成功
不使用服务网关,直接访问服务提供者,以
zuul-provider-02
为例,返回信息无误下面对服务网关的功能进行验证
3.1 拦截测试
浏览器输入http://localhost:9899/getPro01/getConfig
,返回accessToken is empty
,拦截成功
3.2 服务转发
浏览器输入http://localhost:9899/getPro02/getConfig?accessToken=test12345
(accessToken内容没有做校验,只要不为空任何信息都可),浏览器返回服务提供者02传入的信息,服务转发成功。
`
四、下载
4.1 Demo下载
- GitHub项目地址:
https://github.com/diyzhang/42j124-zuuldemo
- 使用Git下载项目的命令:
git clone https://github.com/diyzhang/42j124-zuuldemo.git