一、介紹
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