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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…