零底子入门gRPC:从 0 实现一个Hello World

打印 上一主题 下一主题

主题 865|帖子 865|积分 2595

在之前解说 Nacos 注册中央的过程中,我曾简要提到过 gRPC,主要是由于 Nacos 的最新版已经采用了 gRPC 作为其核心通信协议。这一变化带来了显著的性能优化,尤其在心跳检测、健康检查等接口的消息传输上,gRPC 可以有用减少网络负担和延迟,从而提高系统的整体效率。
所以,今天我们将简要了解一下 gRPC 这种通信协议是如何运作的,并通过一个简单的 HelloWorld 示例来展示它的基本利用方式。
gRPC

gRPC(全称:gRPC Remote Procedure Call)是一个由 Google 开发的高性能、开源的远程过程调用(RPC)框架,它基于 HTTP/2 协议,并且采用了 Protocol Buffers(Protobuf)作为接口界说语言。gRPC 旨在简化和优化微服务架构中的服务间通信,提供高效、可靠的通信机制,适用于大规模分布式系统。
gRPC 的通信流程大致如下:

  • 接口界说:开发者利用 Protobuf 界说服务接口(.proto 文件)。该文件形貌了服务的 RPC 方法、哀求和相应消息类型。
  • 代码生成:利用 Protobuf 编译器(protoc)根据 .proto 文件生成对应语言的客户端和服务器代码。
  • 客户端调用:客户端通过 gRPC 客户端 API 调用远程方法,发送哀求并接收相应。gRPC 客户端和服务器之间的通信是透明的,客户端只必要像调用本地方法一样调用远程方法。
  • 服务器实现:服务器端实现 .proto 文件中界说的 RPC 方法,并通过 gRPC 框架处置惩罚客户端的哀求。
  • 通信协议:gRPC 利用 HTTP/2 协议举行高效的通信,基于 Protobuf 编码和解码哀求和相应数据。
快速入门

新建项目

按照我们刚才讨论的通信流程,接下来我们将通过一个简单的示例来实现这一过程。首先,我们必要创建一个新的项目,项目的名称可以根据个人喜欢举行定名。如图所示:

项目结构

接下来,我们将在刚才创建的项目中进一步细化结构,我们整体的项目结构如下:
│  pom.xml

├─grpc-api
│  │  .gitignore
│  │  pom.xml
│  │
│  ├─src
│  │  ├─main
│  │  │  ├─java
│  │  │  │  └─org
│  │  │  │      └─xiaoyu
│  │  │  │          │  Main.java
│  │  │  │          └─test
│  │  │  └─proto
│  │  │          hello.proto
├─grpc-client
│  │  pom.xml
│  ├─src
│  │  ├─main
│  │  │  ├─java
│  │  │  │  └─org
│  │  │  │      └─xiaoyu
│  │  │  │          │  Main.java
│  │  │  └─resources
│  │  │          application.yml
└─grpc-server
│  pom.xml
├─src
│  ├─main
│  │  ├─java
│  │  │  └─org
│  │  │      └─xiaoyu
│  │  │          │  Main.java
│  │  │          └─service
│  │  │                  HelloWorldController.java
│  │  └─resources
│  │          application.yaml
跟着上面的目次结构,我们必要创建子项目,如图所示:

接下来,我们将设置父项目与各子项目之间的依赖关系,以确保它们可以或许精确地协同工作。
项目依赖

