SpringBoot 之整合gRPC

父工程中引入基本的依赖:

<modules><module>api</module><module>client</module><module>service</module></modules><parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.7.3</version>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>

API模块(定义proto文件):

<artifactId>grpc-api</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging><properties><grpc.version>1.6.1</grpc.version><protobuf.version>3.3.0</protobuf.version>
</properties><dependencies><dependency><groupId>io.grpc</groupId><artifactId>grpc-netty</artifactId><version>${grpc.version}</version><scope>provided</scope></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>${grpc.version}</version><scope>provided</scope></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>${grpc.version}</version><scope>provided</scope></dependency><dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>${protobuf.version}</version></dependency>
</dependencies><build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.5.0.Final</version></extension></extensions><plugins><!-- 引入一些插件来帮助我们将.proto文件编译为java的类 --><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.5.0</version><configuration><!--使用的protoc版本,os.detected.classifier表示检测到的操作系统,这里检测到的是windows-x86_64--><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>src/main/proto</protoSourceRoot><!--生成的文件的存放位置 --><outputDirectory>src/main/java</outputDirectory><!--在调用插件去生成java类时,是否清空输出文件夹,这个要设置为false,否则运行compile-custom时会把compile的结果给删了--><clearOutputDirectory>false</clearOutputDirectory></configuration><!-- 做的一个扩展,在执行maven的compile的时候,顺便也执行protobuf-maven-plugin插件的compile和compile-custom--><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin></plugins>
</build>

在src/main目录下创建proto文件夹。
创建一个HelloWorldService.proto文件。
在这里插入图片描述

//使用proto3语法
syntax = "proto3";//生成多个java文件
option java_multiple_files = true;
//把生成的文件放到哪个包下
option java_package = "com.gotion.grpc.api";
//输出的类名
option java_outer_classname = "HelloWorldServiceProto";//定义一个类
service HelloWorldService {//定义一个gRPC方法,参数为HelloRequest,返回结果为HelloResponserpc helloWorld(HelloRequest) returns(HelloResponse) {};
}
//定义的一个请求参数对象
message HelloRequest {//msg参数,编号为1,这是编号不是赋值string msg = 1;//code参数,编号为2int32 code = 2;
}
//定义的一个返回结果对象
message HelloResponse {//resut参数,编号为1string result = 1;
}

将proto文件编译成需要的JAVA文件(使用maven去compile)了。

server模块:

<dependencies><!-- 引入api模块--><dependency><groupId>com.gotion</groupId><artifactId>grpc-api</artifactId><version>1.0.0</version></dependency><!--  引入gRPC服务提供端依赖--><dependency><groupId>net.devh</groupId><artifactId>grpc-server-spring-boot-starter</artifactId><version>2.14.0.RELEASE</version></dependency>
</dependencies>

application.yml文件:

server:port: 8081 #正常的SpringBoot应用监听的端口号grpc:server:port: 9081 #gRPC服务监听的端口号

编写启动类。
实现在API模块中定义的gRPC服务。

