個人博客:程序員笑笑生,歡迎瀏覽博客!,搜索博客可添加微信公衆號。前端
上一章 SpringCloud 基礎教程(九)-Hystrix服務監控(下)當中,咱們深刻了解Hystrix的服務監控。實現了分佈式環境下,監控多個服務的信息,本章節將探索微服務的另外一個組件,網關。java
什麼是Zuul,Zuul能夠說是一個大門,全部的來自前端的請求,通過Zuul時,可以實現動態路由轉發,監控、安全的等邊緣服務應用程序。好比能夠做爲統一資源的訪問入口、負載均衡等。爲何須要須要這樣的一個組件呢?Netflix開發這樣的產品是考慮到了如下的緣由:api的多樣性和訪問量大可以致使不少的問題,沒法預警。因此咱們須要這樣的系統組件應付這些狀況。程序員
身份認證和安全-能夠識別訪問資源的每個請求,拒毫不知足的請求spring
洞察和監控,跟蹤有意義的數據並統計,以便生成有意義的生產視圖apache
動態路由,根據須要將請求動態的路由到不一樣的後端集羣,(最主要的功能)json
壓力測試,逐漸增長集羣的流量,評估性能後端
限流,爲每個請求分配容量,並丟棄超過限制的請求api
處理靜態響應,直接在邊緣處構建響應,而不是轉發給內部集羣安全
新建Maven項目,引入Zuul的依賴和Eureka的依賴,咱們轉發請求是須要從Eureka中獲取服務的信息。Zuul的依賴默認集成了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啓動類,添加@EnableZuulProxy註解,@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker三個註解:表示是一個SpringBoot程序,啓動服務發現功能和服務熔斷功能,
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); } }
固然咱們可使用@SpringCloudApplication一個註解,從源碼上能夠看出@SpringCloudApplication包含了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker三個註解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
配置applicaiton.yml,配置端口號,配置鏈接Eureka的url,配置zuul相關配置:
server: port: 9876 eureka: instance: instance-id: gateway1 hostname: eureka7001.com #服務端的實例名稱 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: #配置服註冊在Eureka的服務名稱,指的是服務中spring.application.name的配置 #將/server-provider/開頭的都轉發到服務名爲server-provider的服務上, path: /server-provider/*
第二種:
zuul: ignored-services: "*" routes: server-a: #名稱隨便起 #將/server-provider/開頭的都轉發到服務名爲server-provider的服務上, path: /server-provider/* #配置服註冊在Eureka的服務名稱,指的是服務中spring.application.name的配置 serviceId: server-provider
第三種:
zuul: ignored-services: "*" routes: server-b: #名稱隨便起 #將/server-provider/開頭的都轉發到url爲 http://localhost:5168/ #的服務上, path: /server-provider/* #配置服註冊在Eureka的服務名稱,指的是服務中spring.application.name的配置 url: http://localhost:5168/ #不經過Eureka
接下來,咱們啓動Eureka中心,2個服務提供者: server-provider,啓動Zuul網關服務,查看Eureka監控頁面:
而後咱們經過如下的URL訪問:http://localhost:9876/server-provider/sayHello?name=1 ,能夠看到咱們經過了Zuul網關實現了路由,服務提供方也能返回請求的結果,並實現了負載均衡:
上文咱們實現了簡單的路由轉發,除了路由轉發,在實際的企業應用中,須要結合不一樣的需求實現不一樣的功能,Zuul能夠經過過濾器來實現接口權限驗證、限流、統計等。Zuul定義了4種不一樣的過濾器類型:
咱們能夠理解爲在請求的不一樣時間分別調用:
自定義過濾器須要集成com.netflix.zuul.ZuulFilter類,並實現其抽象的方法達到所須要的目的,這裏咱們簡單的實現經過Token的驗證:
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; /** *驗證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; } /** * 判斷是否要執行 true表示執行 run方法 * * @return */ @Override public boolean shouldFilter() { return true; } /** * 當 shouldFilter() 返回true時候 * 執行run中的具體邏輯、返回值在當前的版本中沒有意義 * * @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爲空,設置返回狀態爲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 { //不然執行請求 logger.info("msg:{}","ok"); return null; } return null; } }
接下來,咱們啓動相應的服務,併發送請求,若是沒有token,則返回以下的信息:
這樣咱們就能實現一個簡單的經過Token的過濾驗證了。
對於啓用/禁用過濾器,咱們不可能去修改過濾器的代碼,咱們能夠經過配置文件配置進行過濾的控制,在applicaiton.yml中咱們能夠這樣配置:
zuul: #過濾器的名稱 TokenFilter: pre : #true表示禁用 disable : true
當Zuul轉發失敗時,能夠經過配置使Ribbon的客戶端進行重試,默認是false
zuul: retryable: true
在請求的轉發過程當中,默認會轉發HTTP的Header信息,有時候咱們不但願這些信息被轉發,好比Cookie,token,咱們能夠經過sensitiveHeaders配置,多項之間用逗號隔開:
zuul: sensitive-headers: Cookie,token
zuul: prefix: /api
本章分享了Zuul組件在微服務架構中擔任的角色,並經過示例的方式實現了經過Token簡單的過濾請求,固然Zuul的功能不知於此,Zuul經歷過各大互聯網公司的檢驗,可以和Spring Cloud生態完美的融合,是微服務不可或缺的一個關鍵節點。
----END----
以就是本期的分享,你還能夠關注公衆號: 程序員笑笑生,關注更多精彩內容!
SpringCloud基礎教程(一)-微服務與SpringCloud
SpringCloud基礎教程(二)-服務發現 Eureka
SpringCloud基礎教程(五)-配置中心熱生效和高可用
SpringCloud 基礎教程(六)-負載均衡Ribbon
SpringCloud 基礎教程(七)-Feign聲明式服務調用
SpringCloud 基礎教程(八)-Hystrix熔斷器(上)
SpringCloud 基礎教程(九)-Hystrix服務監控(下)
更多精彩內容,請期待...
本文由博客一文多發平臺 OpenWrite 發佈!
個人博客地址蘭陵笑笑生,歡迎瀏覽!