SpringCloud 基礎(chǔ)教程(十)-Zuul 服務(wù)網(wǎng)關(guān)

我的博客:程序員笑笑生,歡迎瀏覽博客曾撤!材鹦,搜索博客可添加微信公眾號(hào)蔗喂。

? ?上一章 SpringCloud 基礎(chǔ)教程(九)-Hystrix服務(wù)監(jiān)控(下)當(dāng)中再姑,我們深入了解Hystrix的服務(wù)監(jiān)控胳岂。實(shí)現(xiàn)了分布式環(huán)境下编整,監(jiān)控多個(gè)服務(wù)的信息,本章節(jié)將探索微服務(wù)的另一個(gè)組件乳丰,網(wǎng)關(guān)掌测。

前言

?什么是Zuul,Zuul可以說是一個(gè)大門,所有的來自前端的請(qǐng)求产园,經(jīng)過Zuul時(shí)汞斧,能夠?qū)崿F(xiàn)動(dòng)態(tài)路由轉(zhuǎn)發(fā),監(jiān)控淆两、安全的等邊緣服務(wù)應(yīng)用程序断箫。比如可以作為統(tǒng)一資源的訪問入口、負(fù)載均衡等秋冰。為什么需要需要這樣的一個(gè)組件呢仲义?Netflix開發(fā)這樣的產(chǎn)品是考慮到了以下的原因:api的多樣性和訪問量大能夠?qū)е潞芏嗟膯栴},無法預(yù)警。所以我們需要這樣的系統(tǒng)組件應(yīng)付這些情況埃撵。

一赵颅、Zuul 提供的功能

  • 身份認(rèn)證和安全-可以識(shí)別訪問資源的每一個(gè)請(qǐng)求,拒絕不滿足的請(qǐng)求

  • 洞察和監(jiān)控暂刘,跟蹤有意義的數(shù)據(jù)并統(tǒng)計(jì)饺谬,以便生成有意義的生產(chǎn)視圖

  • 動(dòng)態(tài)路由,根據(jù)需要將請(qǐng)求動(dòng)態(tài)的路由到不同的后端集群谣拣,(最主要的功能)

  • 壓力測(cè)試募寨,逐漸增加集群的流量,評(píng)估性能

  • 限流森缠,為每一個(gè)請(qǐng)求分配容量拔鹰,并丟棄超過限制的請(qǐng)求

  • 處理靜態(tài)響應(yīng),直接在邊緣處構(gòu)建響應(yīng)贵涵,而不是轉(zhuǎn)發(fā)給內(nèi)部集群

二列肢、Zuul 快速入門

?新建Maven項(xiàng)目,引入Zuul的依賴和Eureka的依賴宾茂,我們轉(zhuǎn)發(fā)請(qǐng)求是需要從Eureka中獲取服務(wù)的信息瓷马。Zuul的依賴默認(rèn)集成了hystrix和ribbon

<dependency>
   <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

?新建GateWayApplication啟動(dòng)類,添加@EnableZuulProxy注解跨晴,@SpringBootApplication欧聘、@EnableDiscoveryClient、@EnableCircuitBreaker三個(gè)注解:表示是一個(gè)SpringBoot程序坟奥,啟動(dòng)服務(wù)發(fā)現(xiàn)功能和服務(wù)熔斷功能树瞭,

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringCloudApplication
@EnableZuulProxy
public class GateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class);
    }
}

?當(dāng)然我們可以使用@SpringCloudApplication一個(gè)注解,從源碼上可以看出@SpringCloudApplication包含了@SpringBootApplication爱谁、@EnableDiscoveryClient晒喷、@EnableCircuitBreaker三個(gè)注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {
}

?配置applicaiton.yml,配置端口號(hào),配置連接Eureka的url访敌,配置zuul相關(guān)配置:

server:
  port: 9876
  
eureka:
  instance:
    instance-id: gateway1
    hostname: eureka7001.com  #服務(wù)端的實(shí)例名稱
  client:
    service-url:
       defaultZone: http://eureka7001.com:7001/eureka/
