grpc 和限流Sentinel

基于gRPC的微服務通信模塊技術方案書

1. 總體架構設計

長連接
gRPC客戶端
gRPC服務端
Sentinel限流
業務邏輯處理
返回響應
輪詢調度器

2. 技術棧說明

組件版本功能
gRPC1.58.0高性能RPC框架
Protocol Buffers3.24.4接口定義與序列化
Sentinel1.8.7流量控制與熔斷降級
Netty4.1.100.Final網絡通信基礎
Spring Boot3.1.5應用框架

3. 詳細設計方案

3.1 gRPC接口定義 (helloworld.proto)

syntax = "proto3";option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "HelloWorldProto";service Greeter {rpc SayHello (HelloRequest) returns (HelloReply) {}
}message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}

3.2 服務端實現

3.2.1 核心組件
包含
使用
實現
GrpcServer
+start() : void
+stop() : void
HelloServiceImpl
+sayHello(HelloRequest) : HelloReply
SentinelInterceptor
+interceptCall(ServerCall, Metadata, ServerCallHandler)
ServerInterceptor
3.2.2 限流配置
參數說明
資源名grpc_service:SayHelloSentinel資源標識
閾值類型QPS每秒請求數
單機閾值2每秒最大請求數
流控效果直接拒絕超限直接返回錯誤

3.3 客戶端實現

3.3.1 連接管理策略
Client ChannelPool gRPC服務端 獲取Channel 返回可用Channel 發起RPC調用 返回響應 歸還Channel Client ChannelPool gRPC服務端
參數說明
連接池大小5最大連接數
空閑超時30分鐘自動關閉空閑連接
心跳間隔60秒保持連接活躍

4. 代碼實現

4.1 依賴配置 (pom.xml)

<dependencies><!-- gRPC --><dependency><groupId>io.grpc</groupId><artifactId>grpc-netty</artifactId><version>1.58.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>1.58.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>1.58.0</version></dependency><!-- Sentinel --><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.8.7</version></dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-grpc</artifactId><version>1.8.7</version></dependency><!-- 連接池 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.11.1</version></dependency>
</dependencies>

4.2 服務端實現

