文章目錄
- 介紹
- 搭建Zuul網關伺服器
- 路由
- 過濾器
-
- 自定義zuulFilter
-
- 身份認證示例
- Zuul原理
- 弊端
介紹
Zuul是Netflix開源的微服務網關,它可以和Eureka、Ribbon、Hystrix等元件配合使用,Zuul元件核心是一系列過濾器,這些過濾器可以完成:
- 動态路由:動态将請求路由到不同後端叢集
- 壓力測試:逐漸增加指向叢集的流量,以了解性能
- 負載配置設定:為每一種負載類型配置設定對應的容量,并棄用超出限定值的請求
- 靜态相應處理:邊緣位置進行響應,避免轉發到内部叢集
- 身份認證和安全:識别每個一資源的驗證要求,并拒絕那些不符合的請求。Spring Cloud對Zuul進行了整合和增強
搭建Zuul網關伺服器
- 建立一個新的maven工程,引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
- 配置yml
server:
port: 8888 #端口
spring:
application:
name: api-zuul-service #服務名稱
- 啟動類
@SpringBootApplication
//開啟Zuul網關功能
@EnableZuulProxy
public class ZuulServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServerApplication.class,args);
}
}
路由
路由:根據請求的url将請求配置設定到對應的微服務中進行處理。
- 基礎路由配置
#路由配置
zuul:
routes:
#例子
product-service: #路由id
path: /product-service/** #映射路徑 #localhost:8888/product-service/xxxxx
url: http://192.168.0.107:9001/ #映射路徑對應的實際位址
通路:http://127.0.0.1:8888/product-service/product/getProduct/1
-
面向服務的路由配置(整合Eureka)
1.添加Eureka的依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.開啟Eureka的用戶端服務發現
//在啟動類上添加注解(比較新的版本可以不加)
@EnableDiscoveryClient
3.在Zuul網關服務中配置Eureka的注冊中心相關資訊
添加eureka配置
#eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:9000/eureka/,http://localhost:8999/eureka/
instance:
prefer-ip-address: true #使用ip位址注冊
instance-id: ${spring.cloud.client.ip-address}:${server.port} #向注冊中心中注冊ip
4.修改路由中的映射配置
#路由配置
zuul:
routes:
#例子
product-service: #路由id
path: /product-service/** #映射路徑 #localhost:8888/product-service/xxxxx
# url: http://192.168.0.107:9001/ #映射路徑對應的實際位址
serviceId: product-service #配置轉發的微服務的服務名稱
- 簡化路由配置
#路由配置
zuul:
routes:
#如果目前的微服務名稱product-service,預設的請求映射路徑 /product-service/**
# 如果路由id和對應的微服務的serviceId一緻的話
product-service: /product-service/**
其實不配置也可以,比如,現在配置檔案上沒有配置comsumer-service,但是如果直接通路:http://127.0.0.1:8888/consumer-service/demo/get/1,也是完全沒問題的。
過濾器
Zuul中的過濾器跟我們使用的javax.servlet.Filter不一樣,javax.servlet.Filter隻有一種類型,可以通過配置urlPatterns來攔截對應的請求。而Zuul中的過濾器一共就4種類型,而且每一種類型都有對應的使用場景:
- PRE:這種過濾器在請求被路由之前調用。我們可以利用這種過濾器實作身份驗證、在集權中選擇請求的微服務、記錄調試資訊等。
- ROUTING:這種過濾器将請求路由到微服務。這種過濾器用于建構發送給微服務的請求,并使用Apache HttpClient或者Netfilx Ribbon請求微服務。
- POST:這種過濾器在路由到微服務以後執行。這種過濾器可用來為響應添加标準的HTTP Header、收集統計資訊和名額、将響應從微服務發送給用戶端等。
-
ERROR:在其他階段發生錯誤時執行該過濾器。
調用順序示意圖:
自定義zuulFilter
1.繼承ZuulFilter ,實作四個方法
2.将LoginFilter 交給spring容器管理
/**
* 自定義的zuul過濾器
* 繼承抽象父類
* */
@Component
public class LoginFilter extends ZuulFilter {
/**
* 定義過濾器類型
* pre
* routing
* post
* error
* */
@Override
public String filterType() {
return "pre";
}
/**
* 指定過濾器的執行順序
* 傳回值越小,執行順序越高
* */
@Override
public int filterOrder() {
return 1;
}
/**
* 目前過濾氣是否生效
* true:使用
* false:不适用
* */
@Override
public boolean shouldFilter() {
return true;
}
/**
* 執行過濾器中的業務邏輯
* */
@Override
public Object run() throws ZuulException {
System.out.println("執行了過濾器");
return null;
}
}
身份認證示例
重寫run方法
/**
* 執行過濾器中的業務邏輯
* 身份認證:
* 1.所有的請求需要攜帶一個參數:access-token
* 2.擷取request請求
* 3.通過request擷取參數access-token
* 4.判斷token是否為空
* 4.1 token == null:身份驗證失敗
* 4.2 token != null:執行後續操作
* */
@Override
public Object run() throws ZuulException {
//1.擷取zuul提供的上下文對象RequestContext
RequestContext ctx = RequestContext.getCurrentContext();
//2.從RequestContext中擷取request
HttpServletRequest request = ctx.getRequest();
//3.擷取請求參數access-token
String token = request.getParameter("access-token");
//4.判斷
if(token == null){
ctx.setSendZuulResponse(false);//攔截請求
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
//繼續執行
return null;
}
Zuul原理
弊端
1.請求線程池同步阻塞問題
2.不支援WebSoucket