Spring Boot集成grpc快速入门demo

1.什么是GRPC?

gRPC 是一个高性能、开源、通用的RPC框架,由Google推出,基于HTTP2协议标准设计开发,默认采用Protocol Buffers数据序列化协议,支持多种开发语言。gRPC提供了一种简单的方法来精确的定义服务,并且为客户端和服务端自动生成可靠的功能库。 在gRPC客户端可以直接调用不同服务器上的远程程序,使用姿势看起来就像调用本地程序一样,很容易去构建分布式应用和服务。和很多RPC系统一样,服务端负责实现定义好的接口并处理客户端的请求,客户端根据接口描述直接调用需要的服务。客户端和服务端可以分别使用gRPC支持的不同语言实现。

grpc_concept_diagram_00

主要特性

  • 强大的IDLgRPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议(类似于XML、JSON、hessian)。ProtoBuf能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。
  • 多语言支持gRPC支持多种语言,并能够基于语言自动生成客户端和服务端功能库。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它语言的版本正在积极开发中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等语言,grpc-java已经支持Android开发。
  • HTTP2gRPC基于HTTP2标准设计,所以相对于其他RPC框架,gRPC带来了更多强大功能,如双向流、头部压缩、多复用请求等。这些功能给移动设备带来重大益处,如节省带宽、降低TCP链接次数、节省CPU使用和延长电池寿命等。同时,gRPC还能够提高了云端服务和Web应用的性能。gRPC既能够在客户端应用,也能够在服务器端应用,从而以透明的方式实现客户端和服务器端的通信和简化通信系统的构建。

 

2.代码工程

我们建议将您的项目分为2至3个不同的模块。

  1. grpc-api 项目 包含原始 protobuf 文件并生成 java model 和 service 类。 你可能会在不同的项目中会共享这个部分。
  2. grpc-Server 项目 包含项目的业务实现,并使用上面的 Interface 项目作为依赖项。
  3. grpc-Client 项目(可选,可能很多) 任何使用预生成的 stub 来访问服务器的客户端项目。

实验目的

定义了一个Hello Service,客户端发送包含字符串名字的请求,服务端返回Hello消息。

grpc-api

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>grpc</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><modelVersion>4.0.0</modelVersion><artifactId>grpc-api</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><protobuf.version>3.23.4</protobuf.version><protobuf-plugin.version>0.6.1</protobuf-plugin.version><grpc.version>1.58.0</grpc.version></properties><dependencies><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>${grpc.version}</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>${grpc.version}</version></dependency><dependency><!-- Java 9+ compatibility - Do NOT update to 2.0.0 --><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>1.3.5</version><optional>true</optional></dependency></dependencies><build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.7.0</version></extension></extensions><plugins><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>${protobuf-plugin.version}</version><configuration><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></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin></plugins></build>
</project>
proto

将您的 protobuf 定义/.proto文件放入src/main/proto。 有关编写 protobuf 文件的信息,请参阅官方的 protobuf 文档。 您的 .proto 文件跟如下的示例类似:

syntax = "proto3";package net.devh.boot.grpc.example;option java_multiple_files = true;
option java_package = "com.et.grpc.api.protobuf.lib";
option java_outer_classname = "HelloWorldProto";// The greeting service definition.
service MyService {// Sends a greetingrpc SayHello (HelloRequest) returns (HelloReply) {}
}// The request message containing the user's name.
message HelloRequest {string name = 1;
}// The response message containing the greetings
message HelloReply {string message = 1;
}

生成文件,源码在target/generated-sources/protobuf

mvn protobuf:compile
mvn protobuf:compile-custom

最后打包给server和client引用

grpc-server

protoc-gen-grpc-java 插件为你的每个 grpc 服务生成一个类。 例如:MyServiceGrpc 的 MyService 是 proto 文件中的 grpc 服务名称。 这个类 包含您需要扩展的客户端 stub 和服务端的 ImplicBase。 在这之后,你还有四个步骤:

  1. 请确保您的 MyServiceImp 实现了 MyServiceGrpc.MyServiceImpBase
  2. 将 @GrpcService 注解添加到您的 MyServiceImp 类上
  3. 请确保 MyServiceImplic 已添加到您的应用程序上下文中。
    • 通过在您的 @Configuration 类中创建 @Bean
    • 或者将其放置在 spring 的自动检测到路径中(例如在您Main类的相同或子包中)
  4. 实现 grpc 服务方法。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>grpc</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><modelVersion>4.0.0</modelVersion><artifactId>grpc-server</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>net.devh</groupId><artifactId>grpc-server-spring-boot-starter</artifactId><version>${grpc.version}</version></dependency><dependency><groupId>com.et</groupId><artifactId>grpc-api</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
