引言
基于前文的雪花ID解决方案------需要RPC部署,我就来写一个怎么部署gRPC,并整合到springboot中吧。
一、系统架构概览
1.1 整体架构图
yaml
┌─────────────────────────────────────────────────────────┐
│ 业务微服务集群 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 用户服务 │ │ 订单服务 │ │ 商品服务 │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
└─────────┼────────────────┼────────────────┼───────────┘
│ │ │
│ gRPC调用 │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ 负载均衡器 (K8s Service) │
└─────────────────────┬───────────────────────────────────┘
│ 负载分发
┌────────────────────┼────────────────────────────────────┐
│ ▼ │
│ 雪花ID生成RPC服务集群 (Kubernetes Pods) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pod-1 │ │ Pod-2 │ │ Pod-3 │ │
│ │WorkerId: 1 │ │WorkerId: 2 │ │WorkerId: 3 │ │
│ │HTTP: 8349 │ │HTTP: 8349 │ │HTTP: 8349 │ │
│ │gRPC: 8350 │ │gRPC: 8350 │ │gRPC: 8350 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────┼────────────────────────────────────┘
│
▼
┌─────────────────────┐
│ MySQL数据库 │
│ WORKER_NODE表 │
│ WorkerId管理 │
└─────────────────────┘
1.2 技术栈组成
技术组件 | 版本 | 作用 |
---|---|---|
Spring Boot | 2.x | 应用框架,服务启动和依赖管理 |
gRPC | 1.53.0 | 高性能RPC通信协议 |
Protocol Buffers | 3.21.12 | 序列化协议和接口定义 |
grpc-spring-boot-starter | 2.15.0.RELEASE | gRPC与Spring Boot集成 |
MySQL | 8.0+ | WorkerId持久化存储 |
Kubernetes | 1.20+ | 容器编排和服务发现 |
Maven | 3.6+ | 项目构建和依赖管理 |
二、模块化架构设计
2.1 项目结构
bash
open-cloud-common-snowflake/
├── pom.xml # 父级Maven配置
├── GRPC_USAGE_GUIDE.md # gRPC使用指南
├── open-cloud-snowflake-lib/ # 公共库模块
│ ├── pom.xml # lib模块Maven配置
│ └── src/main/proto/
│ └── snowflake.proto # Protocol Buffer定义
├── open-cloud-snowflake-server/ # 服务端模块
│ ├── pom.xml # server模块Maven配置
│ ├── README.md # 服务端说明
│ ├── K8S_API_TESTING_GUIDE.md # K8s测试指南
│ └── src/main/java/com/opencloud/snowflake/server/
│ ├── SnowFlakeApplication.java # Spring Boot启动类
│ ├── grpc/
│ │ └── SnowflakeGeneratorGrpcService.java # gRPC服务实现
│ ├── config/
│ │ ├── GrpcServerPerformanceConfig.java # gRPC性能配置
│ │ └── SimpleGrpcServerConfig.java # 简化gRPC配置
│ └── service/
│ └── Impl/GeneratorService.java # 业务服务实现
├── open-cloud-snowflake-client/ # 客户端模块
│ ├── pom.xml # client模块Maven配置
│ ├── README.md # 客户端说明
│ ├── README-CONNECTION-POOL.md # 连接池说明
│ └── src/main/java/com/opencloud/snowflake/client/
│ ├── SnowflakeGrpcClient.java # gRPC客户端
│ ├── pool/
│ │ └── SnowflakeGrpcConnectionPool.java # 连接池实现
│ ├── config/
│ │ └── SnowflakeClientProperties.java # 客户端配置
│ └── util/
│ └── RpcSnowflakeUtil.java # 工具类
└── open-cloud-snowflake-starter/ # 自动配置模块
└── src/main/resources/
└── META-INF/spring.factories # 自动配置
2.2 模块职责划分
open-cloud-snowflake-lib (公共库)
功能定位: 提供gRPC接口定义和通用数据结构
核心文件:
java
// snowflake.proto - Protocol Buffer定义
syntax = "proto3";
package snowflake;
service SnowflakeGenerator {
// 生成单个ID
rpc GenerateId (GenerateIdRequest) returns (GenerateIdResponse) {}
// 批量生成ID
rpc GenerateBatchIds (GenerateBatchRequest) returns (GenerateBatchResponse) {}
// 高级批量生成
rpc GenerateBatchIdsAdvanced (GenerateBatchAdvancedRequest) returns (GenerateBatchResponse) {}
// 获取生成器状态
rpc GetGeneratorStatus (GeneratorStatusRequest) returns (GeneratorStatusResponse) {}
// 性能基准测试
rpc Benchmark (BenchmarkRequest) returns (BenchmarkResponse) {}
// WorkerId管理接口(Pod感知)
rpc RegisterWorker (RegisterWorkerRequest) returns (RegisterWorkerResponse) {}
rpc GetWorkerInfo (GetWorkerInfoRequest) returns (GetWorkerInfoResponse) {}
rpc UnregisterWorker (UnregisterWorkerRequest) returns (UnregisterWorkerResponse) {}
}
编译产物:
- 自动生成的Java gRPC存根类
- 消息类和构建器
- 服务接口定义
open-cloud-snowflake-server (服务端)
功能定位: 提供gRPC雪花ID生成服务的完整实现
核心组件:
- SpringBoot应用主类
java
@EnableCaching
@EnableConfigurationProperties
@EnableQxIDGenerator // 启用雪花ID生成器
@SpringBootApplication(scanBasePackages = {"com.opencloud.snowflake"})
@MapperScan("com.opencloud.snowflake.server.mapper")
public class SnowFlakeApplication {
public static void main(String[] args) {
SpringApplication.run(SnowFlakeApplication.class, args);
}
}
- gRPC服务实现
java
@GrpcService
public class SnowflakeGeneratorGrpcService extends SnowflakeGeneratorGrpc.SnowflakeGeneratorImplBase {
@Autowired
private GeneratorService generatorService;
@Override
public void generateId(GenerateIdRequest request, StreamObserver<GenerateIdResponse> responseObserver) {
try {
long id = generatorService.generate();
responseObserver.onNext(GenerateIdResponse.newBuilder()
.setSuccess(true)
.setId(id)
.setTimestamp(System.currentTimeMillis())
.build());
responseObserver.onCompleted();
} catch (Exception e) {
// 错误处理
}
}
}
- gRPC性能配置
java
@Configuration
public class GrpcServerPerformanceConfig {
@Value("${grpc.server.port:8350}")
private int port;
@Value("${grpc.server.max-inbound-message-size:1KB}")
private DataSize maxInboundMessageSize;
// 性能优化配置监控和建议
}
open-cloud-snowflake-client (客户端)
功能定位: 提供调用gRPC服务的客户端SDK和连接池优化
核心特性:
- 智能连接池
java
@Component
public class SnowflakeGrpcConnectionPool implements InitializingBean, DisposableBean {
// 连接池核心组件
private final ConcurrentLinkedQueue<ManagedChannel> availableChannels = new ConcurrentLinkedQueue<>();
private final ConcurrentHashMap<String, ManagedChannel> activeChannels = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Object> stubCache = new ConcurrentHashMap<>();
// 性能监控指标
private final AtomicInteger totalConnections = new AtomicInteger(0);
private final AtomicLong totalRequests = new AtomicLong(0);
private final AtomicLong successfulRequests = new AtomicLong(0);
}
- 客户端配置管理
java
@ConfigurationProperties(prefix = "snowflake.client")
public class SnowflakeClientProperties {
private String host = "localhost";
private int port = 8350;
private long connectTimeout = 10000;
private boolean enableTls = false;
private int maxInboundMessageSize = 4 * 1024 * 1024;
}
三、gRPC集成实现细节
3.1 基于grpc-spring-boot-starter的集成
Maven依赖配置:
xml
<!-- 服务端依赖 -->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>2.15.0.RELEASE</version>
</dependency>
<!-- 客户端依赖 -->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-starter</artifactId>
<version>2.15.0.RELEASE</version>
</dependency>
<!-- Protocol Buffers编译插件 -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
</plugin>
3.2 自动服务发现与注册
@GrpcService注解自动注册:
java
@GrpcService // 自动注册为gRPC服务
public class SnowflakeGeneratorGrpcService extends SnowflakeGeneratorGrpc.SnowflakeGeneratorImplBase {
// 服务实现会被自动发现并注册到gRPC服务器
}
配置文件驱动的服务配置:
yaml
# bootstrap.yml - gRPC服务端配置
grpc:
server:
port: 8350 # gRPC服务端口
enable-keep-alive: true
keep-alive-time: 2m
keep-alive-timeout: 20s
max-connection-idle: 5m
max-inbound-message-size: 1KB # 针对雪花ID优化
max-inbound-metadata-size: 512B
health-service-enabled: true
reflection-service-enabled: true
3.3 Protocol Buffers接口设计
完整的服务接口定义:
java
service SnowflakeGenerator {
// === 核心ID生成接口 ===
rpc GenerateId (GenerateIdRequest) returns (GenerateIdResponse) {}
rpc GenerateBatchIds (GenerateBatchRequest) returns (GenerateBatchResponse) {}
rpc GenerateBatchIdsAdvanced (GenerateBatchAdvancedRequest) returns (GenerateBatchResponse) {}
// === 服务管理接口 ===
rpc GetGeneratorStatus (GeneratorStatusRequest) returns (GeneratorStatusResponse) {}
rpc Benchmark (BenchmarkRequest) returns (BenchmarkResponse) {}
// === WorkerId管理接口(Pod感知扩展)===
rpc RegisterWorker (RegisterWorkerRequest) returns (RegisterWorkerResponse) {}
rpc GetWorkerInfo (GetWorkerInfoRequest) returns (GetWorkerInfoResponse) {}
rpc UnregisterWorker (UnregisterWorkerRequest) returns (UnregisterWorkerResponse) {}
}
消息类型设计:
java
// Pod感知WorkerId注册请求
message RegisterWorkerRequest {
string service_name = 1; // 服务名称
string pod_name = 2; // Pod名称(K8s环境)
string host_name = 3; // 主机名
string client_ip = 4; // 客户端IP
string environment = 5; // 环境标识(k8s/dev/prod)
int64 timestamp = 6; // 注册时间戳
}
// WorkerId注册响应
message RegisterWorkerResponse {
bool success = 1; // 是否成功
int64 worker_id = 2; // 分配的WorkerId
string assigned_port = 3; // 分配的端口标识符
string message = 4; // 成功消息或错误信息
bool is_new_worker = 5; // 是否为新注册的Worker
int64 timestamp = 6; // 响应时间戳
}
4.3 服务启动流程
整合的rpc服务部署运行,其他服务则引入client
端依赖,启动时会经过以下一系列操作。这样设计的目的,在此文已经提到: 分布式ID:基于K8s-PodName的百度雪花ID生成方案优化引言 雪花ID(Snowflake ID)作为分布式系统 - 掘金
为了外部微服务调用rpc服务时,用的workerNode
节点是唯一的。
1. 应用启动序列:
sequenceDiagram
participant K8s as Kubernetes
participant Pod as Pod Container
participant App as Spring Boot App
participant gRPC as gRPC Server
participant DB as MySQL Database
K8s->>Pod: 创建Pod并注入环境变量
Pod->>App: 启动Spring Boot应用
App->>App: 加载配置文件
App->>DB: 连接数据库
App->>App: 初始化WorkerId分配器
App->>DB: 查询/分配WorkerId
App->>gRPC: 启动gRPC服务器
App->>App: 注册健康检查端点
App->>K8s: 就绪状态报告
2. WorkerId分配流程:
java
// KubernetesPodAwareWorkerIdAssigner核心逻辑
@Transactional
public long assignWorkerId() {
// 1. 构建工作节点实体
WorkerNodeEntity workerNodeEntity = buildWorkerNode();
// 2. 调用分配逻辑
return assignWorkerId(workerNodeEntity);
}
private WorkerNodeEntity buildWorkerNode() {
WorkerNodeEntity entity = new WorkerNodeEntity();
// 设置主机名
entity.setHostName(DockerUtils.isDocker() ?
DockerUtils.getDockerHost() : NetUtils.getLocalAddress());
// 核心:使用Pod名称作为端口标识
String portIdentifier = getPortIdentifier();
entity.setPort(portIdentifier);
return entity;
}
private String getPortIdentifier() {
// 1. 优先使用K8s Pod名称
String podName = System.getenv("KUBERNETES_POD_NAME");
if (StringUtils.isNotBlank(podName)) {
return podName;
}
// 2. 降级使用服务名称+时间戳
return serviceName + ":" + System.currentTimeMillis() + "-" + RandomUtils.nextInt(10000);
}
五、高可用与性能优化
5.1 连接池优化
客户端连接池配置:
java
@Component
public class SnowflakeGrpcConnectionPool {
// 连接池配置
@Value("${snowflake.client.pool.max-connections:16}")
private int maxConnections;
@Value("${snowflake.client.pool.min-connections:4}")
private int minConnections;
@Value("${snowflake.client.pool.initial-connections:8}")
private int initialConnections;
// 性能优化配置
@Value("${snowflake.client.max-inbound-message-size:1KB}")
private DataSize maxInboundMessageSize;
@Value("${snowflake.client.keep-alive-time:30s}")
private Duration keepAliveTime;
private ManagedChannel createChannel() {
return ManagedChannelBuilder.forAddress(serverHost, serverPort)
.maxInboundMessageSize(config.getMaxInboundMessageSizeBytes())
.executor(executorService)
.keepAliveTime(config.getKeepAliveTimeSeconds(), TimeUnit.SECONDS)
.keepAliveTimeout(config.getKeepAliveTimeoutSeconds(), TimeUnit.SECONDS)
.keepAliveWithoutCalls(config.isKeepAliveWithoutCalls())
.usePlaintext()
.build();
}
}
5.2 性能监控与指标
gRPC服务端性能配置监控:
java
@Configuration
public class GrpcServerPerformanceConfig {
@PostConstruct
public void printConfigurationInfo() {
log.info("================== gRPC服务器配置监控 ==================");
log.info("📊 系统环境信息:");
log.info(" - CPU核心数: {}", CPU_CORES);
log.info(" - 建议线程数: {} (CPU核心数 × 2)", OPTIMAL_THREADS);
log.info(" - 雪花ID消息大小: ~{}字节", SNOWFLAKE_MESSAGE_SIZE);
log.info("🔧 gRPC服务器配置:");
log.info(" - 服务端口: {}", port);
log.info(" - Keep-Alive启用: {}", enableKeepAlive);
log.info(" - 最大入站消息大小: {}", maxInboundMessageSize);
log.info(" - 健康检查服务: {}", healthServiceEnabled);
}
}
总结
本文档详细介绍了基于gRPC的雪花ID生成服务的完整架构与部署方案。该系统通过模块化设计、Pod感知的WorkerId分配、高性能连接池等技术,实现了高可用、高性能的分布式ID生成服务。
核心优势:
- 模块化架构:lib、server、client分离,职责清晰
- 无缝集成:基于grpc-spring-boot-starter,配置简单
- Pod感知优化:解决Kubernetes环境下的WorkerId冲突
最终测试单机4G、8核QPS:3w/s(未加线程池优化)。 经实践,这个上限推测是机器上限。