← 返回首页

gRPC实战教程

📂 java ⏱ 2 min 270 words

gRPC实战教程

gRPC是Google开源的高性能RPC框架,基于HTTP/2和Protobuf实现高效的跨语言服务通信。

Protobuf定义

// user.proto
syntax = "proto3";
package com.example.user;
option java_package = "com.example.user.proto";
option java_multiple_files = true;

service UserService {
    rpc GetUser(GetUserRequest) returns (UserResponse);
    rpc ListUsers(ListUsersRequest) returns (stream UserResponse);
    rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}

message GetUserRequest {
    string user_id = 1;
}

message UserResponse {
    string user_id = 1;
    string name = 2;
    string email = 3;
    int32 age = 4;
}

message ListUsersRequest {
    int32 page_size = 1;
    string page_token = 2;
}

message ChatMessage {
    string sender = 1;
    string content = 2;
    int64 timestamp = 3;
}

服务端实现

@GrpcService
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {
    @Autowired
    private UserMapper userMapper;

    // 一元调用
    @Override
    public void getUser(GetUserRequest request,
                        StreamObserver<UserResponse> responseObserver) {
        User user = userMapper.findById(request.getUserId());
        if (user == null) {
            responseObserver.onError(Status.NOT_FOUND
                .withDescription("User not found")
                .asRuntimeException());
            return;
        }
        responseObserver.onNext(toProto(user));
        responseObserver.onCompleted();
    }

    // 服务端流式
    @Override
    public void listUsers(ListUsersRequest request,
                          StreamObserver<UserResponse> responseObserver) {
        List<User> users = userMapper.findByPage(
            request.getPageSize(), request.getPageToken());
        for (User user : users) {
            responseObserver.onNext(toProto(user));
        }
        responseObserver.onCompleted();
    }
}

客户端调用

@Service
@RequiredArgsConstructor
public class GrpcClientService {
    private final UserGrpc.UserStub userStub;

    // 一元调用
    public User getUser(String userId) {
        CompletableFuture<UserResponse> future = new CompletableFuture<>();
        userStub.getUser(
            GetUserRequest.newBuilder().setUserId(userId).build(),
            new StreamObserver<>() {
                @Override
                public void onNext(UserResponse response) {
                    future.complete(response);
                }
                @Override
                public void onError(Throwable t) {
                    future.completeExceptionally(t);
                }
                @Override
                public void onCompleted() {}
            });
        return toEntity(future.get(5, TimeUnit.SECONDS));
    }

    // 双向流式
    public void startChat(StreamObserver<ChatMessage> responseObserver) {
        StreamObserver<ChatMessage> requestObserver =
            userStub.chat(responseObserver);
        // 发送消息
        requestObserver.onNext(ChatMessage.newBuilder()
            .setSender("client").setContent("hello").build());
    }
}

四种通信模式

模式 客户端 服务端 适用场景
一元RPC 1个请求 1个响应 普通API调用
服务端流式 1个请求 N个响应 数据推送、实时行情
客户端流式 N个请求 1个响应 文件上传、批量提交
双向流式 N个请求 N个响应 聊天、实时同步

Spring Boot配置

grpc:
  server:
    port: 9090
  client:
    address: 'discovery:///user-service'
    negotiationType: plaintext

小结

gRPC基于HTTP/2和Protobuf,提供高性能、强类型的跨语言RPC通信能力。