service
/** Copyright (c) 2016-2023 The gRPC-Spring Authors** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.et.grpc.server;import com.et.grpc.api.protobuf.lib.HelloReply;
import com.et.grpc.api.protobuf.lib.HelloRequest;
import com.et.grpc.api.protobuf.lib.MyServiceGrpc;
import io.grpc.stub.StreamObserver;import net.devh.boot.grpc.server.service.GrpcService;/*** @author Michael (yidongnan@gmail.com)* @since 2016/11/8*/@GrpcService
public class GrpcServerService extends MyServiceGrpc.MyServiceImplBase {@Overridepublic void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + req.getName()).build();responseObserver.onNext(reply);responseObserver.onCompleted();}}
application.yaml
spring:application:name: local-grpc-server
grpc:server:port: 9898

grpc-client

以下列表包含您可能在客户端使用到的的所有功能。 如果您不想使用任何高级功能,那么前两个元素可能都是您需要使用的。

  • @GrpcClient: 在需要注入的客户端的字段或者 setter 方法上这个注解。 支持 Channel和各种类型的 Stub。 请不要将 @GrpcClient 与 @Autowireed 或 @Inject 一起使用。 目前,它不支持构造函数和 @Bean 方法参数。 这种情况请查看后面 @GrpcClientBean 的使用文档。 注意: 同一应用程序提供的服务只能在 ` ApplicationStartedEvent 之后访问/调用。 连接到外部服务的 Stubs 可以提前使用;从 @PostConstruct / 初始化Bean#afterPropertiesSet()` 开始。
  • @GrpcClientBean: 注解会把使用 @GrpcClient 注解的类型注册到 Spring Context 中,方便 @Autowired 和 @Qualifier 的使用。 这个注解可以重复添加到您的 @Configuration 类中。
  • Channel: Channel 是单个地址的连接池。 目标服务器可能是多个 gRPC 服务。 该地址将使用 NameResolver 做解析,最终它可能会指向一批固定数量或动态数量的服务端。
  • ManagedChannel: ManagedChannel 是 Channel 的一种特殊变体,因为它允许对连接池进行管理操作,例如将其关闭。
  • NameResolver、 NameResolver.Factory: 一个用于将地址解析为SocketAddress 列表的类 ,当与先前列出的服务端连表连接失败或通道空闲时,地址将会重新做解析。 参阅 Configuration -> Choosing the Target。
  • ClientInterceptor: 在每个 Channel 处理之前拦截它们。 可以用于日志、监测、元数据处理和请求/响应的重写。 grpc-spring-boot-starter 将自动接收所有带有 @GrpcGlobalClientInterceptor 注解以及手动注册在GlobalClientInterceptorRegistry 上的客户拦截器。 参阅 Configuration -> ClientInterceptor。
  • CallCredentials: 管理身份验证的组件。 它可以用于存储凭据和会话令牌。 它还可以用来身份验证,并且使用返回的令牌(例如 OAuth) 来授权实际请求。 除此之外,如果令牌过期并且重新发送请求,它可以续签令牌。 如果您的应用程序上下文中只存在一个 CallCredentials bean,那么 spring 将会自动将其附加到Stub(  Channel )。 CallCredentialsHelper工具类可以帮助您创建常用的 CallCredentials 类型和相关的StubTransformer
  • StubFactory: 一个用于从 Channel 创建特定 Stub 的工厂。 可以注册多个 StubFactory,以支持不同类型的 stub。 参阅 Configuration -> StubFactory。
  • StubTransformer: 所有客户端的 Stub 的注入之前应用的转换器。 参阅 Configuration -> StubTransformer。
pom.xml
/** Copyright (c) 2016-2023 The gRPC-Spring Authors** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.et.grpc.client;import com.et.grpc.api.protobuf.lib.HelloReply;
import com.et.grpc.api.protobuf.lib.HelloRequest;
import com.et.grpc.api.protobuf.lib.MyServiceGrpc;
import org.springframework.stereotype.Service;import io.grpc.StatusRuntimeException;
import net.devh.boot.grpc.client.inject.GrpcClient;/*** @author Michael (yidongnan@gmail.com)* @since 2016/11/8*/
@Service
public class GrpcClientService {@GrpcClient("local-grpc-server")// @GrpcClient("cloud-grpc-server")private MyServiceGrpc.MyServiceBlockingStub myServiceStub;public String sendMessage(final String name) {try {final HelloReply response = this.myServiceStub.sayHello(HelloRequest.newBuilder().setName(name).build());return response.getMessage();} catch (final StatusRuntimeException e) {return "FAILED with " + e.getStatus().getCode().name();}}}
controller
/** Copyright (c) 2016-2023 The gRPC-Spring Authors** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.et.grpc.client;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @author Michael (yidongnan@gmail.com)* @since 2016/12/4*/
@RestController
public class GrpcClientController {@Autowiredprivate GrpcClientService grpcClientService;@RequestMapping("/")public String printMessage(@RequestParam(defaultValue = "Michael") String name) {return grpcClientService.sendMessage(name);}}
application.yaml
server:port: 8088
spring:application:name: local-grpc-clientgrpc:client:local-grpc-server:address: 'static://127.0.0.1:9898'enableKeepAlive: truekeepAliveWithoutCalls: truenegotiationType: plaintext

3.测试

