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.mzph.cn/pingmian/61053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET架构师学习大纲

目录 微服务 Consul Ocelot Polly Skywalking Exceptionless Apollo Jenkins Docker Kubernetes DDD领域驱动设计 DevOps CDN Nginx 应用服务器集群 数据库高可用 异步化架构 Azure前沿技术 工具排查 O/RM-EFCore IOC&AOP Core WebApi WebServer 数…

汽车资讯新篇章:Spring Boot技术启航

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

「二」体验HarmonyOS端云一体化开发模板(一)

关于作者 白晓明 宁夏图尔科技有限公司董事长兼CEO、坚果派联合创始人 华为HDE、润和软件HiHope社区专家、鸿蒙KOL、仓颉KOL 华为开发者学堂/51CTO学堂/CSDN学堂认证讲师 开放原子开源基金会2023开源贡献之星 1 前置条件 实名认证的华为开发者账号 安装DevEco Studio 5.0.0 Re…

逆向攻防世界CTF系列41-EASYHOOK

逆向攻防世界CTF系列41-EASYHOOK 看题目是一个Hook类型的&#xff0c;第一次接触&#xff0c;虽然学过相关理论&#xff0c;可以看我的文章 Hook入门(逆向)-CSDN博客 题解参考&#xff1a;https://www.cnblogs.com/c10udlnk/p/14214057.html和攻防世界逆向高手题之EASYHOOK-…

Windows文件资源管理器增强工具

引言&#xff1a; 资源管理器在我们使用电脑时是经常用到的&#xff0c;各种文件资源等的分类整理都离不开它。但是Windows Explorer确实不好用&#xff0c;不智能&#xff0c;不符合人体工程学。特别是在一些场合&#xff0c;在打开的一堆文件夹里&#xff0c;想从中找到自己要…

【Flask+Gunicorn+Nginx】部署目标检测模型API完整解决方案

【Ubuntu 22.04FlaskGunicornNginx】部署目标检测模型API完整解决方案 文章目录 1. 搭建深度学习环境1.1 下载Anaconda1.2 打包环境1.3 创建虚拟环境1.4 报错 2. 安装flask3. 安装gunicorn4. 安装Nginx4.1 安装前置依赖4.2 安装nginx4.3 常用命令 5. NginxGunicornFlask5.1 ng…

Mac系统下配置 Tomcat 运行环境

下载并解压JDK 下载 根据自己需求下载对应版本的 jdk&#xff0c;我演示使用的是最新版的 jdk23&#xff0c;其他版本过程一样。 如果你是 M 芯片可以点击这个链接下载 如果你是 Intel 芯片可以点击这个链接下载 解压 下载完成后双击解压&#xff0c;将解压出来的文件夹放…

chatgpt训练需要什么样的gpu硬件

训练像ChatGPT这样的大型语言模型对GPU硬件提出了极高的要求&#xff0c;因为这类模型的训练过程涉及大量的计算和数据处理。以下是训练ChatGPT所需的GPU硬件的关键要素&#xff1a; ### 1. **高性能计算能力** - **Tensor Cores**: 现代深度学习训练依赖于Tensor Cores&#…

ESP32 烧录问题

ESP32 烧录问题 1.无法连接 Connecting......................................A fatal error occurred: Failed to connect to ESP32: No serial data received.这个表示通过串口连接esp32失败&#xff0c;可能存在多种原因&#xff0c;比如串口选择错误。 所选串口不是连接…

Getx:响应式数据,实现数据的局部刷新

Flutter官网demo实现计数器 这个demo中&#xff0c;如果要更新_count&#xff0c;调用setState就会重新build&#xff0c;这样做比较耗费性能&#xff0c;此时可以使用Getx的响应式状态管理器实现局部刷新 import package:flutter/material.dart;class JiShu extends Stateful…

从 const 到 mutable:C++ 中的优雅妥协与设计智慧

