马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一、gRPC简介
gRPC是Google开源的高性能RPC框架,基于HTTP/2和Protocol Buffers,支持双向流、多语言代码天生。相比REST JSON,gRPC序列化体积小3-5倍,耽误低沉30%以上,是微服务间通讯的首选方案。
二、项目布局
- grpc-demo/
- ├── grpc-api/ # Proto定义 + 生成代码
- │ └── src/main/proto/
- │ └── user.proto
- ├── grpc-server/ # 服务端
- └── grpc-client/ # 客户端
复制代码 三、Proto文件界说
- syntax = "proto3";
- package com.example.grpc;
- option java_package = "com.example.grpc.user";
- option java_outer_classname = "UserProto";
- service UserService {
- rpc GetUser (GetUserRequest) returns (GetUserResponse);
- rpc ListUsers (ListUsersRequest) returns (stream GetUserResponse);
- rpc CreateUser (stream CreateUserRequest) returns (CreateUserBatchResponse);
- rpc Chat (stream ChatMessage) returns (stream ChatMessage);
- }
- message GetUserRequest {
- int32 id = 1;
- }
- message GetUserResponse {
- int32 id = 1;
- string name = 2;
- string email = 3;
- int32 age = 4;
- }
- message ListUsersRequest {
- int32 page = 1;
- int32 size = 2;
- }
- message CreateUserRequest {
- string name = 1;
- string email = 2;
- int32 age = 3;
- }
- message CreateUserBatchResponse {
- int32 count = 1;
- repeated GetUserResponse users = 2;
- }
- message ChatMessage {
- string from = 1;
- string message = 2;
- }
复制代码 四、Maven依赖设置
- <dependencies>
- <dependency>
- <groupId>net.devh</groupId>
- grpc-spring-boot-starter</artifactId>
- <version>3.1.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>io.grpc</groupId>
- grpc-protobuf</artifactId>
- <version>1.62.2</version>
- </dependency>
- <dependency>
- <groupId>io.grpc</groupId>
- grpc-stub</artifactId>
- <version>1.62.2</version>
- </dependency>
- </dependencies>
- <build>
- <extensions>
- <extension>
- <groupId>kr.motd.maven</groupId>
- os-maven-plugin</artifactId>
- <version>1.7.1</version>
- </extension>
- </extensions>
- <plugins>
- <plugin>
- <groupId>org.xolstice.maven.plugins</groupId>
- protobuf-maven-plugin</artifactId>
- <version>0.6.1</version>
- <configuration>
- <protocArtifact>com.google.protobuf:protoc:3.25.3:exe:${os.detected.classifier}</protocArtifact>
- <pluginId>grpc-java</pluginId>
- <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.62.2:exe:${os.detected.classifier}</pluginArtifact>
- </configuration>
- <executions>
- <execution>
- <goals><goal>compile</goal><goal>compile-custom</goal></goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
复制代码 五、服务端实现
- @GrpcService
- public class UserGrpcService extends UserServiceGrpc.UserServiceImplBase {
- @Autowired
- private UserRepository userRepository;
- @Override
- public void getUser(GetUserRequest request, StreamObserver<GetUserResponse> responseObserver) {
- User user = userRepository.findById(request.getId())
- .orElseThrow(() -> new StatusRuntimeException(
- Status.NOT_FOUND.withDescription("User not found")));
- responseObserver.onNext(toResponse(user));
- responseObserver.onCompleted();
- }
- @Override
- public void listUsers(ListUsersRequest request,
- StreamObserver<GetUserResponse> responseObserver) {
- List<User> users = userRepository.findAll(
- PageRequest.of(request.getPage(), request.getSize())).getContent();
- for (User user : users) {
- responseObserver.onNext(toResponse(user));
- }
- responseObserver.onCompleted();
- }
- @Override
- public StreamObserver<CreateUserRequest> createUser(
- StreamObserver<CreateUserBatchResponse> responseObserver) {
- return new StreamObserver<CreateUserRequest>() {
- List<User> created = new ArrayList<>();
- public void onNext(CreateUserRequest req) {
- User user = new User(req.getName(), req.getEmail(), req.getAge());
- created.add(userRepository.save(user));
- }
- public void onError(Throwable t) { }
- public void onCompleted() {
- CreateUserBatchResponse resp = CreateUserBatchResponse.newBuilder()
- .setCount(created.size())
- .addAllUsers(created.stream().map(u -> toResponse(u)).collect(Collectors.toList()))
- .build();
- responseObserver.onNext(resp);
- responseObserver.onCompleted();
- }
- };
- }
- private GetUserResponse toResponse(User user) {
- return GetUserResponse.newBuilder()
- .setId(user.getId()).setName(user.getName())
- .setEmail(user.getEmail()).setAge(user.getAge()).build();
- }
- }
复制代码 六、客户端调用
- @Service
- public class UserGrpcClient {
- @GrpcClient("user-service")
- private UserServiceGrpc.UserServiceBlockingStub blockingStub;
- @GrpcClient("user-service")
- private UserServiceGrpc.UserServiceStub asyncStub;
- public GetUserResponse getUser(int id) {
- return blockingStub.getUser(GetUserRequest.newBuilder().setId(id).build());
- }
- public List<GetUserResponse> listUsers(int page, int size) {
- List<GetUserResponse> result = new ArrayList<>();
- Iterator<GetUserResponse> it = blockingStub.listUsers(
- ListUsersRequest.newBuilder().setPage(page).setSize(size).build());
- while (it.hasNext()) { result.add(it.next()); }
- return result;
- }
- public void createUserBatch(List<CreateUserRequest> requests) {
- StreamObserver<CreateUserBatchResponse> observer = new StreamObserver<CreateUserBatchResponse>() {
- public void onNext(CreateUserBatchResponse resp) {
- System.out.println("Created " + resp.getCount() + " users");
- }
- public void onError(Throwable t) { t.printStackTrace(); }
- public void onCompleted() { System.out.println("Batch done"); }
- };
- StreamObserver<CreateUserRequest> requestObserver = asyncStub.createUser(observer);
- for (CreateUserRequest req : requests) { requestObserver.onNext(req); }
- requestObserver.onCompleted();
- }
- }
复制代码 七、客户端设置
- # application.yml
- grpc:
- client:
- user-service:
- address: static://localhost:9090
- negotiationType: plaintext
- enableKeepAlive: true
- keepAliveTime: 30s
- keepAliveTimeout: 10s
- server:
- port: 8081
复制代码 八、REST网关集成
- @RestController
- @RequestMapping("/api/users")
- public class UserRestController {
- @Autowired
- private UserGrpcClient grpcClient;
- @GetMapping("/{id}")
- public Map<String, Object> getUser(@PathVariable int id) {
- GetUserResponse resp = grpcClient.getUser(id);
- return Map.of("id", resp.getId(), "name", resp.getName(),
- "email", resp.getEmail(), "age", resp.getAge());
- }
- @GetMapping
- public List<Map<String, Object>> listUsers(
- @RequestParam(defaultValue = "0") int page,
- @RequestParam(defaultValue = "10") int size) {
- return grpcClient.listUsers(page, size).stream()
- .map(r -> Map.of("id", r.getId(), "name", r.getName(),
- "email", r.getEmail(), "age", r.getAge()))
- .collect(Collectors.toList());
- }
- }
复制代码 九、性能对比
- 指标 REST/JSON gRPC/Protobuf
- -----------------------------------------------
- 序列化体积 ~2.1KB ~0.4KB
- 平均延迟 45ms 12ms
- QPS (单连接) ~3,200 ~9,500
- CPU占用 高 低
- 代码生成 无 自动
- 流式支持 SSE(单向) 双向流
复制代码 十、最佳实践
- Proto版本管理:利用buf工具管理Proto文件和Breaking Change检测
- 错误处置处罚:用gRPC Status Code更换业务非常,保持语义划一
- 超时设置:Deadline流传,克制级联超时
- 负载平衡:团结Nacos/Consul实现服务发现+客户端负载平衡
- 拦截器:用gRPC Interceptor实现认证、日记、链路追踪
十一、总结
gRPC + Spring Boot是微服务高性能通讯的最佳实践。通过grpc-spring-boot-starter,Spring Boot开发者可以像写平凡Service一样实现gRPC服务。四种通讯模式(Unary、Server Stream、Client Stream、Bidirectional Stream)覆盖了险些全部微服务交互场景。
免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金. |