import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;/*** gRPC服务提供类,继承api模块中的proto文件编译生成的java文件,重写所定义的gRPC方法*/
@GrpcService
@Slf4j
public class HelloWorldService extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {/*** 定义的gRPC方法** @param request          请求对象* @param responseObserver*/@Overridepublic void helloWorld(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {//解析请求,获取其中的参数,这些都是我们之前在proto文件中定义的String msg = request.getMsg();int code = request.getCode();log.info("请求中的参数为msg:{},code:{}", msg, code);//创建一个响应对象HelloResponse helloResponse = HelloResponse.newBuilder().setResult("我是server服务端,我收到了你的请求~").build();//将该响应对象返回给调用者responseObserver.onNext(helloResponse);//这次调用结束了responseObserver.onCompleted();}
}

client端:

<dependencies><!-- spring boot web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 引入api模块--><dependency><groupId>com.gotion</groupId><artifactId>grpc-api</artifactId><version>1.0.0</version></dependency><!-- 引入gRPC客户端依赖--><dependency><groupId>net.devh</groupId><artifactId>grpc-client-spring-boot-starter</artifactId><version>2.14.0.RELEASE</version></dependency>
</dependencies>

application.yml文件:

server:port: 8080 #springboot应用监听的端口号
grpc:client:#在这里自定义服务提供方的地址,9081是服务提供方的gRPC监听的端口号#后续我会再写一篇使用zookeeper作为服务注册中心的grpc-server:address: localhost:9081negotiation-type: plaintext # 使用明文传输

编写启动类。
测试服务调用(阻塞方式和异步方式)。

import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 测试gRPC服务调用*/
@RestController
@Slf4j
@RequestMapping("/client")
public class TestController {//注入阻塞型的gRPC调用对象,服务调用的地址在application.yml中设置了@GrpcClient("grpc-server")private HelloWorldServiceGrpc.HelloWorldServiceBlockingStub blockingStub;//注入异步调用的gRPC调用对象@GrpcClient("grpc-server")private HelloWorldServiceGrpc.HelloWorldServiceFutureStub futureStub;//创建一个线程池来进行异步调用private ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20,0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(50), new ThreadPoolExecutor.CallerRunsPolicy());//用来接收异步调用结果private String result;/*** 测试阻塞调用** @return 调用结果*/@GetMapping("/block")public String block() {//构造请求对象HelloRequest helloRequest = HelloRequest.newBuilder().setMsg("block").setCode(100).build();//进行阻塞式地调用HelloResponse helloResponse = blockingStub.helloWorld(helloRequest);return helloResponse.getResult();}/*** 测试异步调用** @return 调用结果*/@GetMapping("/future")public String future() throws InterruptedException {//构造请求对象HelloRequest helloRequest = HelloRequest.newBuilder().setMsg("block").setCode(100).build();//进行异步调用,看到这里返回的是一个ListenableFuture,大家应该都知道要怎么做了哈哈哈ListenableFuture<HelloResponse> helloResponseListenableFuture = futureStub.helloWorld(helloRequest);//创建一个CountDownLatch,来等待所有的异步任务完成(如果要执行多个异步任务的话,这里只是用一下)//参数为要等待执行的异步任务数,这里是1,其实就是一个计算器CountDownLatch countDownLatch = new CountDownLatch(1);//设置回调Futures.addCallback(helloResponseListenableFuture,new FutureCallback<HelloResponse>() {@Overridepublic void onSuccess(HelloResponse helloResponse) {log.info("异步调用成功了,结果为{}", helloResponse.getResult());result = helloResponse.getResult();//计数器减1,表示该异步任务执行完成countDownLatch.countDown();}@Overridepublic void onFailure(Throwable throwable) {log.error("异步调用失败,原因是{}", throwable.getMessage());}},executor);//为了更直观地表现出异步任务,这里打印一个日志log.info("这里是主线程");//等待所有异步任务执行完成countDownLatch.await();return result;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/19266.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

高性能linux服务器运维实战 运维深入实践

用户权限管理 用户与用户组 用户与角色分类 用户是根据角色定义的。可分三类用户角色&#xff0c;root用户&#xff0c;普通用户&#xff0c;虚拟用户 虚拟用户实际不存在&#xff0c;只是为了方便管理&#xff0c;满足进程或文件的属主需求 用户和组配置文件 /etc/passw…

景联文科技:以全面数据处理服务推动AI创新与产业智能化转型

数据标注公司在人工智能领域扮演着重要角色&#xff0c;通过提供高质量的数据标注服务&#xff0c;帮助企业和组织训练和优化机器学习模型。从需求分析到数据交付&#xff0c;每一个步骤都需要严格把控&#xff0c;确保数据的质量和安全性。 景联文科技是一家专业的数据采集与标…

上市公司企业研发操纵数据集(2008-2023年)

一、数据介绍&#xff1a;参考《财会月刊》苑泽明&#xff08;2020&#xff09;老师的做法&#xff0c;具体模型如下所示&#xff0c;TA 为总资产&#xff1b;RD 为研发支出&#xff1b;MV 为企业市值取对数&#xff1b;TBQ 为企业托宾 Q值&#xff1b;INT 为营业利润&#xff…

Maven的下载安装及配置

一、下载Maven 1、访问Maven官网&#xff1a; 打开浏览器&#xff0c;访问Maven的官方网站&#xff1a;Download Apache Maven – Maven 2、选择Maven版本&#xff1a; 在下载页面上&#xff0c;选择适合您操作系统的Maven版本。通常&#xff0c;Maven提供二进制zip归档和tar…

ISCTF 2024 web

ISCTF 2024 web 小蓝鲨的冒险 源码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__); $a "isctf2024"; $b $_GET["b"]; parse_str($b); echo "小蓝鲨开始闯关&#xff0c;你能帮助他拿到flag吗?<br>"; if ($a…

Loopy为何成为IP联名新顶流,如何赋能品牌营销新高度?

在当今竞争激烈的市场环境中&#xff0c;跨界合作已成为品牌营销的重要策略之一。一个成功的跨界合作案例&#xff0c;便是Loopy IP与多个品牌的深度合作。这只来自韩国动画片《小企鹅Pororo》中的配角&#xff0c;凭借一套打工人表情包在中国社交网络迅速走红&#xff0c;并逐…

Mendix 创客访谈录|Mendix 助力西门子原生数字化工厂精益高效

本期创客 向宇轩 西门子数控&#xff08;南京&#xff09;有限公司 数字化工程师 大家好&#xff0c;我是向宇轩。专业背景是计算机科学与技术&#xff0c;毕业后加入西门子数控&#xff08;南京&#xff09;有限公司&#xff08;SNC&#xff09;担任数字化工程师的职务&#x…

C++ —— string类(上)

目录 string的介绍 string类功能的使用介绍 constructor —— 构造 介绍使用&#xff08;1&#xff09;&#xff08;2&#xff09;&#xff08;4&#xff09; &#xff1a;构造、拷贝构造、带参构造 介绍&#xff08;3&#xff09;&#xff1a;拷贝string类对象的一部分字符…

关于Qt C++中connect的几种写法

目录 1. 传统的槽函数写法 2. 使用函数指针的connect写法&#xff08;5.0&#xff09; 3. Lambda表达式作为槽函数&#xff08;C11&#xff09; 4.使用QOverload选择重载信号的写法 这connect函数就像是编程世界里的“茴”字&#xff0c;千变万化&#xff0c;各有千秋。咱们…

(二)PyTorch简要教学

文章目录 PyTorch教学一、训练一个神经网络二、用PyTorch是怎么去做的&#xff08;一&#xff09;Dataset & DataLoader&#xff08;二&#xff09;Tensors&#xff08;1&#xff09;Tensor是什么&#xff08;2&#xff09;怎么获得Tensor&#xff08;3&#xff09;Tensor相…

GRPC实现

1.首先下载对应编译插件&#xff0c;这里不再提供下载 2.编写proto文件 3.编写完成用命令生成go文件 protoc --go_out. --go-grpc_out. *.proto --go_out. 其中的. 是说你要编译的 .proto 文件目录为当前目录&#xff0c;按需修改 --go-grpc_out.&#xff0c;其中的. 是说你生…

Path does not exist: file:/D:/pythonProject/spark/main/datas/input/u.data

出现标题中的错误原因可能是&#xff1a; 1.文件路径书写错误&#xff1b; 2.文件本身不存在。 从图中可以看出&#xff0c;数据源文件是存在的&#xff0c;但是读取不到文件&#xff0c;说明代码中的文件路径写错了&#xff0c;从报错的结果可以看出&#xff0c;python在D:/…

Wallpaper壁纸制作学习记录01

导入图像 打开wallpaper软件&#xff0c;找到下方的播放列表&#xff0c;选择壁纸编辑器。 弹出下列界面&#xff0c;在创建壁纸处可以选择图片拖入。 在开始导入任何图像之前&#xff0c;请首先确保主背景图像表示实际屏幕分辨率。展示示例图像是 1920 x 1080&#xff0c;这…

【知识科普】统一身份认证CAS

什么是CAS 综合概述一、CAS概述二、CAS的组成与工作原理三、CAS的特性与支持四、CAS的应用场景 示例展示场景设定CAS认证过程 其他认证细节CAS认证过程的细节CAS认证过程的特性 参考文献 综合概述 统一身份认证CAS&#xff08;Central Authentication Service&#xff09;&…

计算机网络-MSTP工作原理

前面大致学习了MSTP基础概念与组成&#xff0c;今天来了解MSTP的工作原理。 一、MSTP拓扑计算&#xff1a; MSTP可以将整个二层网络划分为多个MST域&#xff0c;各个域之间通过计算生成CST&#xff0c;域内生成IST&#xff0c;CST和IST构成了整个交换设备网络的CIST。 域内还可…

面试题:Kafka(一)

1. Kafka如何保证消息不丢失 生产者发送消息到Brocker丢失 设置异步发送 消息重试 消息在Brocker中存储丢失 发送确认机制acks 消费者从Brocker接收消息丢失 Kafka 中的分区机制指的是将每个主题划分成多个分区&#xff08;Partition&#xff09;topic分区中消息只能由消费者…

odoo 创建应用

1、通过手脚架命令创建文件结构&#xff08;完全可以手动一个个文件/文件夹建&#xff09; odoo-bin scaffold <模块名> <模块放置路径> 在odoo根目录路径执行命令行&#xff1a;./odoo-bin scaffold my_library exte_addons 执行结果&#xff1a; 参考文章&…

十四、SpringMVC的执行流程

文章目录 1. SpringMVC常用组件2. DispatcherServlet初始化过程3. DispatcherServlet调用组件处理请求4. SpringMVC的执行流程 1. SpringMVC常用组件 2. DispatcherServlet初始化过程 3. DispatcherServlet调用组件处理请求 4. SpringMVC的执行流程

java基础概念30:常见API-System

一、System工具类的常用方法 System也是一个工具类&#xff0c;提供了一些与系统相关的方法。 计算机的时间原点:1970年1月1日0:0:0&#xff0c;我国在东八区&#xff0c;有8小时时差。 二、常用方法说明 2-1、System.exit()方法 该方法用于终止当前运行的Java虚拟机&#x…

基于AOA算术优化的KNN数据聚类算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于AOA算术优化的KNN数据聚类算法matlab仿真。通过AOA优化算法&#xff0c;搜索最优的几个特征数据&#xff0c;进行KNN聚类&#xff0c;同时对比不同个数特征下…