  • 启动服务端
  • 启动客户端
  • 调用服务http://127.0.0.1:8088/

测试服务

您可以通过运行 gRPCurl 命令来测试您的应用程序是否正常运行:

grpcurl --plaintext localhost:9898 list
grpcurl --plaintext localhost:9898 list net.devh.boot.grpc.example.MyService
# Linux (Static content)
grpcurl --plaintext -d '{"name": "test"}' localhost:9898 net.devh.boot.grpc.example.MyService/sayHello
# Windows or Linux (dynamic content)
grpcurl --plaintext -d "{\"name\": \"test\"}" localhost:9898 net.devh.boot.grpc.example.MyService/sayHello

gRPCurl 的示例命令输出以及其他信息请参考此 文档 。

4.引用

  • 入门指南 | grpc-spring-boot-starter

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

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

相关文章

随笔(一)

1.即时通信软件原理&#xff08;发展&#xff09; 即时通信软件实现原理_即时通讯原理-CSDN博客 笔记&#xff1a; 2.泛洪算法&#xff1a; 算法介绍 | 泛洪算法&#xff08;Flood fill Algorithm&#xff09;-CSDN博客 漫水填充算法实现最常见有四邻域像素填充法&#xf…

ChatGPT提问提示指南PDF下载经典分享推荐书籍

ChatGPT提问提示指南PDF&#xff0c;在本书的帮助下&#xff0c;您将学习到如何有效地向 ChatGPT 提出问题&#xff0c;以获得更准确和有用的回答。我们希望这本书能够为您提供实用的指南和策略&#xff0c;帮助您更好地与 ChatGPT 交互。 ChatGPT提问提示指南PDF下载 无论您是…

ESLint: Delete `␍`(prettier/prettier)解决问题补充

如果你是克隆的&#xff0c;参考这位大佬的文章 vue.js - Delete ␍eslint(prettier/prettier) 错误的解决方案 - 个人文章 - SegmentFault 思否 如果你是个人在本地实现&#xff0c;且改为 仍旧报错&#xff0c;我解决的方案&#xff1a; 改为&#xff0c;同时勾选和我配置一…

【WebGIS平台】传统聚落建筑科普数字化建模平台

基于上述概括出建筑单体的特征部件&#xff0c;本文利用互联网、三维建模和地理信息等技术设计了基于浏览器/服务器&#xff08;B/S&#xff09;的传统聚落建筑科普数字化平台。该平台不仅实现了对传统聚落建筑风貌从基础到复杂的数字化再现&#xff0c;允许用户轻松在线构建从…

C++|异常

目录 一、异常概念 二、异常使用 2.1异常的抛出与捕获 2.2异常的重新抛出 2.3异常安全注意事项 2.4异常规范 三、自定义异常体系 四、C标准库的异常体系 五、异常的优缺点 对于传统的错误处理机制&#xff0c;例如c语言常用的&#xff1a; 1.assert&#xff0c;捕获到…

虚拟内存【Linux】

虚拟内存 为什么需要虚拟内存Linux虚拟内存的结构32位系统下的虚拟地址空间64位系统下的虚拟地址空间页表多级页表TLB 流程虚拟内存的作用 为什么需要虚拟内存 为了在进行多进程编码进行内存访问的时候保持内存的隔离性&#xff0c;数据安全性&#xff0c;所以出现了虚拟内存。…

Linux | 安装lb-toolkits 1.2.4库

Linux | 安装 lb-toolkits 最近又需要下载葵花的数据&#xff0c;之前分享过一次代码。今天发现之前的环境不小心被我删了&#xff0c;而运行相关的代码需要安装lb-toolkits这个库&#xff0c;今天正好记录了一下安装lb-toolkits的过程。 这里安装的版本是1.2.4&#xff0c;别…

EPSON LQ80KF II驱动 打印机 0x00000003e3

1.添加打印机 2.按名次选择共享打印机,输入共享打印机ip 3.选择创建新端口 4.选择打印机驱动

办公助手推荐✨

办公助手来啦&#xff01;✨ 办公助手来啦&#xff01;✨&#x1f31f; 主要亮点&#x1f4dd; 全新PDF编辑器&#x1f3a8; 丰富的幻灯片版式&#x1f30d; 改进的从右至左显示&#x1f310; 新增本地化选项 &#x1f4ca; 应用场景在线办公套件&#x1f4f1; 多平台支持&…

如何学好C++?

首先&#xff0c;对于零基础的想学习C的同学&#xff0c;我想要你们先明白一件事&#xff1a;C是一门极为复杂且难以掌握的编程语言。因此推荐在学习C之前可以先去学习C语言&#xff0c;在拥有了一定的知识储备和编程能力后再学习C会更加的高效和相对轻松。 下面推荐从三个方面…

6.Python学习:异常和日志

1.异常的抓取 1.1异常的概念 使用异常前&#xff1a; print(1/0)使用异常后&#xff1a;错误提示更加友好&#xff0c;不影响程序继续往下运行 try:print(10/0) except ZeroDivisionError:print("0不能作为分母")1.2异常的抓取 第一种&#xff1a;如果提前知道可…

idea集成本地tomcat

由于网课老师使用的是eclipse,但是……本人用的是idea,所以不得不去找教程。 解决方案1&#xff1a; https://blog.csdn.net/weixin_54048131/article/details/131359793 这个地方&#xff0c;路径一定要到这个tomcat 否则不识别&#xff1a; 这里的JRE也要配置一下 新问题&…

ISO/OSI七层模型

ISO:国际标准化/ OSI:开放系统互联 七层协议必背图 1.注意事项&#xff1a; 1.上三层是为用户服务的&#xff0c;下四层负责实际数据传输。 2.下四层的传输单位&#xff1a; 传输层&#xff1b; 数据段&#xff08;报文&#xff09; 网络层&#xff1a; 数据包&#xff08;报…

python-23-零基础自学python open()和replace()函数运用

学习内容&#xff1a;《python编程&#xff1a;从入门到实践》第二版练习10-2 知识点&#xff1a; 打开文件&#xff0c;replace()替换文件内容&#xff0c;open(), 练习内容&#xff1a; 练习10-2:C语言学习笔记 可使用方法replace()将字符串中的特定单词都替换为另一个单…

C++初探究(2)

引用 对于一个常量&#xff0c;想要将其进行引用&#xff0c;则使用普通的引用相当于权限扩大&#xff08;常量为只读&#xff0c;但此处的引用参数为可读可写&#xff09;&#xff0c;C编译器会报错. 例如&#xff1a; const int a 10;int& ra a;//权限放大&#xff0…

思维+数学,CF 1138B - Circus

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1138B - Circus 二、解题报告 1、思路分析 设第一组会小丑和杂技的人数分别为x1, y1 第二组会小丑和杂技的人数分别为x2, y2 显然根据要求有&#xff1a; x1 y2 > x1 x2 x2 y2 上式说明第二组每…

离线运行Llama3:本地部署终极指南_liama2 本地部署

4月18日&#xff0c;Meta在官方博客官宣了Llama3&#xff0c;标志着人工智能领域迈向了一个重要的飞跃。经过笔者的个人体验&#xff0c;Llama3 8B效果已经超越GPT-3.5&#xff0c;最为重要的是&#xff0c;Llama3是开源的&#xff0c;我们可以自己部署&#xff01; 本文和大家…

QT入门看这一篇就够(详解含qt源码)

目录 一、Qt概述 1.1 什么是Qt 1.2 Qt的发展史 1.3 Qt的优势 1.4 Qt版本 1.5 成功案例 二、创建Qt项目 2.1 使用向导创建 2.2 一个最简单的Qt应用程序 2.2.1 main函数中 2.2.2 类头文件 2.3 .pro文件 2.4 命名规范 2.5 QtCreator常用快捷键 三、Qt按钮小程序 …

北京大学长安汽车发布毫米波与相机融合模型RCBEVDet:最快能达到每秒28帧

Abstract 三维目标检测是自动驾驶中的关键任务之一。为了在实际应用中降低成本&#xff0c;提出了利用低成本的多视角相机进行3D目标检测&#xff0c;以取代昂贵的LiDAR传感器。然而&#xff0c;仅依靠相机很难实现高精度和鲁棒性的3D目标检测。解决这一问题的有效方法是将多视…

游戏AI的创造思路-技术基础-蒙特卡洛树搜索(1)

本篇介绍蒙特卡洛树搜索算法&#xff0c;AlphaGo用于围棋计算的应用就是基于蒙特卡洛树搜索研发的~~~ 目录 1. 定义 2. 发展历史 3. 公式和函数 3.1.算法的公式和函数 3.2. Python实现公式和函数 4. 运行原理 4.1. 运行原理 4.2. 各步骤用Python代码 5. 优缺点和缺陷的…