一在塔、介紹
1.1 功能介紹
Zuul是Netflix開發(fā)的一款提供動(dòng)態(tài)路由胳搞、監(jiān)控、彈性姥闪、安全的網(wǎng)關(guān)服務(wù)始苇,他可以和Eureka,Ribbon,Hystrix等組件配合使用。還可以通過創(chuàng)建過濾器對(duì)校驗(yàn)過濾提供支持筐喳,本節(jié)主要通過一個(gè)實(shí)例完成對(duì)它的服務(wù)轉(zhuǎn)發(fā)和過濾功能的介紹催式。
1.2 項(xiàng)目地址
GitHub地址:
https://github.com/Netflix/zuul
1.3 軟件版本
Spring Boot版本:2.3.3RELEASE
Zuul服務(wù)網(wǎng)關(guān)版本:2.2.4RELEASE
二、環(huán)境搭建
Zuul服務(wù)網(wǎng)關(guān)完成任務(wù)的主要方式是在配置文件配置相關(guān)數(shù)據(jù)避归,下面主要介紹使用配置方法完成服務(wù)轉(zhuǎn)發(fā)及攔截器荣月。
2.1 配置
2.1.1 Eureka注冊(cè)中心配置
2.1.1.1 引入pom文件
創(chuàng)建一個(gè)Spring Boot Web項(xiàng)目,在項(xiàng)目中引入Eureka Server
相關(guān)依賴
<?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文件
主要配置了服務(wù)名梳毙、服務(wù)端口及注冊(cè)中心地址
# 項(xiàng)目端口
server:
port: 9898
# 項(xiàng)目名稱
spring:
application:
name: zuul-eureka-server
# Eureka配置
eureka:
client:
# 本服務(wù)不注冊(cè)到Eureka中
register-with-eureka: false
service-url:
defautZone: http://localhost:9898/eureka
2.1.1.3 配置啟動(dòng)類
在啟動(dòng)類添加@EnableEurekaServer
注解哺窄,使該服務(wù)成為Eureka注冊(cè)中心服務(wù)
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 服務(wù)提供者配置
創(chuàng)建兩個(gè)服務(wù)提供者,除了名稱及部分地址及輸出外顿天,兩個(gè)服務(wù)提供者的內(nèi)容相同堂氯,下面以zuul-provider-01
為例。
2.1.2.1 配置pom文件
提供者主要的功能是輸出一個(gè)Restful風(fēng)格的字符串信息牌废,內(nèi)容為服務(wù)名和當(dāng)前端口咽白,與上一節(jié)完成的功能相同,除了常規(guī)的依賴外鸟缕,需要添加一個(gè)eureka-client
依賴從而使該服務(wù)成為Eureka注冊(cè)中心的客戶端
<?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注冊(cè)中心的地址等信息
# 項(xiàng)目端口
server:
port: 9098
# 項(xiàng)目名稱
spring:
application:
name: zuul-provider-01
# Eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:9898/eureka/
2.1.2.3 配置啟動(dòng)類
啟動(dòng)類添加@EnableEurekaClient
注解使該服務(wù)成為Eureka注冊(cè)中心的客戶端
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 控制層
主要功能是對(duì)外輸出服務(wù)名及端口
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網(wǎng)關(guān)配置
網(wǎng)關(guān)配置為本節(jié)的重點(diǎn)晶框,Zuul主要完成了服務(wù)轉(zhuǎn)發(fā)和攔截兩個(gè)功能,下面分別介紹這兩個(gè)功能如何配置
2.1.3.1 服務(wù)轉(zhuǎn)發(fā)配置
網(wǎng)關(guān)配置主要在yml文件完成懂从,以provider-01為例授段,當(dāng)Zuul接收到以/getPro01
為開頭的url時(shí),Zuul網(wǎng)關(guān)自動(dòng)將該信息轉(zhuǎn)發(fā)到在Eureka中注冊(cè)的番甩、serviceId為zuul-provider-01
的服務(wù)完成接下來的工作侵贵,服務(wù)提供者完成任務(wù)后再發(fā)回到Zuul服務(wù)網(wǎng)關(guān)中,再由網(wǎng)關(guān)發(fā)送到瀏覽器缘薛,整個(gè)過程如下圖所示窍育。
配置內(nèi)容如下:
# 服務(wù)端口
server:
port: 9899
# 服務(wù)名稱
spring:
application:
name: zuul-gateway-service
# 網(wǎng)關(guān)配置
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 攔截器配置
攔截器使用類進(jìn)行配置并使用@Configuration
注解進(jìn)行使用,Zuul網(wǎng)關(guān)共有以下4種攔截方式
- “pre” 預(yù)過濾器 - 在路由分發(fā)一個(gè)請(qǐng)求之前調(diào)用宴胧。
- “post” 后過濾器 - 在路由分發(fā)一個(gè)請(qǐng)求后調(diào)用漱抓。
- “route” 路由過濾器 - 用于路由請(qǐng)求分發(fā)。
- “error” 錯(cuò)誤過濾器 - 在處理請(qǐng)求時(shí)發(fā)生錯(cuò)誤時(shí)調(diào)用
使用時(shí)可根據(jù)功能需要進(jìn)行選擇恕齐,攔截器類需要實(shí)現(xiàn)ZuulFilter
接口乞娄,共4個(gè)函數(shù),其中filterType
函數(shù)返回一個(gè)字符串變量,可填入如下pre, post, erro, route
仪或,分別對(duì)應(yīng)上面幾種攔截方式确镊;本配置選擇'pre'即在分發(fā)之前進(jìn)行攔截
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
ZuulFilter
接口的run方法中配置了攔截內(nèi)容,本例對(duì)accessToken
進(jìn)行了校驗(yàn)溶其,所有通過網(wǎng)關(guān)對(duì)服務(wù)提供者進(jìn)行訪問的請(qǐng)求骚腥,如果accessToken
為空時(shí)攔截器將對(duì)其進(jìn)行攔截并返回access token empty
@Override
public Object run() throws ZuulException {
//獲取上下文
RequestContext ctx = RequestContext.getCurrentContext();
//獲取Request
HttpServletRequest request = ctx.getRequest();
//獲取請(qǐng)求參數(shù)accessToken
String accessToken = request.getParameter("accessToken");
//使用String工具類
if (StringUtils.isBlank(accessToken)) {
ctx.setSendZuulResponse(false); //進(jìn)行攔截
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("accessToken is empty");
} catch (Exception ignored) {
}
return null;
}
2.1.3.3 配置啟動(dòng)類
完成網(wǎng)關(guān)配置后,需要在啟動(dòng)類添加@EnableZuulProxy
注解使該類成功服務(wù)網(wǎng)關(guān)
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);
}
}
三瓶逃、運(yùn)行測(cè)試
分別啟動(dòng)4個(gè)程序束铭,驗(yàn)證啟動(dòng)是否成功
打開http://localhost:9898
,Eureka注冊(cè)中心啟動(dòng)成功
不使用服務(wù)網(wǎng)關(guān)厢绝,直接訪問服務(wù)提供者契沫,以
zuul-provider-02
為例,返回信息無誤下面對(duì)服務(wù)網(wǎng)關(guān)的功能進(jìn)行驗(yàn)證
3.1 攔截測(cè)試
瀏覽器輸入http://localhost:9899/getPro01/getConfig
昔汉,返回accessToken is empty
懈万,攔截成功
3.2 服務(wù)轉(zhuǎn)發(fā)
瀏覽器輸入http://localhost:9899/getPro02/getConfig?accessToken=test12345
(accessToken內(nèi)容沒有做校驗(yàn),只要不為空任何信息都可)靶病,瀏覽器返回服務(wù)提供者02傳入的信息会通,服務(wù)轉(zhuǎn)發(fā)成功。
`
四娄周、下載
4.1 Demo下載
- GitHub項(xiàng)目地址:
https://github.com/diyzhang/42j124-zuuldemo
- 使用Git下載項(xiàng)目的命令:
git clone https://github.com/diyzhang/42j124-zuuldemo.git