Spring Boot限流方案

考慮到應用系統可能會遭受惡意的流量衝擊或者是突發的高並發請求,我們需要實現對系統資源的限流操作,以確保系統優雅的處理請求。Spring Boot限流是從監控分析,性能調優出發,阻止非法請求,控制並發,保障系統可用以及數據安全等方面都能給出解答,下面從框架、降級、限流器、方案、組件、插件、redis、註解、springcloud限流組件選取等方面進行詳細的闡述。

一、Spring Boot限流框架

Spring Boot限流框架可以分為兩類: 基於外部組件的限流和基於自研組件的限流。

基於外部組件的常見限流框架:Netflix Hystrix、阿里Sentinel,銀聯OPS、京東Cat等;

基於自研組件的限流框架: Rate Limiter、Bucket4J等。

Netflix Hystrix是一種基於線程和信號模型的隔離器,用於延遲和故障容錯,主要是按照一定規則對訪問服務的進行限流限速或者降級處理。阿里Sentinel是一款優秀的開源API高可用保護框架,提供外部的流量控制、降級、熔斷和系統負載等保護能力。銀聯OPS支持依據多種指標實現對分散式系統般的限流,結果百分比統計;京東Cat則是用於監控和管理大規模分散式系統的開源框架。

二、Spring Boot限流降級

由於流量太大等情況,甚至會導致系統崩潰,所以需要在限流失敗的時候進行如何優雅的降級處理。Spring Boot限流降級措施包括:

– 快速失敗:當請求超過限流閾值時,快速直接給出失敗響應;
– 返回靜態響應:當請求超過閾值時,返回預設的靜態響應內容;
– 返回動態降級:當請求超過閾值時,根據實際情況動態降級,例如關閉某個功能,降低返回結果精度等手段。

三、Spring Boot限流器

限流器是Spring Boot限流體系中的重要組件之一,管控著系統並發訪問或流量的統計和流量的控制等。他是限流的精華,那麼知道Java中主流的限流的實現方式,可以分為以下幾種:

– 計數器演算法:最簡單常見限流演算法,通過一個計數器和閾值來控制訪問頻率;
– 漏桶演算法:控制速率,通過不斷向漏桶中放水來限流;
– 令牌桶演算法:控制速率,每過來一個請求就消耗一個令牌。

四、Spring Boot限流方案

Spring Boot限流方案包括限流線程池、令牌桶流控和漏桶流控。

五、Spring Boot限流組件

目前常用的Spring Boot限流組件有Sentinel,Hystrix等。

Sentinel是一個全面的流量管理框架,主要是從流量控制和熔斷機制來控制流量,可以及時響應和處理,方便做到及時恢復。Hystrix 是Netflix開發的一款容錯框架,以線程隔離或者信號量模式對不同的依賴請求進行隔離,從而限制請求量。其流量控制是依靠分散式線程池來實現的,非常強大和靈活。

六、Spring Boot限流插件

限流插件可以對Dubbo服務進行流量控制,基於 dubbo的TokenBucket做到對服務限流;另外還有apollo、sentinel等流控組件,可以結合Spring Boot進行使用。

七、Spring Boot限流設置

可以通過屬性設置或代碼設置兩種方式來實現Spring Boot限流設置。屬性配置示例代碼如下:

“`
# 配置Sentinel流控規則
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds1.nacos.data-id=${spring.application.name}-sentinel
spring.cloud.sentinel.datasource.ds1.nacos.group-id=SENTINEL_GROUP

spring.cloud.sentinel.filter.order=0
“`

通過代碼動態設置限流規則示例代碼如下:

“`
// Sentinel控制台的”應用名稱”
String application = “myApp”;

// 需要流控的服務名稱,按 application:serviceName 格式拼接
String resource = application + “:” + “someService”;

// 配置項名稱,多個配置項可用”,”隔開
String param = “timeout”

// 1
// 手動添加管制規則
FlowRule rule = new FlowRule();
rule.setResource(resource);
rule.setCount(10);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp(“default”);
FlowRuleManager.loadRules(Collections.singletonList(rule));

// 2
// 手動更新管制規則
FlowRule rule = new FlowRule();
rule.setResource(resource);
rule.setCount(20);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp(“default”);
FlowRuleManager.loadRules(Collections.singletonList(rule));
“`

八、Spring Boot限流註解

可以使用@RateLimit註解實現方法限流,示例代碼如下:

“`
@GetMapping(“/test”)
@RateLimit(key=”userId”, time = 1, count = 10, msg=”操作過於頻繁,請稍後再試”)
public void test(@RequestParam String userId) {
System.out.println(“test”);
}
“`

九、Spring Boot限流Redis

可以使用Redis實現限流,存儲規則訪問次數與過期時間相結合,示例代碼如下:

“`
//根據ip限流
@RequestMapping(“/test”)
public String test(@RequestParam String ip)throws Exception{
String luaScript = “local key = KEYS[1]\n” +
“local limit = tonumber(ARGV[1])\n” +
“local expireTimeMS = tonumber(ARGV[2])\n” +
“local curLimit = tonumber(redis.call(‘get’, key) or ‘0’)\n” +
“if curLimit + 1 > limit then return 0 end\n” +
“redis.call(‘INCRBY’, key, 1)\n” +
“redis.call(‘pexpire’, key, expireTimeMS)\n” +
“return 1”;
Jedis jedis = jedisPool.getResource();
try {
String limitCount= jedis.eval(luaScript, Collections.singletonList(“Ip_Limit:” + ip),
Collections.singletonList(“1000”),
Collections.singletonList(“60”), Integer.toString(1000*60)).toString();
if(“0”.equals(limitCount)){
return “訪問過於頻繁”;
}
//正常返回
}finally {
jedis.close();
}
}
“`

十、Spring Cloud限流組件選取

Spring Cloud全家桶中的限流組件包括Gateway、Zuul,可以結合具體業務場景進行選取和使用。

十一、總結

本文對Spring Boot限流進行了詳細的闡述,從框架、降級、限流器、方案、組件、插件、redis、註解、Spring Cloud限流組件等方面展開講解,期望能對讀者有所啟示。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/157479.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-18 20:00
下一篇 2024-11-18 20:00

相關推薦

發表回復

登錄後才能評論