父项目依赖如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <parent>
  7.         <groupId>org.springframework.boot</groupId>
  8.         <artifactId>spring-boot-starter-parent</artifactId>
  9.         <version>2.6.7</version>
  10.         <relativePath />
  11.     </parent>
  12.     <groupId>org.xiaoyu</groupId>
  13.     <artifactId>grpc-demo</artifactId>
  14.     <version>1.0-SNAPSHOT</version>
  15.     <packaging>pom</packaging>
  16.     <modules>
  17.         <module>grpc-client</module>
  18.         <module>grpc-server</module>
  19.         <module>grpc-api</module>
  20.     </modules>
  21.     <properties>
  22.         <maven.compiler.source>8</maven.compiler.source>
  23.         <maven.compiler.target>8</maven.compiler.target>
  24.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  25.     </properties>
  26.     <dependencies>
  27.         <dependency>
  28.             <groupId>io.grpc</groupId>
  29.             <artifactId>grpc-protobuf</artifactId>
  30.             <version>1.51.0</version>
  31.         </dependency>
  32.         <dependency>
  33.             <groupId>io.grpc</groupId>
  34.             <artifactId>grpc-stub</artifactId>
  35.             <version>1.51.0</version>
  36.         </dependency>
  37.         <dependency>
  38.             <groupId>io.grpc</groupId>
  39.             <artifactId>grpc-netty-shaded</artifactId>
  40.             <version>1.51.0</version>
  41.         </dependency>
  42.         <dependency>
  43.             <groupId>com.google.protobuf</groupId>
  44.             <artifactId>protobuf-java-util</artifactId>
  45.             <version>3.7.1</version>
  46.         </dependency>
  47.         <dependency>
  48.             <groupId>com.googlecode.protobuf-java-format</groupId>
  49.             <artifactId>protobuf-java-format</artifactId>
  50.             <version>1.4</version>
  51.         </dependency>
  52.     </dependencies>
  53.     <build>
  54.         <extensions>
  55.             <extension>
  56.                 <groupId>kr.motd.maven</groupId>
  57.                 <artifactId>os-maven-plugin</artifactId>
  58.                 <version>1.6.2</version>
  59.             </extension>
  60.         </extensions>
  61.         <plugins>
  62.             <plugin>
  63.                 <groupId>org.xolstice.maven.plugins</groupId>
  64.                 <artifactId>protobuf-maven-plugin</artifactId>
  65.                 <version>0.6.1</version>
  66.                 <configuration>
  67.                     <protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
  68.                     <pluginId>grpc-java</pluginId>
  69.                     <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.34.1:exe:${os.detected.classifier}</pluginArtifact>
  70.                     
  71.                     <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
  72.                     
  73.                     <clearOutputDirectory>false</clearOutputDirectory>
  74.                 </configuration>
  75.                 <executions>
  76.                     <execution>
  77.                         <goals>
  78.                             <goal>compile</goal>
  79.                             <goal>compile-custom</goal>
  80.                         </goals>
  81.                     </execution>
  82.                 </executions>
  83.             </plugin>
  84.             
  85.             <plugin>
  86.                 <groupId>org.codehaus.mojo</groupId>
  87.                 <artifactId>build-helper-maven-plugin</artifactId>
  88.                 <version>3.0.0</version>
  89.                 <executions>
  90.                     
  91.                     <execution>
  92.                         <id>add-source</id>
  93.                         <phase>generate-sources</phase>
  94.                         <goals>
  95.                             <goal>add-source</goal>
  96.                         </goals>
  97.                         <configuration>
  98.                             <sources>
  99.                                 <source>${project.basedir}/src/main/gen</source>
  100.                                 <source>${project.basedir}/src/main/java</source>
  101.                             </sources>
  102.                         </configuration>
  103.                     </execution>
  104.                 </executions>
  105.             </plugin>
  106.         </plugins>
  107.     </build>
  108. </project>
复制代码
client项目依赖如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <parent>
  7.         <groupId>org.xiaoyu</groupId>
  8.         <artifactId>grpc-demo</artifactId>
  9.         <version>1.0-SNAPSHOT</version>
  10.     </parent>
  11.     <artifactId>grpc-client</artifactId>
  12.     <properties>
  13.         <maven.compiler.source>8</maven.compiler.source>
  14.         <maven.compiler.target>8</maven.compiler.target>
  15.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  16.     </properties>
  17.     <dependencies>
  18.         <dependency>
  19.             <groupId>org.springframework.boot</groupId>
  20.             <artifactId>spring-boot-starter</artifactId>
  21.         </dependency>
  22.         <dependency>
  23.             <groupId>org.springframework.boot</groupId>
  24.             <artifactId>spring-boot-starter-web</artifactId>
  25.         </dependency>
  26.         <dependency>
  27.             <groupId>net.devh</groupId>
  28.             <artifactId>grpc-client-spring-boot-starter</artifactId>
  29.             <version>2.14.0.RELEASE</version>
  30.         </dependency>
  31.         <dependency>
  32.             <groupId>org.xiaoyu</groupId>
  33.             <artifactId>grpc-api</artifactId>
  34.             <version>1.0-SNAPSHOT</version>
  35.             <scope>compile</scope>
  36.         </dependency>
  37.     </dependencies>
  38. </project>
复制代码
server的项目依赖如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <parent>
  7.         <groupId>org.xiaoyu</groupId>
  8.         <artifactId>grpc-demo</artifactId>
  9.         <version>1.0-SNAPSHOT</version>
  10.     </parent>
  11.     <artifactId>grpc-server</artifactId>
  12.     <properties>
  13.         <maven.compiler.source>8</maven.compiler.source>
  14.         <maven.compiler.target>8</maven.compiler.target>
  15.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  16.     </properties>
  17.     <dependencies>
  18.         <dependency>
  19.             <groupId>net.devh</groupId>
  20.             <artifactId>grpc-server-spring-boot-starter</artifactId>
  21.             <version>2.14.0.RELEASE</version>
  22.         </dependency>
  23.         <dependency>
  24.             <groupId>org.xiaoyu</groupId>
  25.             <artifactId>grpc-api</artifactId>
  26.             <version>1.0-SNAPSHOT</version>
  27.             <scope>compile</scope>
  28.         </dependency>
  29.     </dependencies>
  30. </project>
复制代码
proto接口界说

接下来,我们必要生成客户端和服务端的接口界说,并基于这些接口界说主动生成相关的代码。接口界说是整个 gRPC 通信的核心,它将明白服务端提供的 API 接口及其对应的消息格式,这为客户端和服务端之间的通信提供了底子。
为了高效地生成这些接口代码,我们可以借助一些主动化工具和 AI 助手来加速这一过程,简单问下即可。如图所示:

