高性能远程通信框架grpc基本使用

文章目录

  • 一、了解grpc
  • 二、关于protobuf
  • 三、试玩grpc
    • 3.1整个工程目录
    • 3.2 proto文件编写
    • 3.3 使用maven protobuf插件转换.proto文件
    • 3.4 Grpc服务端业务实现类
    • 3.5 pom参考
    • 3.6 grpc client调用

一、了解grpc

谷歌开源远程进程调用框架,支持多语言系统间通信,适用于各种分布式系统,使用http2协议并使用protobuf系列化通信数据,高性能。nacos2开始也集成了grpc,用于nacos server与nacos client间通信。grpc还支持了client-server双向流,两个流可独立不阻塞进行连续读写。

二、关于protobuf

如果只是protobuf作为序列化方案,建议使用protostuff(基于protobuf),不用写proto文件。grpc官方的quickstart都是直接使用protobuf,故这里暂不研究是否有grpc+protostuff方案。Java 有maven插件进行proto文件生成Java文件,故不用单独去安装proto了,但proto基本语法还得了解。

三、试玩grpc

官方的quickstart不是基于springboot的,故这里就参考这位大佬的JAVA使用gRPC
,为方便使用,这里server,client都在同一个工程里。如果要分开,则在独立项目中引入grpc-client-spring-boot-starter 等依赖并,并copy需要的类com.example.demo.protogen.UserServiceGrpc,com.example.demo.protogen.User等。

3.1整个工程目录

高性能远程通信框架grpc基本使用_第1张图片

3.2 proto文件编写

proto里放file.proto,message.proto文件如下

syntax = "proto3";

package protogen;
option java_package = "com.example.demo.protogen";

message File {
  string name = 1;
  int32 size = 2;
}
syntax = "proto3";
package protogen;

import "file.proto";

option java_multiple_files = true;
option java_package = "com.example.demo.protogen";

message User {
  reserved 6 to 7;
  reserved "userId2";
  int32 userId = 1;
  string username = 2;
  oneof msg {
    string error = 3;
    int32 code = 4;
  }
  string name = 8;

  UserType userType = 9;
  repeated int32 roles = 10;

  protogen.File file = 11;
  map hobbys = 12;
}

enum UserType {
  UNKNOW = 0;
  ADMIN = 1;
  BUSINESS_USER = 2;
};

service UserService {
  rpc getUser (User) returns (User) {}
  rpc getUsers (User) returns (stream User) {}
  rpc saveUsers (stream User) returns (User) {}
}

service FileService {
  rpc getFile(User) returns(File) {}
}

3.3 使用maven protobuf插件转换.proto文件

protogen里文件都是生成的,插件配置了读取这个目录,并生成到protogen文件夹里。通过点击如图插件按钮实现,protobuf:compile实际是通过proto.exe将.proto文件生成Java文件,除了FileServiceGrpc,UserServiceGrpcprotobuf:compile-custom生成的,其余都是protobuf:compile生成的。

3.4 Grpc服务端业务实现类

UserServiceImpl.java

package com.example.demo.grpc.server;

import com.example.demo.protogen.User;
import com.example.demo.protogen.UserServiceGrpc;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;

/**
 * @author Kone
 * @date 2022/1/29
 */
@GrpcService
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {
    @Override
    public void getUser(User request, StreamObserver<User> responseObserver) {
        System.out.println(request);
        User user = User.newBuilder()
                .setName("response name")
                .build();
        responseObserver.onNext(user);
        responseObserver.onCompleted();
    }

    @Override
    public void getUsers(User request, StreamObserver<User> responseObserver) {
        System.out.println("get users");
        System.out.println(request);
        User user = User.newBuilder()
                .setName("user1")
                .build();
        User user2 = User.newBuilder()
                .setName("user2")
                .build();
        responseObserver.onNext(user);
        responseObserver.onNext(user2);

        responseObserver.onCompleted();
    }

    @Override
    public StreamObserver<User> saveUsers(StreamObserver<User> responseObserver) {

        return new StreamObserver<User>() {
            @Override
            public void onNext(User user) {
                System.out.println("get saveUsers list ---->");
                System.out.println(user);
            }

            @Override
            public void onError(Throwable throwable) {
                System.out.println("saveUsers error " + throwable.getMessage());
            }

            @Override
            public void onCompleted() {
                User user = User.newBuilder()
                        .setName("saveUsers user1")
                        .build();
                responseObserver.onNext(user);
                responseObserver.onCompleted();
            }
        };
    }
}

3.5 pom参考

springboot3有点问题,暂用2.7.9版本springboot



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.9
         
    
    com.example
    demo
    0.0.1-SNAPSHOT
    demo
    Demo project for Spring Boot
    
        17
        3.23.4
        1.26.0
    
    
        
        
            com.google.protobuf
            protobuf-java
            ${protobuf.version}
        
        
        
            net.devh
            grpc-server-spring-boot-starter
            2.14.0.RELEASE
        

        
        
            net.devh
            grpc-client-spring-boot-starter
            2.14.0.RELEASE
        
        
            org.projectlombok
            lombok
            1.18.22
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
        
    

    

        
        
            
                kr.motd.maven
                os-maven-plugin
                1.6.2
            
        
        
            
                org.xolstice.maven.plugins
                protobuf-maven-plugin
                0.6.1

                
                    
                    com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
                    
                    grpc-java
                    io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
                    

                    
                    ${project.basedir}/src/main/java/com/example/demo/proto
                    
                    ${project.basedir}/src/main/java
                    false
                
                
                    
                        
                            compile
                            compile-custom
                        
                    
                
            
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    17
                    17
                
            
        
    

3.6 grpc client调用

  • 基于grpc server的URL直接调用
package com.example.demo;

import com.example.demo.protogen.User;
import com.example.demo.protogen.UserServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

import java.util.Iterator;

public class FramelessGrpcClient {

    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9090).usePlaintext().build();
        UserServiceGrpc.UserServiceBlockingStub userService = UserServiceGrpc.newBlockingStub(managedChannel);
        User user = User.newBuilder()
                .setUserId(100)
                .putHobbys("pingpong", "play pingpong")
                .setCode(200)
                .build();
        System.out.println("get response-------->");
        System.out.println(userService.getUser(user));
        Iterator<User> users = userService.getUsers(user);
    }
}
  • 从spring IOC注入bean来调用grpc server (yml里配置了URL等)。这里使用定时任务来触发调度。 注意注入的“userClient”需要与yml 自定义的client名一致(如果调用多个grpc server,这个自定义名就是用来区别调用哪个grpc server滴)。
package com.example.demo;

import com.example.demo.protogen.User;
import com.example.demo.protogen.UserServiceGrpc;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Iterator;

/**
 * TODO
 *
 * @author majun
 * @version 1.0
 * @since 2023-08-02 20:19
 */
@Component
@EnableScheduling
public class SpringbootGrpcClient {
    @GrpcClient("userClient")
    private UserServiceGrpc.UserServiceBlockingStub userService;


    @Scheduled(fixedDelay = 10000)
    public void test() {
        User user = User.newBuilder()
                .setUserId(100)
                .putHobbys("pingpong", "play pingpong")
                .setCode(200)
                .build();
        System.out.println("get response-------->");
        System.out.println(userService.getUser(user));

        Iterator<User> users = this.userService.getUsers(user);
        while (users.hasNext()) {
            System.out.println(users.next());
        }
    }
}

你可能感兴趣的:(java,grpc,protobuf)