在C编程中&#xff0c;const 关键字被广泛应用于确保数据的不变性&#xff0c;它提供了一种强大的机制来防止意外修改&#xff0c;从而增强了代码的可靠性和可维护性。然而&#xff0c;在某些特定场景下&#xff0c;完全的不变性可能会限制设计的灵活性&#xff0c;这时 mutabl…

解决docker mysql命令行无法输入中文

docker启动时&#xff0c;设置支持中文 docker run --name mysql-container -e MYSQL_ROOT_PASSWORDroot -d mysql:5.7 --character-set-serverutf8mb4 --collation-serverutf8mb4_unicode_ci --default-time-zone8:00 进入docker时&#xff0c;指定LANG即可 docker exec -it …

Dowex 50WX8 ion-exchange resin可以用于去除水中的金属离子(如钠、钾、镁、钙等)和其他杂质,提高水质,11119-67-8

一、基本信息 中文名称&#xff1a;Dowex 50WX8 离子交换树脂 英文名称&#xff1a;Dowex 50WX8 ion-exchange resin CAS号&#xff1a;11119-67-8 供应商&#xff1a;陕西新研博美生物科技 外观&#xff1a;米色至浅棕色或绿棕色粉末/微球状 纯度&#xff1a;≥95% 分子…

使用Tengine 对负载均衡进行状态检查(day028)

本篇文章对于在服务器已经安装了nginx,但却希望使用Tengine 的状态检查或其他功能时使用&#xff0c;不需要卸载服务器上的nginx,思路是使用干净服务器&#xff08;未安装过nginx&#xff09;通过编译安装Tengine&#xff0c;通过对./configure的配置&#xff0c;保证安装Tengi…

PHP服务器如何开启WSS服务端Websocket

在PHP中&#xff0c;开启WebSocket服务器端通常需要使用一些扩展或者库&#xff0c;因为PHP本身并不支持原生的WebSocket协议。一个常用的库是Ratchet&#xff0c;它是一个用于构建实时、双向、基于WebSocket的应用程序的PHP库。 以下是使用Ratchet开启WSS&#xff08;WebSock…

2024 - 超火的多模态深度学习公共数据纯生信5+思路分享

超火的多模态深度学习公共数据纯生信5思路分享 多模态深度学习具有处理和整合多种类型信息的优势&#xff0c;特别是在预测患者预后方面能够结合不同类型的生物医学数据&#xff0c;如临床数据、基因表达数据、蛋白质组学数据、成像数据等&#xff0c;进而提高预后预测的准确性…

深入解析大带宽服务器:性能优势与选择指南

一、大带宽服务器是什么&#xff1f; 大带宽服务器指的是具备高网络带宽能力的服务器&#xff0c;通常提供1Gbps、10Gbps甚至更高的网络连接能力。与普通带宽服务器相比&#xff0c;大带宽服务器能够在更短时间内传输大量数据&#xff0c;因此常用于高流量、高并发需求的场景&…

深入探索高级SQL技巧:解锁数据查询与分析的无限可能

深入探索高级SQL技巧&#xff1a;解锁数据查询与分析的无限可能 在当今数据驱动的时代&#xff0c;SQL&#xff08;Structured Query Language&#xff09;作为数据库管理和查询的基础语言&#xff0c;其重要性不言而喻。然而&#xff0c;仅仅掌握基本的SELECT、INSERT、UPDA…

【MySQL】RedHat8安装mysql9.1

一、下载安装包 下载地址&#xff1a;MySQL Enterprise Edition Downloads | Oracle MySQL :: MySQL Community Downloads 安装包&#xff1a;mysql-enterprise-9.1.0_el8_x86_64_bundle.tar 官方 安装文档&#xff1a;MySQL Enterprise Edition Installation Guide 二、安装…

大前端的发展过程

大前端的发展过程可以概括为以下几个阶段&#xff1a; 静态页面时代&#xff08;1990s - 2000s&#xff09;&#xff1a; 在Web的早期阶段&#xff0c;前端开发主要以静态页面为主&#xff0c;使用HTML、CSS、JavaScript等基础技术。这一时期的网页主要是静态的&#xff0c;交互…