zuul:
  ignored-services: "*"
  routes:
     server-provider:
        path:   /server-provider/*

?在routes下有以下幾種的配置

第一種:

zuul:
  ignored-services: "*"
  routes:
     server-provider:   #配置服注冊(cè)在Eureka的服務(wù)名稱凉敲,指的是服務(wù)中spring.application.name的配置
         #將/server-provider/開頭的都轉(zhuǎn)發(fā)到服務(wù)名為server-provider的服務(wù)上,
      path:   /server-provider/*  

第二種:

zuul:
  ignored-services: "*"
  routes:
     server-a:   #名稱隨便起
         #將/server-provider/開頭的都轉(zhuǎn)發(fā)到服務(wù)名為server-provider的服務(wù)上寺旺,
      path:   /server-provider/*  
       #配置服注冊(cè)在Eureka的服務(wù)名稱爷抓,指的是服務(wù)中spring.application.name的配置
      serviceId:  server-provider  

第三種:

zuul:
  ignored-services: "*"
  routes:
     server-b:   #名稱隨便起
         #將/server-provider/開頭的都轉(zhuǎn)發(fā)到url為 http://localhost:5168/  #的服務(wù)上,
      path:   /server-provider/*  
       #配置服注冊(cè)在Eureka的服務(wù)名稱阻塑,指的是服務(wù)中spring.application.name的配置
      url:  http://localhost:5168/  #不通過Eureka

?接下來蓝撇,我們啟動(dòng)Eureka中心,2個(gè)服務(wù)提供者: server-provider陈莽,啟動(dòng)Zuul網(wǎng)關(guān)服務(wù)渤昌,查看Eureka監(jiān)控頁面:

file

然后我們通過以下的URL訪問:http://localhost:9876/server-provider/sayHello?name=1 虽抄,可以看到我們通過了Zuul網(wǎng)關(guān)實(shí)現(xiàn)了路由,服務(wù)提供方也能返回請(qǐng)求的結(jié)果独柑,并實(shí)現(xiàn)了負(fù)載均衡:

file

三迈窟、Zuul過濾器

3.1 過濾器簡介

?上文我們實(shí)現(xiàn)了簡單的路由轉(zhuǎn)發(fā),除了路由轉(zhuǎn)發(fā)忌栅,在實(shí)際的企業(yè)應(yīng)用中车酣,需要結(jié)合不同的需求實(shí)現(xiàn)不同的功能,Zuul可以通過過濾器來實(shí)現(xiàn)接口權(quán)限驗(yàn)證索绪、限流湖员、統(tǒng)計(jì)等。Zuul定義了4種不同的過濾器類型:

file

我們可以理解為在請(qǐng)求的不同時(shí)間分別調(diào)用:

  • pre:這種過濾器在請(qǐng)求被轉(zhuǎn)發(fā)之前調(diào)用瑞驱,一般用來實(shí)現(xiàn)身份驗(yàn)證等
  • routing:這種路由是用來路由到不同的后端服務(wù)的破衔,底層可以使用httpclient或者ribbon請(qǐng)求微服務(wù)
  • post:當(dāng)請(qǐng)求轉(zhuǎn)發(fā)到微服務(wù)以后,會(huì)調(diào)用當(dāng)前類型的過濾器钱烟。通常用來為響應(yīng)天啊及標(biāo)椎的HTTP Header、收集統(tǒng)計(jì)信息嫡丙,等
  • error:當(dāng)發(fā)生錯(cuò)誤是執(zhí)行的過濾器

3.2 自定義過濾器實(shí)現(xiàn)Token驗(yàn)證

?自定義過濾器需要集成com.netflix.zuul.ZuulFilter類拴袭,并實(shí)現(xiàn)其抽象的方法達(dá)到所需要的目的,這里我們簡單的實(shí)現(xiàn)通過Token的驗(yàn)證:

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *驗(yàn)證token
 */
