分佈式項目(九)zuul 網關

書接上回,這個接的有點久(手動滑稽)。。。css

上次說道使用Nginx對coap接入作負載均衡,讓協議服務器能夠橫向擴展,但咱們的設備管理系統在訪問時仍是訪問的咱們服務器的地址,若是如今有其它服務要調用咱們的設備管理系統若是直接使用其ip地址會有服務地址暴露的風險,而且後期若是作鑑權,都很差作,因此這裏咱們引出了spring cloud另一個組件,zuul網關。html

Zuul是什麼

zuul是netfilx開源的一個api gateway服務器,記住是api 服務器,它只能作api請求網關,或者說是http請求的網關。像上面咱們用Nginx作udp路由,使用的是端口監聽,它是作不了的。java

爲啥要用zuul 它能幹啥

爲啥要用zuul,由於統一入口呀,統一入口能幹啥,那可就多了哦git

  • 審查與監控
  • 動態路由,負載均衡
  • 靜態響應處理
  • 驗證與安全保障

爲啥它能幹這麼多事呢?程序員

上面說zuul是一個api服務器,它本質上是一個web servlet服務器,或者說是個filter應用,專幹攔截過濾的勾當((^o^)/~)。web

zuul核心原理

zuul的工做流程是一系列的filters,和servlet的filter,spring中的aop是同樣同樣兒的。spring

一個http請求要走的路api

http請求->zuul servlet->zuulFilter Runner -> filter1->filter2->.... ->業務服務器-> filter2->filter1->http response緩存

這有點向什麼,Status2的攔截器,也是請求的時候一個關卡一個關卡的過去,回來的時候在從後面的關卡一個一個的回來。安全

知道工做流程,忽然發現一個問題,filter之間是如何傳遞數據的,通常這種問題就兩種解決方案,一是我本身走哪兒帶哪兒,這個好理解,就想咱們帶錢同樣,就揣我兜裏,想用的時候就用,二是放在一個地方我用的時候在去拿,這就好比錢太多了拿不動,咋辦,放銀行,用的時候我再去取。

zuul採用的是第二種方式,filter以前經過一個requestContext的靜態類對進行數據的傳遞,那我把數據放進去了我取得時候咋知道是個人呢,錢存銀行,銀行會給你發張卡,你憑卡取錢,requestContext可沒有卡,但它有另外一個東西,ThreadLocal線程數據緩存器,這數據是A線程存的,那只有你A線程才能取出來,其它線程只能瞅着,錯,連瞅都瞅不了。

剛纔咱們說網關是一個服務的入口,或者說是一個服務集羣的入口,它的核心是filter,但咱們又時候須要加一些新的filter,來知足咱們新的需求,可是咱們又不能把網關給停的,網關停了不整個服務就乾瞪眼了麼,因此咱們須要它能動態地加載filter。

zuul的過濾器是由groovy寫成的,這些過濾器被放在了zull server上特定的目錄下面,zuul會按期輪訓這些目錄,修改過的過濾器會動態地加載到zuul server中以便過濾請求使用。這就知足了咱們動態增過濾器的需求。

zuul過濾器類型

  • zuul定義了四種過濾器類型,這些過濾器類型對應請求的處於什麼週期
  • pre:請求路由之間調用,能夠作權限檢測
  • routing:這種過濾器將請求,這種過濾器用於構建發送到微服務的請求,並使用Apache httpClient或ribbon請求微服務
  • post:這種過濾器在路由到微服務之後執行,能夠用來添加標準的http header,收集統計信息和指標,將響應從微服務發送給客戶端
  • error:在其它階段發生錯誤是執行

這就有點想aop的請求前,請求後,發生錯誤執行了。

zuul還內置了兩個特殊的過濾器

staticResponseFilter:容許從zull自己生成響應,而不是將請求轉發,網關不是作轉發麼,它本身響應請求是個什麼鬼,看名字靜態?是噻,像那種百年不變的js,css,圖片這種靜態資源徹底能夠由網關本身響應。

