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

news/2025/2/16 0:04:50/

文章目录

  • 一、了解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整个工程目录

在这里插入图片描述

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<string, string> 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 {@Overridepublic void getUser(User request, StreamObserver<User> responseObserver) {System.out.println(request);User user = User.newBuilder().setName("response name").build();responseObserver.onNext(user);responseObserver.onCompleted();}@Overridepublic 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();}@Overridepublic StreamObserver<User> saveUsers(StreamObserver<User> responseObserver) {return new StreamObserver<User>() {@Overridepublic void onNext(User user) {System.out.println("get saveUsers list ---->");System.out.println(user);}@Overridepublic void onError(Throwable throwable) {System.out.println("saveUsers error " + throwable.getMessage());}@Overridepublic void onCompleted() {User user = User.newBuilder().setName("saveUsers user1").build();responseObserver.onNext(user);responseObserver.onCompleted();}};}
}

3.5 pom参考

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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.9</version><relativePath/> </parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version><protobuf.version>3.23.4</protobuf.version><grpc.version>1.26.0</grpc.version></properties><dependencies><!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java --><dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>${protobuf.version}</version></dependency><!-- grpc server和spring-boot集成框架 --><dependency><groupId>net.devh</groupId><artifactId>grpc-server-spring-boot-starter</artifactId><version>2.14.0.RELEASE</version></dependency><!-- grpc client和spring-boot集成框架 --><dependency><groupId>net.devh</groupId><artifactId>grpc-client-spring-boot-starter</artifactId><version>2.14.0.RELEASE</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies><build><!-- os系统信息插件, protobuf-maven-plugin需要获取系统信息下载相应的protobuf程序 --><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.6.2</version></extension></extensions><plugins><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><!--os.detected.classifier属性是通过如上os-maven-plugin插件获取的--><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><!-- proto文件目录 --><protoSourceRoot>${project.basedir}/src/main/java/com/example/demo/proto</protoSourceRoot><!-- 生成的Java文件目录,这里指定到这一级就可以咯,proto文件有基于package指定 --><outputDirectory>${project.basedir}/src/main/java</outputDirectory><clearOutputDirectory>false</clearOutputDirectory></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>17</source><target>17</target></configuration></plugin></plugins></build>
</project>

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());}}
}

http://www.ppmy.cn/news/1002143.html

相关文章

MongoDB文档-基础使用-在客户端(dos窗口)/可视化工具中使用MongoDB基础语句

阿丹&#xff1a; 本文章将描述以及研究mongodb在客户端的基础应用以及在spring-boot中整合使用mongodb来完成基本的数据增删改查。 先放官方的文章 MongoDB CRUD操作 - MongoDB-CN-Manual 本文章分为&#xff1a; 在客户端&#xff08;dos窗口&#xff09;/可视化工具中使用…

Docker Compose构建lnmp

目录 Compose的优点 编排和部署 Compose原理 Compose应用案例 安装docker-ce 阿里云镜像加速器 安装docker-compose docker-compose用法 Yaml简介 验证LNMP环境 Compose的优点 先来了解一下我们平时是怎么样使用docker的&#xff1f;把它进行拆分一下&#xff1a; 1…

ebpf开发问题汇总

不同Programs之间通信 用bpf_obj_get来获取MAP的描述符&#xff0c;然后用bpf_map_reuse_fd函数来在不同program之间复用 kernel 与 user space之间 需要pin the BPF MAP to the BPF Virtual File System (VFS),来持久化存储&#xff0c;否则如果map用不到会被destory 引用…

Django学习笔记-默认的用户认证系统(auth)

一、Django默认的用户认证系统 Django 自带一个用户验证系统。它负责处理用户账号、组、权限和基于cookie的用户会话。 Django 验证系统处理验证和授权。简单来说&#xff0c;验证检验用户是否是他们的用户&#xff0c;授权决定已验证用户能做什么。这里的术语验证用于指代这…

股票量价关系分析

量增价平 量增价平是指成交量增加&#xff0c;股价保持相对平稳的量价关系模型&#xff0c;量的增加可以是资金大量流入引起&#xff0c;也可以是资金大量流出引起&#xff0c;因此这种关系模型需要根据股价所处的位置来具体分析。1、股价处于低位 当股价处于低位&#xff0c;此…

ElementUI el-table 鼠标滚动失灵的问题及解决办法

Bug&#xff1a;ElementUI el-table 鼠标滚轮下滑动失灵的情况 我测出来的这个问题条件很苛刻&#xff0c;需要达到以下几个条件才会触发&#xff1a; 1.element plus&#xff08;其他版本没试&#xff09; 2.el-table-column组件有fixed属性时 3.template标签中有el-butto…

Redis的缓存穿透、缓存击穿和缓存雪崩

目录 一、解释说明 二、缓存穿透 1. 什么是缓存穿透&#xff1f; 2. 常见的两种解决方案 &#xff08;1&#xff09;缓存空对象 &#xff08;2&#xff09;布隆过滤 3. 编码解决商品查询的缓存穿透问题 三、缓存雪崩 1. 什么是缓存雪崩&#xff1f; 2. 缓存雪崩解决方…

修改el-select或者el-input样式失效

下午改el-input和el-select这两个的样式真的烦&#xff0c;&#xff0c;&#xff0c;还不如写原生标签了。。 样式使用的是sass 我已经在样式器中挨着挨着去找了&#xff0c;把层级的类都写下来了 .select-wraper{//下拉框.el-select{.el-input .el-input__wrapper{backgrou…