@Component
public class TokenFilter extends ZuulFilter {
    private Logger logger=LoggerFactory.getLogger(TokenFilter.class);
    /**
     * 返回過濾器類型   "pre" / "route" / "post"  / “ error”
     *
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }
    /**
     * 過濾器的順序曙博,不同的過濾器順序可以相同
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 判斷是否要執(zhí)行  true表示執(zhí)行 run方法
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 當(dāng) shouldFilter() 返回true時(shí)候
     * 執(zhí)行run中的具體邏輯拥刻、返回值在當(dāng)前的版本中沒有意義
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
         RequestContext context = RequestContext.getCurrentContext();
         HttpServletRequest request = context.getRequest();
         HttpServletResponse response = context.getResponse();
        //獲取header中的token
        String token = request.getHeader("token");
        JSONObject jsonObject=new JSONObject();
      //如果token為空,設(shè)置返回狀態(tài)為401父泳,返回json的信息
        if (StringUtils.isEmpty(token)) {
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            jsonObject.put("code",401);
            jsonObject.put("msg","UNAUTHORIZED");
            context.setResponseBody(jsonObject.toJSONString());
            logger.info("msg:{}",jsonObject);
        } else {
            //否則執(zhí)行請(qǐng)求
            logger.info("msg:{}","ok");
            return null;
        }
        return null;
    }
}

  • filterType:返回過濾器類型 "pre" / "route" / "post" / “ error”
  • filterOrder:過濾器的順序
  • shouldFilter:為true時(shí)候般哼,執(zhí)行run方法
  • run:具體的邏輯,在方法中我們可以獲取到RequestContext對(duì)象惠窄,通過該對(duì)象獲取請(qǐng)求頭的信息蒸眠,并設(shè)置返回信息

?接下來,我們啟動(dòng)相應(yīng)的服務(wù)杆融,并發(fā)送請(qǐng)求楞卡,如果沒有token,則返回如下的信息:

file

這樣我們就能實(shí)現(xiàn)一個(gè)簡單的通過Token的過濾驗(yàn)證了脾歇。

?對(duì)于啟用/禁用過濾器蒋腮,我們不可能去修改過濾器的代碼,我們可以通過配置文件配置進(jìn)行過濾的控制藕各,在applicaiton.yml中我們可以這樣配置:

zuul:
   #過濾器的名稱
  TokenFilter:
     pre :
     #true表示禁用
       disable : true

3.3 請(qǐng)求重試

?當(dāng)Zuul轉(zhuǎn)發(fā)失敗時(shí)池摧,可以通過配置使Ribbon的客戶端進(jìn)行重試,默認(rèn)是false

zuul:
  retryable: true

3.4 敏感Header的過濾

?在請(qǐng)求的轉(zhuǎn)發(fā)過程中激况,默認(rèn)會(huì)轉(zhuǎn)發(fā)HTTP的Header信息作彤,有時(shí)候我們不希望這些信息被轉(zhuǎn)發(fā)膘魄,比如Cookie,token宦棺,我們可以通過sensitiveHeaders配置瓣距,多項(xiàng)之間用逗號(hào)隔開:

zuul:
  sensitive-headers: Cookie,token

3.5 設(shè)置統(tǒng)一的前綴

zuul:
  prefix: /api

四、總結(jié)

?本章分享了Zuul組件在微服務(wù)架構(gòu)中擔(dān)任的角色代咸,并通過示例的方式實(shí)現(xiàn)了通過Token簡單的過濾請(qǐng)求蹈丸,當(dāng)然Zuul的功能不知于此,Zuul經(jīng)歷過各大互聯(lián)網(wǎng)公司的檢驗(yàn)呐芥,能夠和Spring Cloud生態(tài)完美的融合逻杖,是微服務(wù)不可或缺的一個(gè)關(guān)鍵節(jié)點(diǎn)。

                                                                           ----END----

以就是本期的分享思瘟,你還可以關(guān)注公眾號(hào): 程序員笑笑生荸百,關(guān)注更多精彩內(nèi)容!

file
file

SpringCloud基礎(chǔ)教程(一)-微服務(wù)與SpringCloud

SpringCloud基礎(chǔ)教程(二)-服務(wù)發(fā)現(xiàn) Eureka

SpringCloud基礎(chǔ)教程(三)-Eureka進(jìn)階

SpringCloud 基礎(chǔ)教程(四)-配置中心入門

SpringCloud基礎(chǔ)教程(五)-配置中心熱生效和高可用

SpringCloud 基礎(chǔ)教程(六)-負(fù)載均衡Ribbon

SpringCloud 基礎(chǔ)教程(七)-Feign聲明式服務(wù)調(diào)用

SpringCloud 基礎(chǔ)教程(八)-Hystrix熔斷器(上)

SpringCloud 基礎(chǔ)教程(九)-Hystrix服務(wù)監(jiān)控(下)

SpringCloud 基礎(chǔ)教程(十)-Zull服務(wù)網(wǎng)關(guān)

更多精彩內(nèi)容滨攻,請(qǐng)期待...

本文由博客一文多發(fā)平臺(tái) OpenWrite 發(fā)布够话!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市光绕,隨后出現(xiàn)的幾起案子女嘲,更是在濱河造成了極大的恐慌,老刑警劉巖诞帐,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欣尼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡停蕉,警方通過查閱死者的電腦和手機(jī)愕鼓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慧起,“玉大人菇晃,你說我怎么就攤上這事◎炯罚” “怎么了谋旦?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長屈尼。 經(jīng)常有香客問我册着,道長,這世上最難降的妖魔是什么脾歧? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任甲捏,我火速辦了婚禮,結(jié)果婚禮上鞭执,老公的妹妹穿的比我還像新娘司顿。我一直安慰自己芒粹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布大溜。 她就那樣靜靜地躺著化漆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钦奋。 梳的紋絲不亂的頭發(fā)上座云,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音付材,去河邊找鬼朦拖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛厌衔,可吹牛的內(nèi)容都是我干的璧帝。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼富寿,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼睬隶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起页徐,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤理疙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后泞坦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砖顷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年贰锁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滤蝠。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡豌熄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出物咳,到底是詐尸還是另有隱情锣险,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布览闰,位于F島的核電站芯肤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏压鉴。R本人自食惡果不足惜崖咨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望油吭。 院中可真熱鬧击蹲,春花似錦署拟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至类咧,卻和暖如春馒铃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轮听。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工骗露, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人血巍。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓萧锉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親述寡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子柿隙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容