4.2.1 gRPC服務實現 (HelloServiceImpl.java)
public class HelloServiceImpl extends GreeterGrpc.GreeterImplBase {private static final Logger logger = LoggerFactory.getLogger(HelloServiceImpl.class);@Overridepublic void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {String name = request.getName();String message = "Hello, " + name + "!";HelloReply reply = HelloReply.newBuilder().setMessage(message).build();responseObserver.onNext(reply);responseObserver.onCompleted();logger.info("Processed request for: {}", name);}
}
4.2.2 Sentinel攔截器 (SentinelInterceptor.java)
public class SentinelInterceptor implements ServerInterceptor {private static final String RESOURCE_NAME = "grpc_service:SayHello";static {// 初始化限流規則:QPS=2FlowRule rule = new FlowRule();rule.setResource(RESOURCE_NAME);rule.setGrade(RuleConstant.FLOW_GRADE_QPS);rule.setCount(2);rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);FlowRuleManager.loadRules(Collections.singletonList(rule));}@Overridepublic <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,Metadata headers,ServerCallHandler<ReqT, RespT> next) {// 資源名稱根據方法名動態生成String resourceName = RESOURCE_NAME + ":" + call.getMethodDescriptor().getFullMethodName();Entry entry = null;try {entry = SphU.entry(resourceName, EntryType.IN);return next.startCall(call, headers);} catch (BlockException e) {// 限流處理call.close(Status.RESOURCE_EXHAUSTED.withDescription("Request blocked by Sentinel"), new Metadata());return new ServerCall.Listener<>() {};} finally {if (entry != null) {entry.exit();}}}
}
4.2.3 gRPC服務啟動器 (GrpcServer.java)
public class GrpcServer {private Server server;public void start() throws IOException {int port = 50051;server = ServerBuilder.forPort(port).addService(new HelloServiceImpl()).intercept(new SentinelInterceptor()) // 添加Sentinel攔截器.build().start();Runtime.getRuntime().addShutdownHook(new Thread(() -> {GrpcServer.this.stop();}));}public void stop() {if (server != null) {server.shutdown();}}public void blockUntilShutdown() throws InterruptedException {if (server != null) {server.awaitTermination();}}
}

4.3 客戶端實現

4.3.1 連接池管理 (ChannelPoolFactory.java)
public class ChannelPoolFactory {private static final GenericObjectPool<ManagedChannel> channelPool;static {PooledObjectFactory<ManagedChannel> factory = new BasePooledObjectFactory<>() {@Overridepublic ManagedChannel create() {return ManagedChannelBuilder.forAddress("localhost", 50051).usePlaintext().idleTimeout(30, TimeUnit.MINUTES) // 30分鐘空閑超時.keepAliveTime(60, TimeUnit.SECONDS) // 60秒心跳.build();}@Overridepublic PooledObject<ManagedChannel> wrap(ManagedChannel channel) {return new DefaultPooledObject<>(channel);}@Overridepublic void destroyObject(PooledObject<ManagedChannel> p) {p.getObject().shutdown();}};GenericObjectPoolConfig<ManagedChannel> config = new GenericObjectPoolConfig<>();config.setMaxTotal(5); // 最大連接數config.setMinIdle(1);  // 最小空閑連接config.setMaxWaitMillis(3000); // 獲取連接超時時間channelPool = new GenericObjectPool<>(factory, config);}public static ManagedChannel getChannel() throws Exception {return channelPool.borrowObject();}public static void returnChannel(ManagedChannel channel) {channelPool.returnObject(channel);}
}
4.3.2 客戶端輪詢邏輯 (GrpcClient.java)
public class GrpcClient {private static final Random random = new Random();private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);public static void main(String[] args) {// 啟動10個客戶端線程模擬并發for (int i = 0; i < 10; i++) {scheduler.scheduleAtFixedRate(() -> makeRequest(), 0, 500 + random.nextInt(1500), TimeUnit.MILLISECONDS);}}private static void makeRequest() {ManagedChannel channel = null;try {channel = ChannelPoolFactory.getChannel();GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);HelloRequest request = HelloRequest.newBuilder().setName("Client-" + Thread.currentThread().getId()).build();try {HelloReply response = stub.sayHello(request);System.out.printf("[%s] Received: %s%n", Thread.currentThread().getName(), response.getMessage());} catch (StatusRuntimeException e) {if (e.getStatus().getCode() == Status.Code.RESOURCE_EXHAUSTED) {System.err.printf("[%s] Request blocked by rate limiting%n", Thread.currentThread().getName());} else {e.printStackTrace();}}} catch (Exception e) {e.printStackTrace();} finally {if (channel != null) {ChannelPoolFactory.returnChannel(channel);}}}
}

5. 性能優化策略

5.1 連接管理優化

策略實現方式效果
連接預熱啟動時創建最小空閑連接避免首次請求延遲
動態擴容監控連接等待隊列自動增加連接池大小
健康檢查定期ping空閑連接及時發現失效連接

5.2 Sentinel高級配置

// 添加熱點參數限流
ParamFlowRule rule = new ParamFlowRule(RESOURCE_NAME).setParamIdx(0) // 第一個參數.setCount(5).setGrade(RuleConstant.FLOW_GRADE_QPS).setDurationInSec(1).setParamFlowItemList(Collections.singletonList(new ParamFlowItem().setObject("highPriority").setClassType(String.class.getName()).setCount(10)));
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));

5.3 監控與告警

Metrics
Logs
gRPC服務
Prometheus
Grafana
ELK
告警

監控指標:

