400ToJava:124-Zuul服務網關介紹

一、介紹

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服務網關中,再由網關發送到瀏覽器,整個過程如下圖所示。

圖-1

配置內容如下:

# 服務端口
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注冊中心啟動成功

圖-2

不使用服務網關,直接訪問服務提供者,以zuul-provider-02為例,返回信息無誤
圖-3

下面對服務網關的功能進行驗證

3.1 攔截測試

瀏覽器輸入http://localhost:9899/getPro01/getConfig,返回accessToken is empty,攔截成功

圖-4

3.2 服務轉發

瀏覽器輸入http://localhost:9899/getPro02/getConfig?accessToken=test12345(accessToken內容沒有做校驗,只要不為空任何信息都可),瀏覽器返回服務提供者02傳入的信息,服務轉發成功。
`

圖-5

四、下載

4.1 Demo下載

  • 使用Git下載項目的命令:
git clone https://github.com/diyzhang/42j124-zuuldemo.git
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。