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://www.pswp.cn/web/42749.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42749.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42749.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UE5.3-基礎藍圖類整理一

常用藍圖類整理&#xff1a; 1、獲取當前關卡名&#xff1a;Get Current LevelName 2、通過關卡名打開關卡&#xff1a;Open Level(by name) 3、碰撞檢測事件&#xff1a;Event ActorBeginOverlap 4、獲取當前player&#xff1a;Get Player Pawn 5、判斷是否相等&#xff1…

深入解析CSS中的!important規則:優先級與最佳實踐

先上實踐&#xff0c;再討論設計 在實際工程中&#xff0c;!important 的使用場景通常出現在需要確保某個樣式規則具有最高優先級&#xff0c;以覆蓋其他可能沖突的樣式規則時。以下是一個具體的例子&#xff1a; 場景描述 假設你正在開發一個網站&#xff0c;該網站使用了多…

JavaScript的數組與函數

數組 <script type"text/javascript">/** 知識點&#xff1a;數組* 理解&#xff1a;一維數組的容器* 概念&#xff1a;* 1.數組中的數據叫做元素* 2.元素都有編號叫做下標/索引* 3.下標從0開始* 注意&#xff1a;* 1.數組作為數據的容器…

【JavaScript腳本宇宙】狀態管理利器:JavaScript 庫全面解析

提升項目效率與可維護性&#xff1a;JavaScript 狀態管理庫大揭秘 前言 在現代前端開發中&#xff0c;狀態管理是一個至關重要的話題。隨著復雜性的增加&#xff0c;有效地管理應用程序的狀態變得越來越具有挑戰性。本文將介紹一些流行的 JavaScript 庫&#xff0c;這些庫提供…

WEB安全基礎:網絡安全常用術語

一、攻擊類別 漏洞&#xff1a;硬件、軟件、協議&#xff0c;代碼層次的缺陷。 后?&#xff1a;方便后續進行系統留下的隱蔽后?程序。 病毒&#xff1a;一種可以自我復制并傳播&#xff0c;感染計算機和網絡系統的惡意軟件(Malware)&#xff0c;它能損害數據、系統功能或攔…

C++語言學習精簡筆記(包含C++20特性)

目錄 1 C新語法C與CC編譯運行String編程范式C基礎類型**自動類型推導**統一對象初始化&#xff1a;Uniform Initialization 控制結構if語句for語句switch語句namespace 2 函數函數聲明形式參數函數參數傳遞的選擇函數返回值的選擇 函數重載 Lambda表達式函數的定義和申明生存期…

磁力貓磁力搜索大全教程,如何使用磁力鏈接

磁力鏈接是一種特殊的下載鏈接&#xff0c;磁力鏈接可以理解為一個文件識別碼&#xff0c;而并非具體的資源地址&#xff0c;下載軟件需要拿著這個識別碼去整個互聯網(DHT網絡)去尋找持有該資源的用戶(節點)&#xff0c;如果找到則可以進行傳輸下載。一般年代越久遠的磁力鏈接下…

【一】m2芯片的mac中安裝ubuntu24虛擬機集群

文章目錄 1. 虛擬機配置2. 復制虛擬機2.1 修改主機名2.2 修改網絡 1. 虛擬機配置 在官方網站下載好ubuntu24-arm版鏡像開始安裝&#xff0c;安裝使用VMWare Fusion的社區免費授權版,使用一臺m2芯片的mac電腦作為物理機平臺。 為什么選擇ubuntu24&#xff1f;因為centOS7目前已…

Proteus + Keil單片機仿真教程(五)多位LED數碼管的靜態顯示

Proteus + Keil單片機仿真教程(五)多位LED數碼管 上一章節講解了單個數碼管的靜態和動態顯示,這一章節將對多個數碼管的靜態顯示進行學習,本章節主要難點: 1.鎖存器的理解和使用; 2.多個數碼管的接線封裝方式; 3.Proteus 快速接頭的使用。 第一個多位數碼管示例 元件…

『C + ⒈』‘\‘

&#x1f942;在反斜杠(\)有⒉種最常用的功能如下所示&#x1f44b; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main(void) {int a 10;int b 20;int c 30;if (a 10 &&\b 20 &&\c 30){printf("Your print\n");}else{prin…

二分查找3

1. 有序數組中的單一元素&#xff08;540&#xff09; 題目描述&#xff1a; 算法原理&#xff1a; 二分查找解題關鍵就在于去找到數組的二段性&#xff0c;這里數組的二段性是從單個數字a開始出現然后分隔出來的&#xff0c;如果mid落入左半部分那么當mid為偶數時nums[mid1]…

ByteMD富文本編輯器的vue3配置

Git地址&#xff1a;GitHub - bytedance/bytemd: ByteMD v1 repository 控制面板輸入 npm install bytemd/vue-next 下載成功后在src/main.ts中引用 import "bytemd/dist/index.css";引入后保存&#xff0c;下面是一些插件&#xff0c;比如說我用到gmf和hightLight&…

java后端向jsp傳日期,jsp調用數據錯誤問題

問題 今天遇到個bug&#xff0c;后端使用request.setAttribute("key", value);將startDate、endDate兩個日期字符串傳遞到jsp中&#xff0c;使jsp可以獲取到日期進行查詢操作。但接口拼接的參數startDate為2017&#xff0c;endDate為1986&#xff0c;讓人百思不得其…

彩色圖像(RGB)或灰度圖像(Gray)轉tensor數據(附img2tensor代碼)

&#x1f4aa; 專業從事且熱愛圖像處理&#xff0c;圖像處理專欄更新如下&#x1f447;&#xff1a; &#x1f4dd;《圖像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《語義分割》 &#x1f4dd;《風格遷移》 &#x1f4dd;《目標檢測》 &#x1f4dd;《暗光增強》 &a…

homebrew常用命令

Homebrew 提供了許多命令和選項來管理軟件包。以下是一些常用的 Homebrew 命令&#xff1a; ### 常用 Homebrew 命令 1. **安裝軟件包**&#xff1a; brew install <軟件包名稱> 2. **卸載軟件包**&#xff1a; brew uninstall <軟件包名稱> 3. **更…

CompletableFuture工具類使用

CompletableFuture工具類可以幫助實現Java并發編程中的任務編排 以上除了join用于阻塞調用該方法的線程并且接受CompletableFuture的返回值以外其它方法皆有Async異步和Executor指定線程池選項 對于supply,run,apply,accept的區別在于函數式編程的接口類型不同: supply: Sup…

tk 文本生成器

import random import tkinter as tk import ttkbootstrap as ttk from tkinter import messagebox import pyperclipdef wenben_run():def generate_text(original_text, length):# 去掉原始文本中的換行符和空格original_text original_text.replace(\n, )original_text or…

LLM生成的CUDA CUPTI Metrics for Capability 7.0解釋

LLM生成的CUDA CUPTI Metrics for Capability 7.0解釋 1.原文 2.6.1.3. Metrics for Capability 7.0 2.system_prompt 你是一位GPU專家,請詳細解釋用戶輸入GPU Metric的功能以及如何結合這個指標來優化Kernel的性能,要求專業術語用英文,其它用中文3.輸出 achieved_occupanc…

提升網絡包容性:探索Webkit的訪問性特性

在數字化時代&#xff0c;網絡的無障礙訪問性&#xff08;Accessibility&#xff09;對于確保每個人都能平等地訪問和使用網絡內容至關重要。Webkit&#xff0c;作為多個流行瀏覽器的核心渲染引擎&#xff0c;提供了一系列的訪問性特性&#xff0c;以支持殘障用戶更好地瀏覽網頁…

Windows11配置WSL2支持代理上網

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、安裝WSL2分發版二、配置步驟三、測試總結 前言 說起來本來這個功能我也不需要的&#xff0c;只是最近突然有個需求就順便研究了下&#xff0c;WSL2默認的網…