  1. 請求QPS與響應時間
  2. 限流拒絕次數
  3. 連接池使用率
  4. 線程池活躍度

6. 部署方案

6.1 容器化部署 (Dockerfile)

FROM openjdk:17-jdk-slimWORKDIR /appCOPY target/grpc-service.jar /app/app.jarEXPOSE 50051ENTRYPOINT ["java", "-jar", "app.jar"]

6.2 Kubernetes部署 (deployment.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:name: grpc-service
spec:replicas: 3selector:matchLabels:app: grpc-servicetemplate:metadata:labels:app: grpc-servicespec:containers:- name: grpc-serviceimage: registry.example.com/grpc-service:1.0.0ports:- containerPort: 50051resources:limits:memory: "512Mi"cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:name: grpc-service
spec:selector:app: grpc-serviceports:- protocol: TCPport: 50051targetPort: 50051

7. 測試方案

7.1 性能測試腳本 (test.sh)

#!/bin/bash# 啟動服務端
java -jar grpc-server.jar &# 等待服務啟動
sleep 5# 啟動客戶端測試
for i in {1..10}
dojava -jar grpc-client.jar > client-$i.log &
done# 監控限流情況
watch -n 1 "grep 'blocked' *.log | wc -l"

7.2 測試結果驗證

測試場景預期結果驗證方法
正常請求(QPS<2)全部成功響應成功率100%
限流觸發(QPS>2)部分拒絕錯誤日志包含"blocked"
長連接保持連接復用連接創建日志次數<請求次數
高并發壓力服務穩定CPU/內存波動在安全范圍

8. 項目優勢總結

  1. 高性能通信:基于gRPC HTTP/2協議,支持多路復用和頭部壓縮
  2. 精準流量控制:Sentinel實現毫秒級QPS限流
  3. 資源高效利用:連接池管理減少TCP握手開銷
  4. 彈性擴展:無狀態設計支持水平擴展
  5. 生產就緒:集成健康檢查、指標監控等生產級特性

部署說明:項目啟動順序為:1. 啟動gRPC服務端 2. 啟動gRPC客戶端。Sentinel限流規則會在服務端啟動時自動初始化。

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

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

相關文章

經典灰狼算法+編碼器+雙向長短期記憶神經網絡,GWO-Transformer-BiLSTM多變量回歸預測,作者:機器學習之心!

經典灰狼算法編碼器雙向長短期記憶神經網絡&#xff0c;GWO-Transformer-BiLSTM多變量回歸預測&#xff0c;作者&#xff1a;機器學習之心&#xff01; 目錄 經典灰狼算法編碼器雙向長短期記憶神經網絡&#xff0c;GWO-Transformer-BiLSTM多變量回歸預測&#xff0c;作者&#…

VGG Image Annotator (VIA):一款免費的數據標注軟件介紹與使用

VGG Image Annotator (VIA)&#xff1a;一款免費的數據標注軟件介紹與使用 在計算機視覺領域&#xff0c;數據標注是訓練機器學習模型的基礎步驟之一&#xff0c;而標注工具的選擇直接影響標注的效率和準確性。眾多標注工具中&#xff0c;VGG Image Annotator (VIA) 是一個開源…

CSS實現百分比水柱圖

背景 在echarts沒發現有可以直接使用的展示百分比的柱形圖,只好自己封裝一個組件使用 實現思路 一、圖形拆解 要實現的組件是一個 可配置的圓柱形液柱圖組件&#xff0c;常用于展示比例進度&#xff0c;比如任務完成度、指標達成率等。把圖拆成最小單元然后拼接起來&#x…

詳解 rzsz 工具:Windows 與 Linux 文件傳輸

&#xff08;Linux之軟件包管理器&#xff08;CentOS系統&#xff09; —— yum-CSDN博客&#xff09;rzsz工具之前我在這篇文章中介紹過&#xff0c;現在重新詳細介紹一下該工具。rzsz 是一個用于在 Windows 和 Linux 系統之間傳輸文件的工具集&#xff0c;通常通過終端模擬器…

網絡編程1(UDP)

網絡編程套接字&#xff08;socket api&#xff09; 了解了網絡的一些概念&#xff0c;接下來就要進行網絡中的跨主機通信&#xff0c;了解網絡中的一些API&#xff0c;這里談到的API都是針對傳輸層進行的&#xff0c;這是因為我們編寫的代碼是在應用層&#xff0c;而傳輸層就…

【電機】定點線性映射

這是一個定點數線性映射的問題&#xff0c;通常用于將浮點型的物理量&#xff08;如速度、位置、扭矩&#xff09;轉換為嵌入式系統中使用的整型數據格式&#xff0c;便于通過 CAN 總線或其它通信協議發送給電機控制器。 我們來逐步解析這個過程&#xff0c;并以“速度”為例說…

Spring Cloud 微服務(遠程調用與熔斷機制深度解析)

&#x1f4cc; 摘要 在微服務架構中&#xff0c;服務之間的遠程調用是構建分布式系統的核心環節。然而&#xff0c;隨著服務數量的增加和網絡復雜度的提升&#xff0c;調用失敗、延遲高、異常等問題變得越來越頻繁。 為此&#xff0c;Spring Cloud 提供了強大的遠程調用組件 …

electron-vite 抽離config.js

1、將config.js 放到resources下的config目錄下 module.exports {url: http://192.168.1.17:8000,wsUrl: ws://192.168.1.17:8000, }2、在preload.js 暴露讀取API src/preload/index.js(或你的preload入口) const fs require(fs); const path require(path);function getCo…

MySQL Undo Log 深度解析:事務回滾與MVCC的核心功臣

引言 作為MySQL的“數據后悔藥”和“歷史版本檔案館”&#xff0c;Undo Log&#xff08;回滾日志&#xff09;在事務處理和并發控制中扮演著至關重要的角色。今天咱們就從底層原理出發&#xff0c;結合實際場景&#xff0c;把Undo Log的“里里外外”說個明白&#xff01; 一、…

gin如何返回html

? 方法一&#xff1a;直接返回 HTML 字符串 這種方式適合簡單場景&#xff0c;比如返回一段固定的 HTML 內容。 package mainimport "github.com/gin-gonic/gin"func main() {r : gin.Default()r.GET("/html", func(c *gin.Context) {htmlContent : <…

Insulation score算法解讀

Insulation score&#xff08;IS&#xff09;&#xff0c;俗稱絕緣分數&#xff0c;用于計算識別三維基因組中的拓撲關聯結構域TAD。 首次提出是在&#xff1a; 1&#xff0c;概念 為染色體上的基因組區間分配‘絕緣評分’的方法。該評分用于衡量跨越每個區間的所有相互作用的…

電腦系統重裝有什么用?

一、解決系統軟件問題 1、修復系統崩潰與錯誤 系統出現頻繁藍屏、死機、啟動失敗或程序運行異常&#xff08;如驅動沖突、系統文件損壞&#xff09; 2、清除惡意軟件與病毒 電腦中病毒或惡意軟件難以通過殺毒軟件徹底清除 二、優化系統性能 1、清理冗余文件與設置 長時間…

js隨機生成一個顏色

在 JavaScript 中&#xff0c;隨機生成顏色有多種方式&#xff0c;以下是最常見的幾種實現方法&#xff1a; 方法1&#xff1a;生成隨機十六進制顏色&#xff08;如 #FFFFFF&#xff09; 這是最常見的方式&#xff0c;生成格式為 #RRGGBB 的顏色字符串&#xff1a; function…

運維打鐵: 服務器防火墻策略配置與管理

文章目錄 思維導圖一、防火墻基礎1. 防火墻概念2. 常見防火墻類型3. 防火墻工作原理 二、策略配置1. 規則制定原則2. 端口與服務開放Linux 系統&#xff08;以 iptables 為例&#xff09;Windows 系統&#xff08;以 Windows 防火墻為例&#xff09; 3. IP 地址過濾允許特定 IP…

locate 命令更新機制詳解

文章目錄 **一、定時更新的實現載體&#xff1a;crontab 任務****二、定時任務的配置邏輯****三、更新觸發的額外機制****四、更新流程的性能優化****五、常見問題與解決方案****總結** 一、定時更新的實現載體&#xff1a;crontab 任務 Linux 系統通常通過 crontab 定時任務 …

docker部署nacos【單機模式使用mysql,使用.env配置】(更新:2025/7/1~)

視頻 我的個人視頻&#xff0c;有詳細步驟 使用docker部署nacos_嗶哩嗶哩_bilibili 環境 虛擬機&#xff1a;VM&#xff0c;CentOS7 遠程連接工具&#xff1a;MobaXterm 使用工具 隨機生成字符串&#xff1a; 隨機字符串生成器 | 菜鳥工具 Base64編碼&#xff1a; B…

如何安全地清除筆式驅動器

您是否正在尋找安全清除筆式驅動器的方法&#xff1f;如果是的話&#xff0c;您可以從本文中得到4個有效的解決方案。無論您準備出售還是捐贈您的筆式驅動器&#xff0c;您都可以輕松清空筆式驅動器。雖然簡單的刪除似乎就足夠了&#xff0c;但殘留的數據通常可以恢復。因此&am…

信息新技術

目錄 分布式處理基礎 一、基礎概念 二、通信與網絡 三、分布式協調與一致性 四、分布式存儲與數據庫 五、分布式計算框架 六、容錯與高可用 七、負載均衡與調度 八、安全與監控 九、常見分布式系統設計模式 十、典型系統與工具學習 區塊鏈 區塊鏈的核心技術 物聯…

創客匠人解析創始人 IP 定位:從專業度到用戶心智的占領之道

在知識付費領域&#xff0c;創始人 IP 的定位往往決定了商業變現的天花板。創客匠人通過服務 5 萬 知識博主的實踐經驗&#xff0c;揭示了一個核心邏輯&#xff1a;定位的本質不是簡單的標簽設定&#xff0c;而是通過持續提升專業度&#xff0c;以實際成果占領用戶心智。這一過…

詳解Kafka如何保證消息可靠性

Kafka 通過多個環節的精心設計和配置&#xff0c;能夠提供高可靠的消息傳遞保證&#xff0c;最大限度地減少消息丟失的可能性。這需要生產者、Broker 和消費者三方的協同配置才能實現端到端的不丟失。以下是關鍵機制&#xff1a; 一、核心原則&#xff1a;副本機制 (Replicati…