SpringCloud實戰9
微服務閘道器
微服務閘道器是介於客戶端與伺服器端的中間層,所有外部請求先經過閘道器。
微服務閘道器封裝了應用程式的內部結構,客戶端只用跟閘道器互動,而無需直接呼叫特定的微服務介面
Zuul簡介
Zuul可以通過載入動態過濾機制,從而實現以下各項功能:
1.驗證與安全保障: 識別面向各類資源的驗證要求並拒絕那些與要求不符的請求。
2.審查與監控: 在邊緣位置追蹤有意義資料及統計結果,從而為我們帶來準確的生產狀態結論。
3.動態路由: 以動態方式根據需要將請求路由至不同後端叢集處。
4.壓力測試: 逐漸增加指向叢集的負載流量,從而計算效能水平。
5.負載分配: 為每一種負載型別分配對應容量,並棄用超出限定值的請求。
6.靜態響應處理: 在邊緣位置直接建立部分響應,從而避免其流入內部叢集。
7.多區域彈性: 跨越AWS區域進行請求路由,旨在實現ELB使用多樣化並保證邊緣位置與使用者儘可能接近。
編寫Zuul微服務閘道器
建立一個子專案
新增pom.xml依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
啟動類添加註解@EnableZuulProxy
@SpringBootApplication
@EnableZuulProxy //宣告一個Zuul代理
public class YmkGetewayZuulApplication {
public static void main(String[] args) {
SpringApplication.run(YmkGetewayZuulApplication.class, args);
}
}
修改application,yml
server: port: 8040 spring: application: name: gateway-zuul eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ management: security: enabled: false
一個簡單的微服務閘道器就完成了,有配置可知道,添加了Zuul的依賴,並註冊到Eureka Server上。
預設情況下,Zuul會代理所有註冊到Eureka Server上的微服務,並且Zuul的路由規則如下:http://zuul_host:zuul_port/微服務的serviceId/**
路由配置下詳解
前文已經編寫了一個簡單的Zuul閘道器,並讓閘道器代理了所有註冊到Eureka Server的微服務,但是現實中可能只想Zuul代理部分微服務,又或者需要對URL的路由配置。
1、自定義指定微服務的訪問路徑
zuul:
routes:
feign-consumer: /test/**
2、忽略指定微服務
忽略多個微服務,逗號分隔即可
zuul:
ignored-services: feign-consumer
3、忽略所有的服務,只路由指定的服務
zuul:
ignored-services: '*' # 使用'*'可忽略所有微服務
routes:
feign-consumer: /user/**
4、同時指定微服務的serviceId和對應路徑
zuul:
routes:
user-route: # 該配置方式中,user-route只是給路由一個名稱,可以任意起名。
service-id: feign-consumer
path: /user/** # service-id對應的路徑
跟例項1一樣的效果
5、同時指定path和url
zuul:
routes:
user-route: # 該配置方式中,user-route只是給路由一個名稱,可以任意起名。
url: http://localhost:8000/ # 指定的url
path: /user/** # url對應的路徑。
這樣就可以將/user/** 對映到http://localhost:8000/**。這種方式配置的路由不會作為HystrixCommand執行,同時也不能用Ribbon來負載均衡多個URL。例項6可解決該問題。
6、同時指定path和url,並且不破壞Zuul的Hystrix,Bibbon特性。
zuul:
routes:
user-route:
path: /user/**
service-id: feign-consumer
ribbon:
eureka:
enabled: false # 禁用掉ribbon的eureka使用。
feign-consumer:
ribbon:
listOfServers: localhost:8000,localhost:8001
7、路由字首
zuul:
prefix: /api
routes:
feign-consumer: /test/**
8、忽略某些路徑
zuul:
ignoredPatterns: /**/admin/** # 忽略所有包括/admin/的路徑
routes:
feign-consumer: /user/**
9、本地轉發
zuul:
routes:
route-name:
path: /path-a/**
url: forward:/path-b
這樣訪問,Zuul的path/a/**路徑,將轉發到path/b/**
Zuul過濾器
過濾器是zuul的核心元件,過濾器可以說是Zuul實現API閘道器功能最為核心的部件,每一個進入Zuul的HTTP請求都會經過一系列的過濾器處理鏈得到請求響應並返回給客戶端
zuul定義了4中標準過濾器
pre:可以在請求被路由之前呼叫。
routing:在路由請求時候被呼叫。
post:在routing和error過濾器之後被呼叫。
error:處理請求時發生錯誤時被呼叫。
編寫一個過濾器
新建過濾器類
public class PermisFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String login = request.getParameter("login");
if (login == null) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.addZuulResponseHeader("content-type","text/html;charset=utf-8");
ctx.setResponseBody("非法訪問");
}
return null;
}
}
filterType:該函式需要返回一個字串來代表過濾器的型別,而這個型別就是在HTTP請求過程中定義的各個階段。在Zuul中預設定義了四種不同生命週期的過濾器型別
filterOrder:通過int值來定義過濾器的執行順序,數值越小優先順序越高。
shouldFilter:返回一個boolean型別來判斷該過濾器是否要執行。我們可以通過此方法來指定過濾器的有效範圍。
run:過濾器的具體邏輯。在該函式中,我們可以實現自定義的過濾邏輯,來確定是否要攔截當前的請求,不對其進行後續的路由,或是在請求路由返回結果之後,對處理結果做一些加工等
在啟動類,新增過濾器
@SpringBootApplication
@EnableZuulProxy //宣告一個Zuul代理
public class YmkGetewayZuulApplication {
public static void main(String[] args) {
SpringApplication.run(YmkGetewayZuulApplication.class, args);
}
//配置過濾器Bean
@Bean
PermisFilter permisFilter() {
return new PermisFilter();
}
}