400ToJava:124-Zuul服務(wù)網(wǎng)關(guān)介紹

一在塔、介紹

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è)過程如下圖所示窍育。

圖-1

配置內(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)成功

圖-2

不使用服務(wù)網(wǎng)關(guān)厢绝,直接訪問服務(wù)提供者契沫,以zuul-provider-02為例,返回信息無誤
圖-3

下面對(duì)服務(wù)網(wǎng)關(guān)的功能進(jìn)行驗(yàn)證

3.1 攔截測(cè)試

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

圖-4

3.2 服務(wù)轉(zhuǎn)發(fā)

瀏覽器輸入http://localhost:9899/getPro02/getConfig?accessToken=test12345(accessToken內(nèi)容沒有做校驗(yàn),只要不為空任何信息都可)靶病,瀏覽器返回服務(wù)提供者02傳入的信息会通,服務(wù)轉(zhuǎn)發(fā)成功。
`

圖-5

四娄周、下載

4.1 Demo下載

  • 使用Git下載項(xiàng)目的命令:
git clone https://github.com/diyzhang/42j124-zuuldemo.git
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末涕侈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子煤辨,更是在濱河造成了極大的恐慌裳涛,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件众辨,死亡現(xiàn)場(chǎng)離奇詭異端三,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鹃彻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門郊闯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蛛株,你說我怎么就攤上這事虚婿。” “怎么了泳挥?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)至朗。 經(jīng)常有香客問我屉符,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任矗钟,我火速辦了婚禮唆香,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吨艇。我一直安慰自己躬它,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布东涡。 她就那樣靜靜地躺著冯吓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疮跑。 梳的紋絲不亂的頭發(fā)上组贺,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音祖娘,去河邊找鬼失尖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛渐苏,可吹牛的內(nèi)容都是我干的掀潮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼琼富,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼仪吧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起公黑,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤邑商,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后凡蚜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體人断,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年朝蜘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恶迈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谱醇,死狀恐怖暇仲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情副渴,我是刑警寧澤奈附,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站煮剧,受9級(jí)特大地震影響斥滤,放射性物質(zhì)發(fā)生泄漏将鸵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一佑颇、第九天 我趴在偏房一處隱蔽的房頂上張望顶掉。 院中可真熱鬧,春花似錦挑胸、人聲如沸痒筒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽簿透。三九已至,卻和暖如春闷沥,著一層夾襖步出監(jiān)牢的瞬間萎战,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工舆逃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚂维,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓路狮,卻偏偏與公主長(zhǎng)得像虫啥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奄妨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354