surgicalDebugFilter:容許將特定請求路由到分隔的調試集羣和主機上

關於zuul就簡單介紹一下,下面開始編寫代碼。

建立protocol-zuul

maven配置

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
	<version>2.1.1.RELEASE</version>
</dependency>

<dependency>
	<groupId>cn.le</groupId>
	<artifactId>consul-discovery-client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

#application配置

spring.application.name=protocol-zuul
server.port=8888

#健康檢查路徑
spring.cloud.consul.discovery.health-check-path=/actuator/health

#eureka.client.service-url.defaultZone=http://127.0.0.1:1111/eureka/

spring.cloud.consul.discovery.prefer-ip-address=true
spring.cloud.consul.discovery.instance-id=${spring.application.name}:${server.port}
spring.cloud.consul.discovery.hostname=${spring.application.name}
spring.cloud.consul.discovery.service-name=${spring.application.name}

#配置路由到此服務器
zuul.routes.api-a.service-id=iot-manage
#配置路由規則
zuul.routes.api-a.path=/manage/**
zuul.routes.api-a.stripPrefix=false

zuul關於路由映射的方式兩種,一種是使用ip映射,一種是如今使用的這種zuul.routes.api-a.service-id的方法,ip映射的方式能夠在獨立使用zuul的時候使用,咱們這裏使用了註冊中心,因此使用id名稱映射的方式,這種方式對動態擴容,服務發現、註冊友好。

而ip映射,電腦的IP地址有時候是會變更的,一旦變更,懂了賽。

啓動zuul服務

zuul啓動後,在consul的管理頁面就能夠看到zuul的服務了。

前面咱們直接訪問一下http://127.0.0.1:8081/manage/swagger-ui.html 能夠正常打開設備管理系統的swagger的界面,可是如今咱們有的服務網關,須要從服務網關去訪問, http://127.0.0.1:8888/manage/swagger-ui.html 8888是zuul服務的端口,利用訪問zuul的方式去訪問設備管理系統看看能不能成功打開swagger。

同樣能正常打開,這就表示zuul成功了。

自定義過濾器

剛纔咱們只用利用zuul去訪問manager系統,可是沒作任何處理,若是咱們須要在訪問以前對請求作處理,好比驗證是否登陸。

建立AuthFilter類,並繼承ZuulFilter,做用是聲明AuthFilter是一個ZuulFilter,而且可讓ZuulFilter Runner調用。

package cn.le.pre;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

[@Component](https://my.oschina.net/u/3907912)
/**
 * 自定義過濾器,繼承zuulFilter便可
 */
public class AuthFilter extends ZuulFilter {

    //pre類型,請求路由以前調用
    [@Override](https://my.oschina.net/u/1162528)
    public String filterType() {
        return "pre";
    }
    //過濾器的執行順序,數字越小表示越先執行
    [@Override](https://my.oschina.net/u/1162528)
    public int filterOrder() {
        return 0;
    }
    //判斷此過濾器是否執行,true執行,false不執行
    [@Override](https://my.oschina.net/u/1162528)
    public boolean shouldFilter() {
        return true;
    }
    //過濾器執行邏輯
    [@Override](https://my.oschina.net/u/1162528)
    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        System.out.println("AuthFilter----"+request);
        return null;
    }
}

這裏只打印了請求信息,並無寫關於登陸的邏輯,由於登陸是一個綜合組件配套的邏輯,這裏篇幅有限就不實現了。

從新訪問一下http://192.168.0.105:8888/manage/swagger-ui.html

從控制檯日誌咱們能夠看出對請求進行的過濾。

zuul 1.0與zuul 2.0對比

這個就看一下程序員DD大牛寫的,我就不獻醜了,zuul 1.0與2.0從設計結構與流程上都發生了變化,區別仍是蠻大的。

http://blog.didispace.com/api-gateway-Zuul-1-zuul-2-how-to-choose/

結束語

https://gitee.com/distant/cloud-work.git

https://gitee.com/distant/iot-pt.git

相關文章
相關標籤/搜索