然后复制过来简单改一下,代码如下:
  1. syntax = "proto3";
  2. import "google/protobuf/any.proto";
  3. package org.xiaoyu.test;
  4. option java_multiple_files = true;
  5. option java_package = "org.xiaoyu.test";
  6. option objc_class_prefix = "HelloWorld";
  7. // 定义服务
  8. service Greeter {
  9.     // 定义一个 SayHello 方法,接收一个 HelloRequest 类型的请求,并返回一个 HelloReply 类型的响应
  10.     rpc SayHello (HelloRequest) returns (HelloReply) {}
  11. }
  12. // 定义请求消息类型
  13. message HelloRequest {
  14.     string name = 1;
  15. }
  16. // 定义响应消息类型
  17. message HelloReply {
  18.     string message = 1;
  19. }
复制代码
完成接口界说后,我们只需通过执行 mvn compile 命令,直接对 API 项目举行编译,即可主动生成与接口界说相关的全部代码类。这个过程将会根据我们在 .proto 文件中界说的 gRPC 服务和消息结构,主动生成相应的客户端和服务端代码,包括 Java 类、存根(stub)、消息类等。

服务端

接下来,如果在编译或生成代码的过程中仍然遇到标题,大概对某些步调存在疑问,完全可以继承向 AI 助手寻求资助。AI 助手可以为我们提供针对性的标题解决方案和调试建议,无论是编译错误、依赖标题,还是代码生成后的一些设置标题,都能快速给出指导。如图所示:

在生成了相关代码后,我们可以直接将这些代码复制到 server 项目中,方便我们举行服务端的开发和集成。同样地,当我们开始举行具体业务逻辑的实现时,AI 助手也能发挥重要作用。在实现服务端逻辑时,AI 助手不仅能主动补全代码,还可以基于项目的上下文和需求,智能推荐最佳的实现方式。

最终代码如下,很简单:
  1. @GrpcService
  2. public class HelloWorldController extends GreeterGrpc.GreeterImplBase {
  3.     @Override
  4.     public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
  5.         responseObserver.onNext(HelloReply.newBuilder().setMessage("xiaoyu: Hello " + request.getName()).build());
  6.         responseObserver.onCompleted();
  7.     }
  8. }
复制代码
服务端设置

我们必要简单设置一下服务端的监听接口,如下:
  1. grpc:
  2.   server:
  3.     port: 9090
复制代码
剩下的步调就是启动我们已经集成了 gRPC 服务的 Spring 项目。当我们运行项目时,Spring Boot 应用会主动加载并初始化相关的 gRPC 服务设置,并开始监听指定的端口。

客户端

在客户端部门,我们必要举行一些手动设置,虽然目前尚未找到可以或许直接启动并主动设置的注解或工具。在这个阶段,客户端代码的编写相对简单,主要是利用从 API 项目生成的客户端代码来完成对服务端的哀求调用。尽管这部门无法完全主动化,我们可以通过直接利用生成的客户端代码来手动构建哀求对象,并发起 gRPC 调用,从而实现与服务端的通信。如下:
  1. public class Main {
  2.     public static void main(String[] args) {
  3.         ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
  4.                 .usePlaintext()
  5.                 .build();
  6.         // 创建一元式阻塞式存根
  7.         GreeterGrpc.GreeterBlockingStub blockingStub = GreeterGrpc.newBlockingStub(channel);
  8.         // 创建请求对象
  9.         HelloRequest request = HelloRequest.newBuilder()
  10.                 .setName("World")
  11.                 .build();
  12.         // 发送请求信息并接收响应
  13.         HelloReply response = blockingStub.sayHello(request);
  14.         // 处理信息响应
  15.         System.out.println("Received  response: " + response);
  16.     }
  17. }
复制代码
只需直接运行项目,即可成功启动并完成服务的全部设置。与其他服务接口的调用方式类似,我们在这里无需编写任何额外的接口调用代码,看下运行结果,如图所示:

总结

通过本文的解说,我们了解了 gRPC 作为一种高效的通信协议在微服务架构中的应用,特别是在与 Nacos 集成时带来的性能优化。gRPC 的高效性,得益于其基于 HTTP/2 协议和 Protobuf 的数据传输方式,使得跨服务通信更加迅速且可靠。本文通过 HelloWorld 示例演示了从接口界说到服务端和客户端的实现流程,充分展示了 gRPC 的强盛功能和易用性。
把握这一协议,不仅可以或许提拔服务间的通信效率,也为开发更具扩展性的分布式系统奠定了底子。最终,gRPC 作为微服务架构中的关键组件,其提供的性能优化和便捷性,必将在未来的项目中发挥重要作用。
我是努力的小雨,一名 Java 服务端码农,潜心研究着 AI 技术的奥秘。我热爱技术交流与分享,对开源社区充满热情。同时也是一位腾讯云创作之星、阿里云专家博主、华为云云享专家、掘金优秀作者。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

没腿的鸟

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表