問:什麼是網關服務?
答:給外部提供單一的訪問接口,並作過濾和攔截處理的服務。java
問:微服務架構中網關服務有什麼做用?
答:咱們微服務架構中項目衆多,若是直接拋給外部,將會很容易引發調用錯誤而且大大增長了維護成本,因此咱們須要提供單一訪問接口,外部請求所有經過統一端口網關,而後在分發到不一樣的服務器。若是熟悉nginx 的同窗想必就知道,其實就是nginx 反向代理的功能。linux
問:那爲何不使用nginx,而是使用zuul
答: nginx 確實能夠實現網關的功能,可是咱們一樣的要維護nginx.conf 文件,若是項目夠多,是很容易出問題的,使用zuul 的話,能夠和eureka 自然的融合,使得管理維護起來更加方便。nginx
下面咱們就來看下怎麼實現zuul 吧。git
咱們建立一個zuul 的模塊,pom.xml 文件中引入zuul 和erueka程序員
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
在啓動類中咱們加入@EnableZuulProxy 註解
將springBootApplication 註解換成@SpringCloudApplication 註解。
EnableZuulProxy 註解表示啓動zuul 網關服務。
SpringCloudApplication 註解,咱們來看下源碼github
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
能夠看到包含的註解主要是SpringBootApplication、EnableDiscoveryClient、EnableCircuitBreaker 而這三個註解,咱們前面都接觸過的,SpringBootApplication就是Springboot項目啓動的專用註解,EnableDiscoveryClient註解是將服務註冊到服務中心,並發現服務的。EnableCircuitBreaker 是實現熔斷處理的註解,因此說SpringCloudApplication 註解是對三個的一層封裝,因此咱們之後構建微服務的時候,使用SpringCloudApplication 註解會更方便。spring
接下來咱們在配置問價中增長以下配置segmentfault
server.port=9007 spring.application.name=zuul eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/ zuul.routes.test-a.path=/a/** zuul.routes.test-a.service-id=ribbon-consumer
server.port和spring.application.name 用來指定項目啓動的端口和項目在註冊中心的名稱,eureka.client.serviceUrl.defaultZone用來指定註冊中心的地址。
zuul.routes.*.path 和zuul.routes.*.service-id 用來指定咱們的目的項目。
好比我這裏配置的ribbon-consumer 項目,將localhost:9007/a/** 轉發到ribbon-consumer 對應的接口上。
# 測試
好了,咱們如今就把網關配置好了。咱們如今啓動一下項目,啓動以下幾個項目進行測試吧就。
其中EurekaServer是註冊中心,ribbon-consumer 是服務消費者,ribbon-consumer 是服提供者,zuul 是網關。咱們啓動好這幾個項目後,咱們輸入一下地址:安全
http://localhost:9007/a/index
能夠看到其實訪問的是服務器
http://localhost:9003/index
上面的能夠看到,咱們主要的配置就是在配置文件中配置好目標地址的路徑。可是這樣的話,和nginx 有什麼區別呢,若是項目足夠多配置起來仍是會出錯的,因此前面說zuul 和eureka 能夠無縫鏈接,因此,這裏zuul 作了一個默認映射,爲全部註冊到註冊中心的服務提供了一個惟一對應的默認映射。怎麼說呢,咱們看一下服務中心的控制檯。
zuul 將eureka 中服務名做爲映射前綴,好比
http://localhost:9007/ribbon-consumer/index
能夠看到,達到了同樣的效果,ribbon-consumer 就是服務名。
前面咱們講了zuul 網關能夠轉發請求,可是它還有一個強大的功能,那就是請求過濾,咱們知道具體項目中咱們的接口會作安全限制,因此在具體的項目中會寫過濾器和攔截器。在微服務項目中,咱們既然提供了統一的網關服務,因此咱們能夠將安全校驗和具體業務剝離出來,將安全校驗放在zuul 網關中來統一處理,這樣減小了冗餘代碼,也方便維護。
那麼怎在zuul 中實現請求過濾呢?
繼承ZuulFilter 類。
咱們建立一個AccessFilter你類來繼承ZuulFilter 。代碼以下:
@Slf4j public class AccessFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext ctx=RequestContext.getCurrentContext(); HttpServletRequest request=ctx.getRequest(); String token=request.getParameter("token"); if(token == null || !token.equals("123456")){ log.info("token is error!"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(500); return "error"; } log.info("token is ok"); return null; } }
直接將書上的解釋拿出來了。主要的方法是run方法,獲取請求中的request 和參數,對參數進行校驗從而過濾。
這裏我就是對token 進行簡單的校驗,也就是說只有檢驗經過了才能訪問目標接口。
昨晚上面這些還不夠,還差一步,在項目zuul 服務啓動的時候,須要將 AccessFilter bean 註冊服務中。因此咱們在啓動類中注入
@Bean public AccessFilter accessFilter(){ return new AccessFilter(); }
好了,咱們來啓動一下項目看看。
能夠看到就能夠起到攔截的做用。
到此爲止,zuul 網關服務搭建好了,並運行一個很是簡單的例子。
代碼上傳到github:
https://github.com/QuellanAn/SpringCloud
後續加油♡
歡迎你們關注我的公衆號 "程序員愛酸奶"
分享各類學習資料,包含java,linux,大數據等。資料包含視頻文檔以及源碼,同時分享本人及投遞的優質技術博文。
若是你們喜歡記得關注和分享喲❤