小白學SpringCloud(五):路由網(wǎng)關(guān)(Zuul)

zuul_logo

在微服務(wù)的架構(gòu)下,各個服務(wù)一般會有各自的網(wǎng)絡(luò)地址,在這樣的情況下外部客戶端的調(diào)用可能會形成雜亂無章的局面。這時候我們就可以使用微服務(wù)網(wǎng)關(guān)Zuul這個組件,我們讓所有的客戶端請求全部請求Zuul,再由Zuul統(tǒng)一的去請求各個服務(wù)。

一、Zuul簡介

Zuul是Netflix開源的微服務(wù)網(wǎng)關(guān),他可以和Eureka,Ribbon,Hystrix等組件配合使用。Zuul組件的核心是一系列的過濾器,這些過濾器可以完成以下功能:

  • 身份認證和安全: 識別每一個資源的驗證要求,并拒絕那些不符的請求
  • 審查與監(jiān)控:
  • 動態(tài)路由:動態(tài)將請求路由到不同后端集群
  • 壓力測試:逐漸增加指向集群的流量,以了解性能
  • 負載分配:為每一種負載類型分配對應(yīng)容量,并棄用超出限定值的請求
  • 靜態(tài)響應(yīng)處理:邊緣位置進行響應(yīng),避免轉(zhuǎn)發(fā)到內(nèi)部集群
  • 多區(qū)域彈性:跨域AWS Region進行請求路由,旨在實現(xiàn)ELB(ElasticLoad Balancing)使用多樣化

Spring Cloud對Zuul進行了整合和增強。目前,Zuul使用的默認是Apache的HTTP Client,也可以使用Rest Client,可以設(shè)置ribbon.restclient.enabled=true.。

二、創(chuàng)建一個api-gateway工程

這里我們使用IntelliJ IDEA進行展示。
1.首先創(chuàng)建一個Zuul項目
使用IDEA創(chuàng)建一個項目

eureka_2

中間有一步我們選擇Zuul選項和SpringBoot版本,如圖
eureka_2

然后下一步就可以創(chuàng)建好了
2.添加@EnableZuulProxy注解
這個注解只需要在springboot工程的啟動application類上就好了

@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class ApiGetwayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGetwayApplication.class, args);
    }

然后在配置文件中添加config的配置,具體可以見小白學SpringCloud(三):統(tǒng)一配置中心(config)。然后就可以使用Zuul工程的路由了,依次運行Eureka、Config、Client客戶端、Zuul。
我們先來隨便訪問一下client端的env接口

zuul_2

然后我們通過zuul服務(wù)的端口+項目名/接口名這種方式來訪問一下這個接口
zuul_3

可以看到,同樣訪問到了結(jié)果。
另外,我們也可以在配置文件中更加細粒度控制路由路徑:

# 表示只要HTTP請求是 /client1開始的,就會轉(zhuǎn)發(fā)到服務(wù)id為client1的服務(wù)上面
zuul:
  routes:
    client1:
      path:/client1/**  // 路由路徑
      serviceId: client1 // 服務(wù)id
    client2:
      path:/client2/**  // 路由路徑
      serviceId: client2 // 服務(wù)id

需要注意的是,使用Zuul默認不會將Cookie的信息帶入服務(wù)端,所以我們需要在配置文件中進行配置,將敏感頭設(shè)置為空即可:

zuul:
  sensitiveHeaders:  

二、服務(wù)過濾

zuul不僅只是路由,并且還能過濾,做一些安全驗證。我們來新建一個Filter并且繼承ZuulFilter

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * @Author: lllx
 * @Description:
 * @Date: Created on 17:54 2018/7/10
 * @Modefied by:
 */
public class MyFilter extends ZuulFilter {
    
    /*返回一個字符串代表過濾器的類型
    pre:路由之前
    routing:路由之時
    post: 路由之后
    error:發(fā)送錯誤調(diào)用
    我們可以通過導(dǎo)入FilterConstants這個常量類中的屬性來返回
    */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    //過濾的順序,Zuul中也自定義了很多過濾器,調(diào)用的順序即通過這個方法返回的大小,越小越靠前。我們可以通過FilterConstants這個常量類中定義好的過濾器-1來返回
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER -1;
    }

    //這里可以寫邏輯判斷,是否要過濾,本文true,永遠過濾。
    @Override
    public boolean shouldFilter() {
        return true;
    }

    //過濾器的具體邏輯??捎煤軓?fù)雜,包括查sql,nosql去判斷該請求到底有沒有權(quán)限訪問。
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //從url參數(shù)獲取如果沒有token這個參數(shù)就不允許請求
        String token = request.getParameter("token");
        if(StringUtils.isEmpty(token)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

我們可以通過這樣的方式去自定義一個個的過濾器。


本文作者: catalinaLi
本文鏈接: http://catalinali.top/2018/startZuul/
版權(quán)聲明: 原創(chuàng)文章,有問題請評論中留言。非商業(yè)轉(zhuǎn)載請注明作者及出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容