小白學SpringCloud(五):路由網關(Zuul)

zuul_logo

在微服務的架構下,各個服務一般會有各自的網絡地址,在這樣的情況下外部客戶端的調用可能會形成雜亂無章的局面。這時候我們就可以使用微服務網關Zuul這個組件,我們讓所有的客戶端請求全部請求Zuul,再由Zuul統一的去請求各個服務。

一、Zuul簡介

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

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

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

二、創建一個api-gateway工程

這裏我們使用IntelliJ IDEA進行展示。
1.首先創建一個Zuul項目
使用IDEA創建一個項目
eureka_2
中間有一步我們選擇Zuul選項和SpringBoot版本,如圖
eureka_2
然後下一步就可以創建好了
2.添加@EnableZuulProxy註解
這個註解只需要在springboot工程的啓動application類上就好了

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

然後在配置文件中添加config的配置,具體可以見小白學SpringCloud(三):統一配置中心(config)。然後就可以使用Zuul工程的路由了,依次運行Eureka、Config、Client客戶端、Zuul。
我們先來隨便訪問一下client端的env接口
zuul_2
然後我們通過zuul服務的端口+項目名/接口名這種方式來訪問一下這個接口
zuul_3
可以看到,同樣訪問到了結果。
另外,我們也可以在配置文件中更加細粒度控制路由路徑:

# 表示只要HTTP請求是 /client1開始的,就會轉發到服務id爲client1的服務上面
zuul:
  routes:
    client1:
      path:/client1/**  // 路由路徑
      serviceId: client1 // 服務id
    client2:
      path:/client2/**  // 路由路徑
      serviceId: client2 // 服務id

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

zuul:
  sensitiveHeaders:  

二、服務過濾

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:發送錯誤調用
    我們可以通過導入FilterConstants這個常量類中的屬性來返回
    */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

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

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

    //過濾器的具體邏輯。可用很複雜,包括查sql,nosql去判斷該請求到底有沒有權限訪問。
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //從url參數獲取如果沒有token這個參數就不允許請求
        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/
版權聲明: 原創文章,有問題請評論中留言。非商業轉載請註明作者及出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章