SpringCloud Alibaba 核心組件解析:服務(wù)網(wǎng)關(guān)
技術(shù)棧:Spring Boot 3.2.0 + Spring Cloud Alibaba 2023.0.0.0-RC1 + Sentinel + Gateway + Nacos
6.1 是什么 — Sentinel 網(wǎng)關(guān)限流
Gateway 負責(zé)路由轉(zhuǎn)發(fā),Sentinel 負責(zé)流量控制。兩者整合后,可以在網(wǎng)關(guān)層對進入微服務(wù)的流量進行統(tǒng)一限流和熔斷,在請求到達微服務(wù)之前就攔截。
6.1.1 調(diào)用鏈路
客戶端請求
│
▼
┌─────────────────────────────┐
│ Gateway (9528) │
│ ┌─────────────────────────┐ │
│ │ SentinelGatewayFilter │ │ ← 在這里攔截!超閾值直接拒絕
│ │ (網(wǎng)關(guān)層限流 QPS=2) │ │
│ └─────────┬───────────────┘ │
│ │ 通過限流 │
└────────────┼────────────────┘
▼
┌─────────────────────────────┐
│ Provider (9001) │
│ ┌─────────────────────────┐ │
│ │ @SentinelResource │ │ ← 服務(wù)層精細化限流
│ └─────────────────────────┘ │
└─────────────────────────────┘6.1.2 網(wǎng)關(guān)限流 vs 服務(wù)限流
| 層級 | 組件 | 粒度 | 場景 |
|---|---|---|---|
| 網(wǎng)關(guān)層 | GatewayFlowRule | 按路由或 API 分組 | 入口總流量控制 |
| 服務(wù)層 | @SentinelResource | 按接口/資源 | 精細化流量控制 |
6.2 為什么 — 網(wǎng)關(guān)層限流的優(yōu)勢
- 請求入口攔截:不讓無效請求進入微服務(wù)層,節(jié)省資源
- 統(tǒng)一管理:所有路由規(guī)則集中在網(wǎng)關(guān)配置,不需要每個微服務(wù)各自配
- 安全防護:惡意刷量在網(wǎng)關(guān)層就被攔截
6.3 怎么做 — 完整實戰(zhàn)
6.3.1 項目模塊
| 模塊 | 端口 | 說明 |
|---|---|---|
clooudalibaba-sentinel-gateway9528 | 9528 | Sentinel + Gateway |
cloudalibaba-provider-payment9001 | 9001 | 被代理的服務(wù) |
6.3.2 步驟 ①:依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Sentinel 適配 Gateway 的橋接包 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>6.3.3 步驟 ②:配置
server:
port: 9528
spring:
application:
name: cloudalibaba-sentinel-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: pay_routh1
uri: http://localhost:9001 # 直接轉(zhuǎn)發(fā)到 Provider
predicates:
- Path=/pay/**
sentinel:
log:
dir: D:/yangnan/Documents/SpringCloud/sentinel-log6.3.4 步驟 ③:核心配置類
// clooudalibaba-sentinel-gateway9528/.../config/GatewayConfiguration.java
@Configuration
public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(
ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
// ① 注冊 Sentinel 異常處理器(最高優(yōu)先級)
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(
viewResolvers, serverCodecConfigurer);
}
// ② 注冊 Sentinel 全局過濾器(Order=-1,低于上方的處理器,但高于其他過濾器)
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
// ③ 應(yīng)用啟動后初始化規(guī)則
@PostConstruct
public void doInit() {
initBlockHandler();
}
private void initBlockHandler() {
// 網(wǎng)關(guān)流控規(guī)則:對路由 pay_routh1 限制每秒最多 2 個請求
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("pay_routh1")
.setCount(2) // QPS 閾值
.setIntervalSec(1)); // 統(tǒng)計間隔 1 秒
GatewayRuleManager.loadRules(rules);
// 自定義限流響應(yīng)(返回 JSON 而不是默認 HTML)
BlockRequestHandler handler = (exchange, t) -> {
Map<String, String> map = new HashMap<>();
map.put("errorCode",
HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());
map.put("errorMessage",
"請求太過頻繁,系統(tǒng)忙不過來,觸發(fā)限流(sentinel+gateway整合Case)");
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(map));
};
GatewayCallbackManager.setBlockHandler(handler);
}
}配置解讀:
| 組件 | 作用 |
|---|---|
SentinelGatewayBlockExceptionHandler | 處理限流時拋出的 BlockException |
SentinelGatewayFilter | 攔截每個請求,執(zhí)行限流規(guī)則判斷 |
GatewayFlowRule | 網(wǎng)關(guān)級流控規(guī)則,按 routeId 限流 |
BlockRequestHandler | 自定義被限流時返回的錯誤信息(JSON 格式) |
6.3.5 步驟 ④:驗證
- 啟動 Nacos → Gateway(9528) → Provider(9001)
- 快速連續(xù)訪問
http://localhost:9528/pay/nacos/1 - QPS > 2 時返回自定義 JSON:
{
"errorCode": "Too Many Requests",
"errorMessage": "請求太過頻繁,系統(tǒng)忙不過來,觸發(fā)限流(sentinel+gateway整合Case)"
}6.4 深入原理 — 網(wǎng)關(guān)限流實現(xiàn)流程
請求到達 Gateway
│
▼
SentinelGatewayFilter.doFilter()
│
├→ 提取 routeId(如 "pay_routh1")
├→ 匹配 GatewayFlowRule(QPS=2)
├→ 判斷是否超閾值
│
├→ 未超:chain.filter() → 轉(zhuǎn)發(fā)到 Provider ?
└→ 超了:throw BlockException → BlockRequestHandler → 返回 JSON ?6.5 網(wǎng)關(guān)限流 vs 服務(wù)限流對比
| 維度 | 網(wǎng)關(guān)限流 | 服務(wù)限流 |
|---|---|---|
| 實現(xiàn)方式 | GatewayFlowRule + SentinelGatewayFilter | @SentinelResource |
| 配置位置 | 網(wǎng)關(guān)代碼中硬編碼或動態(tài)配置 | 控制臺或注解 |
| 粒度 | 按路由/API 分組 | 按資源名/URL |
| 優(yōu)勢 | 統(tǒng)一入口,減少無效流量進入 | 精細化控制 |
| 劣勢 | 無法感知服務(wù)內(nèi)部邏輯 | 需要每個服務(wù)單獨配置 |
6.6 面試題
Q1:網(wǎng)關(guān)層限流和服務(wù)層限流如何選擇?
答:兩者不是替代關(guān)系而是互補關(guān)系。網(wǎng)關(guān)層做粗粒度總流量控制(如每秒不超過 1000),服務(wù)層做細粒度接口控制(如秒殺接口單獨限制)。雙層防護更安全。
Q2:Sentinel 網(wǎng)關(guān)限流和 Resilience4J RequestRateLimiter 有什么區(qū)別?
答:Sentinel 需要獨立部署 Dashboard,提供實時監(jiān)控和規(guī)則熱更新;Resilience4J RequestRateLimiter 是 Gateway 內(nèi)置過濾器,配置簡單但功能有限。
6.7 踩坑指南
| 坑 | 現(xiàn)象 | 原因 | 解決 |
|---|---|---|---|
| ?? 過濾器優(yōu)先級不對 | 限流不生效 | SentinelGatewayFilter 優(yōu)先級低于其他過濾器 | 確保 @Order(-1) |
| ?? 異常處理器不工作 | 限流后返回默認 HTML 錯誤頁 | SentinelGatewayBlockExceptionHandler 未注冊或優(yōu)先級不夠 | 確保 @Order(Ordered.HIGHEST_PRECEDENCE) |
| ?? sentinel-gateway-adapter 版本沖突 | NoClassDefFoundError | adapter 版本與 sentinel-core 不匹配 | 由 Spring Cloud Alibaba BOM 統(tǒng)一管理版本,不要手動指定 |
6.8 章節(jié)總結(jié)
| 要點 | 說明 |
|---|---|
| 三個關(guān)鍵 Bean | SentinelGatewayFilter(攔截請求)+ SentinelGatewayBlockExceptionHandler(處理異常)+ GatewayFlowRule(配置規(guī)則) |
| 規(guī)則配置 | GatewayFlowRule("routeId").setCount(N).setIntervalSec(S) |
| 自定義響應(yīng) | BlockRequestHandler 返回 JSON,替代默認 HTML |
| 雙層防護 | 網(wǎng)關(guān)層粗粒度 + 服務(wù)層細粒度,組合使用 |
| @Order 很重要 | HIGHEST_PRECEDENCE 給異常處理器,-1 給過濾器 |
到此這篇關(guān)于SpringCloud Alibaba 核心組件解析:服務(wù)網(wǎng)關(guān)的文章就介紹到這了,更多相關(guān)SpringCloud Alibaba 服務(wù)網(wǎng)關(guān)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解SpringMVC中的@RequestMapping注解
這篇文章主要介紹了SpringMVC中@RequestMapping注解,@RequestMapping注解是一個用來處理請求地址映射的注解,可用于映射一個請求或一個方法,可以用在類或方法上,需要的朋友可以參考下2023-07-07
Java的super關(guān)鍵字與instanceof運算符使用方法
這篇文章主要介紹了Java的super關(guān)鍵字與instanceof運算符使用方法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09
guava中Multimap、HashMultimap用法小結(jié)
這篇文章主要介紹了guava中Multimap、HashMultimap使用,Multimap它可以很簡單的實現(xiàn)一些功能,LinkedHashMultimap實現(xiàn)類與HashMultimap類的實現(xiàn)方法一樣,唯一的區(qū)別是LinkedHashMultimap保存了記錄的插入順序,本文就這些內(nèi)容講解的非常詳細,需要的朋友參考下吧2022-05-05
Java 最優(yōu)二叉樹的哈夫曼算法的簡單實現(xiàn)
這篇文章主要介紹了Java 最優(yōu)二叉樹的哈夫曼算法的簡單實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
基于Freemarker和xml實現(xiàn)Java導(dǎo)出word
這篇文章主要介紹了基于Freemarker和xml實現(xiàn)Java導(dǎo)出word,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04
Java嵌套for循環(huán)的幾種常見優(yōu)化方案
這篇文章主要給大家介紹了關(guān)于Java嵌套for循環(huán)的幾種常見優(yōu)化,在Java中優(yōu)化嵌套for循環(huán)可以通過以下幾種方式來提高性能和效率,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-07-07

