概述
Spring Cloud Zuul 是 Spring Cloud Netflix 子項(xiàng)目的核心組件之一,可以作為微服務(wù)架構(gòu)中的 API 網(wǎng)關(guān)使用,有以下用途:
- 鑒權(quán):對(duì)于訪問(wèn)每個(gè)服務(wù)的請(qǐng)求進(jìn)行鑒權(quán),拒絕鑒權(quán)失敗的請(qǐng)求
- 監(jiān)控:對(duì)系統(tǒng)的請(qǐng)求進(jìn)行監(jiān)控,記錄請(qǐng)求響應(yīng)日志,實(shí)時(shí)統(tǒng)計(jì)當(dāng)前系統(tǒng)的訪問(wèn)量以及監(jiān)控狀態(tài)
- 壓力測(cè)試:幫助對(duì)集群進(jìn)行可控的壓力測(cè)試
- 灰度測(cè)試:灰度發(fā)布可以保證整體系統(tǒng)的穩(wěn)定,在初始灰度時(shí)就可以發(fā)現(xiàn)問(wèn)題并進(jìn)行調(diào)整
- 動(dòng)態(tài)路由:基于請(qǐng)求路徑,將請(qǐng)求分發(fā)到指定的客戶端
- 負(fù)載控制:統(tǒng)一控制客戶端請(qǐng)求壓力,超過(guò)壓力的請(qǐng)求直接拒絕
- 靜態(tài)響應(yīng)處理:在邊緣位置直接建立部分響應(yīng),避免其流入內(nèi)部集群
構(gòu)建 Zuul 網(wǎng)關(guān)
創(chuàng)建 zuul-service 項(xiàng)目,引入依賴,本項(xiàng)目基于 SpringBoot 2.3.1,SpringCloud Hoxton.SR12
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
在 application.yml 配置文件中添加如下配置:
server:
port: 9080 # 指定運(yùn)行端口
spring:
application:
name: zuul-service # 指定服務(wù)名稱
zuul:
routes:
blog:
path: /baidu/**
url: https://www.baidu.com # url用于配置符合path的請(qǐng)求路徑路由到的服務(wù)地址
在啟動(dòng)類中添加 @EnableZuulProxy
注解
@EnableZuulProxy
@SpringBootApplication
public class ZuulServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServiceApplication.class, args);
}
}
Spring Cloud Netflix Zuul 提供了許多過(guò)濾器,具體取決于啟用的 Zuul 的注解,@EnableZuulProxy
是 @EnableZuulServer
的超集,包含 @EnableZuulServer
安裝的所有過(guò)濾器
啟動(dòng)項(xiàng)目,在瀏覽器中輸入訪問(wèn)地址 http://localhost:9080/baidu
,發(fā)現(xiàn)請(qǐng)求被路由到百度界面,Zuul 服務(wù)搭建成功
Zuul 路由配置
上一節(jié),我們使用路徑的方式匹配路由規(guī)則,path 的結(jié)構(gòu)如下
# 其中customName 為用戶自定義名稱
zuul:
routes:
customName:
# 可使用的通配符有以下幾種:
# ?:單個(gè)字符
# *:任意多個(gè)字符,不包含多級(jí)路徑
# **:任意多個(gè)字符,包含多級(jí)路徑
path: xxx
對(duì)于 url 路徑匹配,還可以使用服務(wù)名稱匹配
zuul:
routes:
# users為用戶自定義名稱
users:
path: /users/**
# serviceId用于配置符合path的請(qǐng)求路徑路由到的服務(wù)名稱
serviceId: users-service
服務(wù)名稱匹配也可以使用簡(jiǎn)化的配置
zuul:
routes:
service-provider:
path: /users/**
如果只配置 path 不配置 serviceld,則 customName 相當(dāng)于服務(wù)名稱,即 service-provider 會(huì)被當(dāng)作服務(wù)名稱,使用 serviceId 要將 zuul 服務(wù)注冊(cè)到注冊(cè)中心使用,比如 Eureka,從而拉取注冊(cè)服務(wù)列表名稱完成調(diào)用
如果想排查配置,可以使用 ignored-services
zuul:
ignoredServices: "*"
routes:
users:
path: /users/**
ignored-services 可以配置不被 zuul 管理的服務(wù)列表,多個(gè)服務(wù)名稱使用號(hào)分隔,配置的的務(wù)將不被 Zuul代理,在上面的實(shí)例中,除了用戶服務(wù)外,所有的服務(wù)均被忽略
可以通過(guò) zuul.prefix
配置路由前綴,例如:
zuul:
prefix: /api
routes:
users:
path: /users/**
配置請(qǐng)求路徑前綴,所有基于此前綴的請(qǐng)求都由 Zuul 網(wǎng)關(guān)提供代理
Zuul 過(guò)濾器
Zuul 定義過(guò)濾器用來(lái)過(guò)濾代理請(qǐng)求,提供額外功能邏輯,如權(quán)限驗(yàn)證、日志記錄等,filter 與 filter 之間不直接通信,在請(qǐng)求線程中會(huì)通過(guò) RequestContext 來(lái)共享狀態(tài),它內(nèi)部是用 ThreadLocal 實(shí)現(xiàn)的
Zuul 過(guò)濾器分為前置過(guò)濾、路由后過(guò)濾、后置過(guò)濾以及異常過(guò)濾:
- 前置過(guò)濾:在請(qǐng)求進(jìn)入 Zuul 后,立刻執(zhí)行的過(guò)濾邏輯
- 路由后過(guò)濾:在請(qǐng)求進(jìn)入 Zuul 后,Zuul 實(shí)現(xiàn)請(qǐng)求路由,并在遠(yuǎn)程服務(wù)調(diào)用之前執(zhí)行過(guò)濾邏輯
- 后置過(guò)濾:遠(yuǎn)程服務(wù)調(diào)用結(jié)束后執(zhí)行過(guò)濾邏輯
- 異常過(guò)濾:任意一個(gè)過(guò)濾器發(fā)生異常或遠(yuǎn)程服務(wù)調(diào)用無(wú)結(jié)果反饋時(shí)(調(diào)用超時(shí))執(zhí)行過(guò)濾邏輯
ZuulFilter 類及其父類 IZuulFilter 共提供了四種抽象方法:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-675173.html
- filterType:返回字符串?dāng)?shù)據(jù),代表當(dāng)前過(guò)濾器的類型,可選值有:
- pre:前置過(guò)濾器,在請(qǐng)求被路由前執(zhí)行,通常用于處理身份認(rèn)證、日志記錄等
- route:在路由執(zhí)行后,服務(wù)調(diào)用前被調(diào)用
- error:任意一個(gè) filter 發(fā)生異?;蜻h(yuǎn)程服務(wù)調(diào)用沒(méi)有反饋時(shí)執(zhí)行(超時(shí)),通常用于處理異
常 - post:在 route 或 error 執(zhí)行后被調(diào)用,一般用于收集服務(wù)信息、統(tǒng)計(jì)服務(wù)性能指標(biāo)等,也可以對(duì) response 結(jié)果做特殊處理
- filterOrder:返回 int 數(shù)據(jù),用于為同一種 filterType 的多個(gè)過(guò)濾器定制執(zhí)行順序,返回值越小,執(zhí)行順序越優(yōu)先
- shouldFilter:返回 boolean 數(shù)據(jù),代表當(dāng)前 filter 是否生效
- run:具體的過(guò)濾執(zhí)行邏輯
具體實(shí)例如下:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-675173.html
@Component
public class tokenFilter extends ZuulFilter {
@Override
public String filterType() {
//定義過(guò)濾器的類型,pre 表示在請(qǐng)求被路由前執(zhí)行
return "pre";
}
@Override
public int filterOrder() {
//返回int 數(shù)據(jù),用于為同一種 filterType 的多個(gè)過(guò)濾器定制執(zhí)行順序
//返回值越小,執(zhí)行順序越優(yōu)先
return 0;
}
@Override
public boolean shouldFilter() {
//判斷過(guò)濾器是否生效,true 代表生效
return true;
}
@Override
public Object run() throws ZuulException {
//獲取上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//獲取 request 對(duì)象
HttpServletRequest request = currentContext.getRequest();
//從請(qǐng)求頭獲取 token 的參數(shù)
String userToken = request.getParameter("token");
if (StringUtils.isEmpty(userToken)) {
//返回錯(cuò)誤提示
//false:表示不會(huì)繼續(xù)往下執(zhí)行,不會(huì)調(diào)用服務(wù)接口,直接響應(yīng)給客戶
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("token is null");
currentContext.setResponseStatusCode(401);
return null;
}
//否則正常執(zhí)行,調(diào)用服務(wù)接口...
return null;
}
}
到了這里,關(guān)于微服務(wù)網(wǎng)關(guān) —— SpringCloud Netflix Zuul的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!