Zuul閘道器和基本應用場景
構建微服務時,常見的問題是為系統的客戶端應用程式提供唯一的閘道器。
事實上,您的服務被拆分為小型微服務應用程式,這些應用程式應該對使用者不可見,否則可能會導致大量的開發/維護工作。還有一些情況,整個生態系統網路流量可能會通過一個可能影響群集效能的點。
為了解決這個問題,Netflix(微服務的一個主要採用者)建立並開源了它的Zuul,Zuul是Netflix的基於JVM的路由器和伺服器端負載均衡器。後來Spring在Pivotal下已經在其Spring Cloud中對其進行了調整,使我們能夠通過簡單的步驟輕鬆有效地使用zuul。
Zuul是一種邊緣服務,它支援對多個服務請求的代理。它為您的生態系統提供統一的“前門”,允許任何瀏覽器,移動應用程式或其他使用者介面使用來自多個主機的服務。您可以將Zuul與其他Netflix堆疊元件(如Hystrix)整合以實現容錯,使用Eureka進行服務發現,或者使用它來管理整個系統中的路由規則,過濾器和負載平衡。
最重要的是,Spring框架通過Spring boot/cloud很好地適應了所有這些元件。
路由器和過濾器
路由是微服務架構不可或缺的一部分。例如,/
可以對映到您的Web應用程式,/api/users
對映到使用者服務並/api/shop
對映到商店服務。
Netflix使用Zuul進行以下操作:
-
認證
-
洞察
-
壓力測試
-
金絲雀測試
-
動態路由
-
服務遷移
-
負載脫落
-
安全
-
靜態響應處理
-
主動/主動流量管理
Zuul的規則引擎允許規則和過濾器基本上以任何JVM語言編寫,內建支援Java和Groovy。
Zuul元件
Zuul主要有四種型別的過濾器,使我們能夠在任何特定事務的請求處理的不同時間線中攔截流量。我們可以為特定的url模式新增任意數量的過濾器。
-
前置過濾器 - 在路由請求之前呼叫。
-
後置過濾器 - 在路由請求後呼叫。
-
路由過濾器 - 用於路由請求。
-
錯誤過濾器 - 在處理請求時發生錯誤時呼叫。
使用不同的過濾器在Zuul內部請求處理流程
過濾器關鍵概念
關鍵詞 | 備註 |
---|---|
型別Type | 定義在路由過程中,過濾器被應用的階段 |
執行順序Execution Order | 在同一個Type中,定義過濾器執行的順序 |
條件Criteria | 過濾器被執行必須滿足的條件 |
動作Action | 如果條件滿足,過濾器中將被執行的動作 |
標準過濾器型別
PRE
在請求被路由到源伺服器前要執行的過濾器
適用業務場景:
-
認證
-
選路由
-
請求日誌
ROUTING
處理將請求傳送到源伺服器的過濾器
POST
在響應從源伺服器返回時要被執行的過濾器
-
對響應增加HTTP 頭
-
收集統計和度量
-
將響應以流的方式傳送回客戶端
ERROR
上述階段中出現錯誤要執行的過濾器
過濾器樣例
public class PreFilter extends ZuulFilter {
// 過濾器型別
netflix zuul例項概述
現在讓我們通過使用Zuul建立一個簡單而有意義的生態系統來嘗試一下。我們將建立下面的元件來演示整個事物:
-
學生微服務 - 基於spring boot啟動的微服務,它只是暴露單個URL以啟用一些搜尋功能。為簡單起見,我們將返回硬編碼值,但在現實世界中,我們可以讓此服務連線資料庫以獲取資料。
-
Zuul閘道器服務
它基於spring boot啟動,它將基本上攔截學生服務的所有流量並應用一系列請求過濾器然後路由到底層服務,並在響應服務時再次,它將應用一些響應過濾。由於它是一個閘道器,我們可以使用過濾器有效地採取許多有趣和有用的操作。
閘道器服務的一些共同責任是 -
-
在閘道器層應用微服務身份驗證和安全性以保護實際服務
-
我們可以通過使一些日誌記錄在邊緣獲取有意義的資料和統計資料來實現微服務洞察和監控進入生態系統的所有流量,從而為我們提供準確的生產檢視。
-
動態路由可以根據需要將請求路由到不同的後端群集。
-
我們可以通過逐漸增加到新叢集的流量來進行執行時壓力測試,以便在許多情況下衡量效能,例如叢集有新的H / W和網路設定,或者部署了新版本的生產程式碼。
-
我們可以進行動態負載,即為每種型別的請求分配容量,並刪除超出限制的請求。
-
我們可以應用靜態響應處理,即直接在邊緣構建一些響應,而不是將它們轉發到內部叢集進行處理。
-
技術棧和執行環境
-
Java 1.8和IntelliJIDEA作為開發環境
-
Spring cloud Zuul作為閘道器代理提供商
-
Spring boot作為應用程式框架
-
Spring Rest用於將微服務暴露為REST
-
Maven作為構建工具
建立學生微服務
按照以下步驟開發學生微服務,稍後將通過zuul代理訪問的幾個REST端點。稍後我們將研究zuul部分,現在讓我們先建立學生服務。
建立Spring Boot專案
建立一個Spring boot專案從spring初始化網站,依賴於Web。
將專案解壓縮並匯入到IDEA中。在此步驟中,使用命令執行maven構建,mvn clean install
以便正確下載所有maven依賴項。
新增幾個REST端點
我們現在只需向此服務新增一些REST端點,以便稍後測試閘道器。為此,我們需要通過新增註釋新增一個REST控制器@RestController
。為簡單起見,我們將新增一個模型類Student
。
完成所有更改後,該類將如下所示。
package com.example.springboostudentservice;
import java.util.Date;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
應用程式配置
spring
這裡我們按屬性給這個服務命名,spring.application.name=student
我們也定義了預設埠server.port=8090
。我們需要覆蓋預設埠,因為我們將在localhost中執行不同微服務的多個例項。
驗證學生服務
最後使用命令執行maven構建,mvn clean install
並通過執行命令將此專案作為spring boot應用程式啟動java -jar target\spring-boot-zuulgatway-student-service-0.0.1-SNAPSHOT.jar
。現在,一旦伺服器啟動,轉到瀏覽器並測試端點是否正常工作。
http://localhost:8090/echoStudentName/james
http://localhost:8090/getStudentDetails/james
建立學校微服務
建立過程和學生微服務一樣,但是由於服務之間的功能和差異性,我們需要對介面進行簡單的修改
新增幾個REST斷點
我們現在只需向此服務新增一些REST端點,為此,我們需要通過新增註釋新增一個REST控制器@RestController
。為簡單起見,我們將新增一個模型類School
。
完成所有更改後,該類將如下所示。
@SpringBootApplication
@RestController
public class SpringBootZuulgatewaySchoolServiceApplication {
@RequestMapping(value = "/echoSchoolName/{name}")
public String echoSchoolName(@PathVariable(name = "name") String name)
{
return "hello <strong style=\"color: green;\">" + name + " </strong> Responsed on : " + new Date();
}
@RequestMapping(value = "/getSchoolDetails/{name}")
public School getSchoolDetails(@PathVariable(name = "name") String name)
{
return new School(name, "China", "ZheJiang");
}
public static void main(String[] args) {
SpringApplication.run(SpringBootZuulgatewaySchoolServiceApplication.class, args);
}
}
class School
{
String name;
String address;
String cls;
public School(String name, String address, String cls) {
super();
this.name = name;
this.address = address;
this.cls = cls;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public String getCls() {
return cls;
}
}
應用程式配置
現在開啟application.properties
檔案並新增這些條目。
spring:
application:
name: school
server:
port: 8100
這裡我們按屬性給這個服務命名,spring.application.name=school我們也定義了預設埠
server.port=8100`。我們需要覆蓋預設埠,因為我們將在localhost中執行不同微服務的多個例項。
驗證學校服務
最後使用命令執行maven構建,mvn clean install
並通過執行命令將此專案作為spring boot應用程式啟動java -jar target\spring-boot-zuulgatway-school-service-0.0.1-SNAPSHOT.jar
。現在,一旦伺服器啟動,轉到瀏覽器並測試端點是否正常工作。
http://localhost:8100/echoSchoolName/學軍中學
http://localhost:8100/getSchoolDetails/學軍中學
現在我們將使用Zuul建立實際的閘道器服務。
建立Zuul閘道器服務
這將是一個基於Spring boot的微服務,但它有一個特殊的功能。它將使用zuul建立一個代表學生服務的API閘道器。稍後我們可以新增任意數量的微服務,如學生服務,學校服務並能夠建立一個強大的微服務生態系統。
建立String Boot專案
從spring初始化網站建立一個具有Zuul
依賴關係的Spring boot專案。
將專案作為現有maven專案解壓縮並匯入IDEA。在此步驟中,使用命令執行maven構建,mvn clean install
以便正確下載所有maven依賴項。
啟用Zuul服務
現在@EnableZuulProxy
在src
資料夾中的Spring啟動應用程式類中新增註釋。使用此批註,此工件將像Zuul服務代理一樣執行,並將啟用API閘道器層的所有功能,如前所述。然後我們將新增一些過濾器和路由配置。
import com.example.zuuldemo.filters.ErrorFilter;
import com.example.zuuldemo.filters.PostFilter;
import com.example.zuuldemo.filters.PreFilter;
import com.example.zuuldemo.filters.RouteFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
Zuul應用配置
開啟application.yml並在下面新增條目
zuul:
routes:
student:
url: http://localhost:8090
school:
url: http://localhost:8100
server:
port: 8080
這裡zuul.routes.student.url
將路由所有流量以請求/student
到實際的學生服務伺服器。zuul.routes.school.url
將路由所有流量以請求/school
到實際的學校服務伺服器 server.port
- 需要覆蓋預設埠,因為我們將在localhost中執行不同微服務的多個例項。
新增Zuul過濾器
正如我們已經描述了zuul元件,我們將新增一些過濾器,Zuul支援4種型別的過濾器,即pre
,post
,route
和error
。在這裡,我們將建立每種型別的過濾器。
要編寫過濾器,我們基本上需要執行以下步驟:
-
需要擴充套件
com.netflix.zuul.ZuulFilter
-
需要重寫
filterType
,filterOrder
,shouldFilter
和run
方法。這裡的filterType
方法只能返回四個String中的任何一個 -pre/post/route/error
。降低此值後,過濾器將像特定過濾器一樣執行。 -
run
method是根據我們的要求放置濾波器邏輯的地方。 -
此外,我們可以根據需要新增任意數量的任何特定過濾器,這種情況
filterOrder
將用於確定該過濾器執行階段該檔案管理器的順序。
前置過濾器程式碼 - 我們將新增以下預過濾器。目前,過濾器除了println
用於測試目的之外什麼都不做。但實際上那些功能足以完成前面提到的許多重要方面。
package com.example.springbootzuulgateway.filters;
import javax.servlet.http.HttpServletRequest;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
public class PreFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
System.out.println("Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString());
return null;
}
}
後置過濾器
package com.example.springbootzuulgateway.filters; import com.netflix.zuul.ZuulFilter; public class PostFilter extends ZuulFilter { @Override public String filterType() { return "post"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { System.out.println("Inside Response Filter"); return null; } }
路由過濾器
package com.example.springbootzuulgateway.filters; import com.netflix.zuul.ZuulFilter; public class RouteFilter extends ZuulFilter { @Override public String filterType() { return "route"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { System.out.println("Inside Route Filter"); return null; } }
錯誤過濾器
package com.example.springbootzuulgateway.filters; import com.netflix.zuul.ZuulFilter; public class ErrorFilter extends ZuulFilter { @Override public String filterType() { return "error"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { System.out.println("Inside Route Filter"); return null; } }
5.5。註冊zuul過濾器
建立要自動註冊和啟用的這些過濾器的bean定義。
@Bean
public PreFilter preFilter() {
return new PreFilter();
}
@Bean
public PostFilter postFilter() {
return new PostFilter();
}
@Bean
public ErrorFilter errorFilter() {
return new ErrorFilter();
}
@Bean
public RouteFilter routeFilter() {
return new RouteFilter();
}
Netflix zuul示例演示
使用命令執行maven構建,mvn clean install
並通過執行命令將此專案作為spring boot應用程式啟動java -jar target\spring-boot-zuulgateway-0.0.1-SNAPSHOT.jar
。
現在,一旦伺服器啟動,轉到瀏覽器並通過訪問學生服務名稱和學校服務來測試端點是否正常工作,即/student
和/school
。
http://localhost:8080/student/echoStudentName/james
http://localhost:8080/school/echoSchoolName/學軍學校
總結
這就是netflix zuul過濾器示例。我建議你自己做,通過代理新增一些更多的底層服務和路由請求,應用不同型別的過濾器並在過濾器中新增真正的邏輯。
連結: https://pan.baidu.com/s/1zpUBTCDNVHO4s8TAIOxKVA 提取碼: 8v7w
請在評論部分將您的問題提交給我。
快樂學習!!