書接上回,這個接的有點久(手動滑稽)。。。css
上次說道使用Nginx對coap接入作負載均衡,讓協議服務器能夠橫向擴展,但咱們的設備管理系統在訪問時仍是訪問的咱們服務器的地址,若是如今有其它服務要調用咱們的設備管理系統若是直接使用其ip地址會有服務地址暴露的風險,而且後期若是作鑑權,都很差作,因此這裏咱們引出了spring cloud另一個組件,zuul網關。html
zuul是netfilx開源的一個api gateway服務器,記住是api 服務器,它只能作api請求網關,或者說是http請求的網關。像上面咱們用Nginx作udp路由,使用的是端口監聽,它是作不了的。java
爲啥要用zuul,由於統一入口呀,統一入口能幹啥,那可就多了哦git
爲啥它能幹這麼多事呢?程序員
上面說zuul是一個api服務器,它本質上是一個web servlet服務器,或者說是個filter應用,專幹攔截過濾的勾當((^o^)/~)。web
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中以便過濾請求使用。這就知足了咱們動態增過濾器的需求。
這就有點想aop的請求前,請求後,發生錯誤執行了。
zuul還內置了兩個特殊的過濾器
staticResponseFilter:容許從zull自己生成響應,而不是將請求轉發,網關不是作轉發麼,它本身響應請求是個什麼鬼,看名字靜態?是噻,像那種百年不變的js,css,圖片這種靜態資源徹底能夠由網關本身響應。
surgicalDebugFilter:容許將特定請求路由到分隔的調試集羣和主機上
關於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啓動後,在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
從控制檯日誌咱們能夠看出對請求進行的過濾。
這個就看一下程序員DD大牛寫的,我就不獻醜了,zuul 1.0與2.0從設計結構與流程上都發生了變化,區別仍是蠻大的。
http://blog.didispace.com/api-gateway-Zuul-1-zuul-2-how-to-choose/