Spring Cloud Gateway 實戰:網關配置與 Sentinel 限流詳解

Spring Cloud Gateway 實戰:網關配置與 Sentinel 限流詳解

在微服務架構中,網關扮演著統一入口、負載均衡、安全認證、限流等多種角色。Spring Cloud Gateway 是 Spring Cloud 官方推出的新一代網關組件,相比于第一代 Netflix Zuul,性能更強、功能更豐富,且基于 Netty 和 WebFlux 開發,完全非阻塞、響應式。

本文將詳細介紹 Spring Cloud Gateway 的基礎配置、與 Nacos 注冊中心的整合,以及如何基于 Sentinel 進行網關限流(包括路由限流和 API 分組限流)。


什么是 Spring Cloud Gateway

Spring Cloud Gateway 是 Spring Cloud 官方網關組件,屬于第二代網關解決方案,替代了 Zuul。

優點

  • 基于 Netty + WebFlux,性能更高
  • 支持豐富的路由謂詞和過濾器
  • 與 Spring Cloud 生態無縫集成

注意事項

  • 不兼容 Servlet(例如 SpringMVC)
  • 不支持 war 包部署,只能以 jar 形式運行

快速上手 Spring Cloud Gateway

引入依賴

一定不能引入 spring-boot-starter-web,因為它基于 Servlet,會導致沖突。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

application.yml 配置

以下為最簡單的靜態路由配置(不使用注冊中心):

server:port: 8010
spring:application:name: gatewaycloud:gateway:routes:- id: provider_routeuri: http://localhost:8081predicates:- Path=/provider/**filters:- StripPrefix=1- id: consumer_routeuri: http://localhost:8181predicates:- Path=/consumer/**filters:- StripPrefix=1

說明

  • id:路由標識
  • uri:轉發地址
  • predicates:請求匹配條件(如路徑)
  • filters:過濾器(如去前綴)

整合 Nacos 服務注冊中心

通過 Nacos 讓 Gateway 自動發現服務,無需手動配置 routes。

引入依賴

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

修改配置

server:port: 8010
spring:application:name: gatewaycloud:gateway:discovery:locator:enabled: true

開啟后,Gateway 會自動根據 Nacos 上注冊的服務自動創建路由。


Gateway 限流(基于 Sentinel)

在實際生產環境中,網關限流非常重要,可以防止后端服務被惡意或突發大流量沖擊。

引入依賴

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>

基于路由 ID 的限流

配置 routes

server:port: 8010
spring:application:name: gatewaycloud:gateway:discovery:locator:enabled: trueroutes:- id: provider_routeuri: http://localhost:8081predicates:- Path=/provider/**filters:- StripPrefix=1

配置限流類

@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;}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@PostConstructpublic void initGatewayRules() {Set<GatewayFlowRule> rules = new HashSet<>();rules.add(new GatewayFlowRule("provider_route").setCount(1).setIntervalSec(1));GatewayRuleManager.loadRules(rules);}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();}@PostConstructpublic void initBlockHandlers() {BlockRequestHandler blockRequestHandler = (exchange, throwable) -> {Map<String, Object> map = new HashMap<>();map.put("code", 0);map.put("msg", "被限流了");return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(map));};GatewayCallbackManager.setBlockHandler(blockRequestHandler);}
}

被限流后,返回自定義 JSON 響應 {"code":0,"msg":"被限流了"}


基于 API 分組的限流

除了基于路由 ID 的限流,還可以針對 URL 前綴或具體路徑進行分組限流。

修改配置

只開啟服務發現,不寫 routes。

server:port: 8010
spring:application:name: gatewaycloud:gateway:discovery:locator:enabled: true

配置限流類

@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;}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@PostConstructpublic void initGatewayRules() {Set<GatewayFlowRule> rules = new HashSet<>();rules.add(new GatewayFlowRule("provider_api1").setCount(1).setIntervalSec(1));rules.add(new GatewayFlowRule("provider_api2").setCount(1).setIntervalSec(1));GatewayRuleManager.loadRules(rules);}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();}@PostConstructpublic void initBlockHandlers() {BlockRequestHandler blockRequestHandler = (exchange, throwable) -> {Map<String, Object> map = new HashMap<>();map.put("code", 0);map.put("msg", "被限流了");return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(map));};GatewayCallbackManager.setBlockHandler(blockRequestHandler);}@PostConstructprivate void initCustomizedApis() {Set<ApiDefinition> definitions = new HashSet<>();ApiDefinition api1 = new ApiDefinition("provider_api1").setPredicateItems(new HashSet<ApiPredicateItem>() {{add(new ApiPathPredicateItem().setPattern("/provider/api1/**").setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));}});ApiDefinition api2 = new ApiDefinition("provider_api2").setPredicateItems(new HashSet<ApiPredicateItem>() {{add(new ApiPathPredicateItem().setPattern("/provider/api2/demo1"));}});definitions.add(api1);definitions.add(api2);GatewayApiDefinitionManager.loadApiDefinitions(definitions);}
}

