gRPC + Spring Boot实战:微服务高性能通信从入门到落地

一、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>
        <artifactId>grpc-spring-boot-starter</artifactId>
        <version>3.1.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
        <version>1.62.2</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
        <version>1.62.2</version>
    </dependency>
</dependencies>

<build>
    <extensions>
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>1.7.1</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>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(单向)      双向流

十、最佳实践

  1. Proto版本管理:使用buf工具管理Proto文件和Breaking Change检测
  2. 错误处理:用gRPC Status Code替代业务异常,保持语义一致
  3. 超时设置:Deadline传播,避免级联超时
  4. 负载均衡:结合Nacos/Consul实现服务发现+客户端负载均衡
  5. 拦截器:用gRPC Interceptor实现认证、日志、链路追踪

十一、总结

gRPC + Spring Boot是微服务高性能通信的最佳实践。通过grpc-spring-boot-starter,Spring Boot开发者可以像写普通Service一样实现gRPC服务。四种通信模式(Unary、Server Stream、Client Stream、Bidirectional Stream)覆盖了几乎所有微服务交互场景。

文章摘自:https://www.cnblogs.com/czlws/p/19853464/grpc-spring-boot-microservice-tutorial