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,一经查实,立即删除!

相关文章

汽车资讯新篇章: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;将解压出来的文件夹放…

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

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

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…

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

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

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

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

【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 二、安装…

力扣(leetcode)题目总结——动态规划篇

leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏&#xff1a;点击进入 leetcode题目分类 关注走一波 前言&#xff1a;本系列文章初衷是为了按类别整理出力扣&#xff08;leetcode&#xff09;最经典题目&#xff0c…

Vscode/Code-server无网环境安装通义灵码

Date: 2024-11-18 参考材料&#xff1a;https://help.aliyun.com/zh/lingma/user-guide/individual-edition-login-tongyi-lingma?spma2c4g.11186623.0.i0 1. 首先在vscode/code-server插件市场中安装通义插件&#xff0c;这步就不细说了。如果服务器没网&#xff0c;会问你要…

力扣周赛:第424场周赛

&#x1f468;‍&#x1f393;作者简介&#xff1a;爱好技术和算法的研究生 &#x1f30c;上期文章&#xff1a;力扣周赛&#xff1a;第422场周赛 &#x1f4da;订阅专栏&#xff1a;力扣周赛 希望文章对你们有所帮助 第一道题模拟题&#xff0c;第二道题经典拆分数组/线段树都…

STM32单片机设计防儿童人员误锁/滞留车内警报系统

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 近年来在车辆逐渐普及的情况下&#xff0c;由于家长的疏忽&#xff0c;将…

Vue Canvas实现区域拉框选择

canvas.vue组件 <template><div class"all" ref"divideBox"><!-- 显示图片&#xff0c;如果 imgUrl 存在则显示 --><img id"img" v-if"imgUrl" :src"imgUrl" oncontextmenu"return false" …

开源音乐分离器Audio Decomposition:可实现盲源音频分离,无需外部乐器分离库,从头开始制作。将音乐转换为五线谱的程序

今天给大家分析一个音频分解器&#xff0c;通过傅里叶变换和信封匹配分离音乐中的各个音符和乐器&#xff0c;实现音乐到乐谱的转换。将音乐开源分离为组成乐器。该方式是盲源分离&#xff0c;从头开始制作&#xff0c;无需外部乐器分离库。 相关链接 代码&#xff1a;https:…

智慧安防丨以科技之力,筑起防范人贩的铜墙铁壁

近日&#xff0c;贵州省贵阳市中级人民法院对余华英拐卖儿童案做出了一审宣判&#xff0c;判处其死刑&#xff0c;剥夺政治权利终身&#xff0c;并处没收个人全部财产。这一判决不仅彰显了法律的威严&#xff0c;也再次唤起了社会对拐卖儿童犯罪的深切关注。 余华英自1993年至2…

【原创】java+ssm+mysql房屋租赁管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…