Controller 示例

@RestController
@RequestMapping("/provider")
public class DemoController {@GetMapping("/api1/demo1")public String demo1() {return "demo1";}@GetMapping("/api1/demo2")public String demo2() {return "demo2";}@GetMapping("/api2/demo1")public String demo3() {return "demo3";}@GetMapping("/api2/demo2")public String demo4() {return "demo4";}
}

限流效果

  • /provider/api1/** 前綴限流,每秒允許 1 個請求
  • /provider/api2/demo1 單接口限流,每秒允許 1 個請求

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86706.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86706.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86706.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JAVA-常用API(二)

目錄 1.Arrays 1.1認識Arrays 1.2Arrays的排序 2.JDK8的新特性&#xff1a;Lambda表達式 2.1認識Lambda表達式 2.2用Lambda表達式簡化代碼、省略規則 3.JDK8的新特性&#xff1a;方法引用&#xff08;進一步簡化Lambda表達式&#xff09; 3.1 靜態方法引用 3.2 實例方法引…

深入理解PHP的命名空間

命名空間是PHP 5.3引入的一個特性&#xff0c;它的主要目的是解決在大型應用程序中可能出現的名稱沖突問題。在沒有命名空間的情況下&#xff0c;如果兩個不同的庫或模塊定義了相同名稱的函數或類&#xff0c;那么在使用這些庫或模塊的時候就會引發沖突。為了解決這個問題&…

SwiftUI學習筆記day5:Lecture 5 Stanford CS193p 2023

SwiftUI學習筆記day5:Lecture 5 Stanford CS193p 2023 課程鏈接&#xff1a;Lecture 5 Stanford CS193p 2023代碼倉庫&#xff1a;iOS課程大綱&#xff1a; Enum 定義&#xff1a;enum MyType { … }關聯值&#xff1a;case drink(name: String, oz: Int)匹配&#xff1a;switc…

idea 報錯:java: 非法字符: ‘\ufeff‘

idea 報錯&#xff1a;java: 非法字符: ‘\ufeff‘ 解決方案&#xff1a;

數據結構與算法之美:圖

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《題海拾貝》、《C修煉之路》 歡迎點贊&#xff0c;關注&am…

SpringBoot -- 熱部署

9.SpringBoot 熱部署&#xff08;自動重啟&#xff09; 在實際開發過程中&#xff0c;每次修改代碼就得將項目重啟&#xff0c;重新部署&#xff0c;對于一些大型應用來說&#xff0c;重啟時間需要花費大量的時間成本。對于一個后端開發者來說&#xff0c;重啟過程確實很難受啊…

HarmonyOS 5瀏覽器引擎對WebGL 2.0的支持如何?

以下是HarmonyOS 5瀏覽器引擎對?WebGL 2.0?支持的詳細技術分析&#xff1a; 一、核心支持能力 ?系統能力聲明 HarmonyOS 5 瀏覽器引擎通過 SystemCapability.Graphic.Graphic2D.WebGL2 提供對 WebGL 2.0 的底層支持 支持的關鍵特性包括&#xff1a; OpenGL ES 3.0 特性…

Class1線性回歸

Class1線性回歸 買房預測 要根據歷史數據來預測一套房子的價格。你發現影響房價的因素有很多&#xff0c;于是你決定使用線性回歸模型來預測房價。 影響房價的因素如下&#xff1a; 房屋面積&#xff08;平方米&#xff09; 房齡&#xff08;年&#xff09; 離地鐵站的距離&a…

Vue.js 3:重新定義前端開發的進化之路

Vue.js 3&#xff1a;重新定義前端開發的進化之路 引言&#xff1a;一場醞釀已久的革新 2020年9月18日&#xff0c;Vue.js團隊以代號"One Piece"正式發布3.0版本&#xff0c;這不僅是框架發展史上的重要里程碑&#xff0c;更是前端工程化領域的一次革命性突破。歷經…

Unity性能優化-渲染模塊(1)-CPU側(1)-優化方向

Unity 中渲染方面的優化大致可以劃分為以下幾塊核心內容&#xff1a; CPU 優化 (減少 Draw Calls 和 CPU 瓶頸) GPU 優化 (減少像素著色和 GPU 瓶頸) 內存和顯存優化 (Resource Management) 光照優化 (Lighting & Global Illumination) 這四個方面是相互關聯的。一個方…

AI矢量圖與視頻無痕修復:用Illustrator與After Effects解鎖創作新維度

最近因一個項目&#xff0c;有機會深度體驗了奧地利Blueskyy藝術學院授權的Adobe教育版全家桶&#xff0c;過程中發現了不少令人驚喜的“黑科技”&#xff0c;很想和大家分享這份發掘寶藏的喜悅。一句話總結這次體驗&#xff1a;慷慨且穩定。比如&#xff0c;它每周提供高達150…

Maven Javadoc 插件使用詳解

Maven Javadoc 插件使用詳解 maven-javadoc-plugin 是 Maven 項目中用于生成 Java API 文檔的標準插件&#xff0c;它封裝了 JDK 的 javadoc 工具&#xff0c;提供了更便捷的配置和集成方式。 一、基本使用 1. 快速生成 Javadoc 在項目根目錄執行以下命令&#xff1a; bas…

Apache Kafka 面試應答指南

Apache Kafka 核心知識詳解與面試應答指南 一、Apache Kafka 概述 Apache Kafka 作為一款分布式流處理框架,在實時構建流處理應用領域發揮著關鍵作用。其最廣為人知的核心功能,便是作為企業級消息引擎被眾多企業采用。 二、消費者組 (一)定義與原理 消費者組是 Kafka 獨…

在NVIDIA Jetson和RTX上運行Google DeepMind的Gemma 3N:多模態AI的邊緣計算革命

在NVIDIA Jetson和RTX上運行Google DeepMind的Gemma 3N&#xff1a;多模態AI的邊緣計算革命 文章目錄 在NVIDIA Jetson和RTX上運行Google DeepMind的Gemma 3N&#xff1a;多模態AI的邊緣計算革命引言&#xff1a;多模態AI進入邊緣計算時代文章結構概覽 第一章&#xff1a;Gemma…

iOS打包流程中的安全處理實踐:集成IPA混淆保護的自動化方案

隨著iOS應用上線節奏的加快&#xff0c;如何在持續集成&#xff08;CI&#xff09;或交付流程中嵌入安全處理手段&#xff0c;成為開發團隊構建自動化發布鏈路時不可忽視的一環。特別是在App已經完成構建打包&#xff0c;準備分發前這一階段&#xff0c;對IPA進行結構層面的加固…

FFmpeg進行簡單的視頻編輯與代碼寫法實例

使用 FFmpeg 進行簡單的視頻編輯非常強大。它是一個命令行工具&#xff0c;雖然一開始可能看起來有點復雜&#xff0c;但掌握了基本命令后會非常有用。 以下是一些常見的簡單視頻編輯操作及其 FFmpeg 命令&#xff1a; 1. 剪切視頻 如果你想從一個視頻中剪切出一段&#xff0…

如何使用免費軟件寫論文?六個免費論文生成軟件使用指南

在學術寫作中&#xff0c;利用AI技術和免費的寫作工具可以極大地提高效率&#xff0c;尤其對于需要處理大量文獻、結構化寫作的論文來說&#xff0c;使用合適的軟件能節省時間&#xff0c;提升論文質量。這里為您推薦六個免費的論文生成軟件&#xff0c;并提供使用指南&#xf…

大數據系統架構實踐(二):Hadoop集群部署

大數據系統架構實踐&#xff08;二&#xff09;&#xff1a;Hadoop集群部署 文章目錄 大數據系統架構實踐&#xff08;二&#xff09;&#xff1a;Hadoop集群部署一、Hadoop簡介二、部署前準備三、部署Hadoop集群1. 下載并解壓安裝包2. 配置hadoop-env.sh3. 配置core-site.xml4…

42道Maven高頻題整理(附答案背誦版)

1.簡述什么是Maven&#xff1f; Maven是一個項目管理和構建自動化工具&#xff0c;主要服務于Java項目。使用Maven&#xff0c;開發者可以方便地管理項目的構建、文檔生成、報告、依賴、SCM&#xff08;軟件配置管理&#xff09;、發布和分發等過程。 Maven的核心概念是基于項…

【數字后端】- 如何進行時鐘樹綜合?

首先&#xff0c;要明確的是&#xff0c;時鐘樹綜合只有命令去操作這一種方式 CTS的步驟 1、時鐘樹綜合前的準備工作-設置時鐘樹cell&#xff08;每個項目必做&#xff09; 最簡單的項目要設置生長時鐘樹時可用的clock buffer和clock inverter cell list&#xff0c;如下 此…