您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

gRPC对比REST,在Spring Boot 中使用gRPC

时间:2023-07-17 11:16:42  来源:  作者:Java学研大本营

1 为什么选择 gRPC

gRPC是一种高性能的先进RPC(远程过程调用)框架,是开源的,并且兼容不同的环境。它使用协议缓冲区作为消息交换格式。

不同语言中的 gRPC 客户端和服务器通信示例

gRPC可以让客户端代码像调用本地对象方法一样轻松地调用位于不同计算机上的服务器应用程序的方法,从而简化了开发分布式应用程序和服务的过程。

2 gRPC VS REST(简要比较)

主要的区别在于:

  • 协议:gRPC 使用 HTTP/2,但通常 REST 使用 HTTP/1.1(下面进行比较)。简而言之,HTTP/2 比 HTTP/1.1 快得多,效率更高。
  • 数据格式:REST 通常使用 JSON,而 gRPC 使用协议缓冲区。
  • API 格式:gRPC 的 API 范式是 RPC(远程过程调用),而 REST 基于表现层状态转移模型。
  • 流式传输:虽然 gRPC 支持双向流式传输,但 REST 仅限于请求-响应模式。

3 项目结构

  • grpc-proto:Demo 项目的 gRPC proto 文件
  • grpc-server:Spring Boot 中的 gRPC 服务器项目
  • grpc-client:Spring Boot 中的 gRPC 客户端项目

4 grpc-proto 项目

syntax = "proto3";

package com.imertyildiz.grpcproto;

option JAVA_multiple_files = true;

message HelloWorldRequest{
    string requestMessage = 1;
    string clientName = 2;
}

message HelloWorldResponse{
    string responseMessage = 1;
}

service HelloWorldService {
    rpc HelloWorld(HelloWorldRequest) returns (HelloWorldResponse);
}

这里创建了一个简单的 .proto 文件,包括服务、方法和消息定义。

使用 protobuf-maven-plugin 将服务器和客户端代码生成集成到 Maven 构建系统中。

<plugin>
 <groupId>org.xolstice.maven.plugins</groupId>
 <artifactId>protobuf-maven-plugin</artifactId>
 <version>${protobuf-maven-plugin.version}</version>
 <configuration>
  <protocArtifact>
   com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
  <pluginId>grpc-java</pluginId>
  <pluginArtifact>
   io.grpc:protoc-gen-grpc-java:${io.grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
 </configuration>
 <executions>
  <execution>
   <id>client-code-generation</id>
   <goals>
    <goal>compile</goal>
   </goals>
  </execution>
  <execution>
   <id>server-code-generation</id>
   <goals>
    <goal>compile-custom</goal>
   </goals>
  </execution>
 </executions>
</plugin>

结果是,当项目通过 mvn package 命令编译时,服务器和客户端代码都会生成。

但是,我们应该将项目 JAR 安装到本地 Maven 仓库中,以便 grpc-client 和 grpc-server 项目可以包含此项目 JAR。

因此,我们应该调用 mvn install 命令。

mvn install 后生成的源代码

我们将在 grpc-server 和 grpc-client 项目中使用的服务和请求对象已创建并安装在本地 Maven 仓库中。

5 grpc-server 项目

使用 grpc-spring-boot-starter 的服务器库,它通过注解简化了客户端和服务器的定义。下面是 proto 项目和 starter 库的一部分 pom.xml。

  <dependency>
    <groupId>.NET.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
    <version>2.14.0.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>com.imertyildiz</groupId>
    <artifactId>grpcproto</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </dependency>

该库在应用程序启动时启动 gRPC 服务器,并监听端口:9090(默认值)。如果我们想更改端口,可以通过 Application.properties 文件更改,例如:grpc.server.port=8000。

当我们为扩展自动生成的 gRPC 服务定义的类使用 @GrpcService 注解时,该库会将服务注册到 gRPC 服务器上。

下面是实现代码:

 package com.imertyildiz.grpcserver.Service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.imertyildiz.grpcproto.HelloWorldRequest;
import com.imertyildiz.grpcproto.HelloWorldResponse;
import com.imertyildiz.grpcproto.HelloWorldServiceGrpc;

import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;


@GrpcService
public class GreeterServer extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {
    private static final Logger logger = LoggerFactory.getLogger(GreeterServer.class);

    @Override
    public void helloWorld(HelloWorldRequest request, StreamObserver<HelloWorldResponse> responseobserver) {
        HelloWorldResponse setResponseMessage = HelloWorldResponse.newBuilder()
                .setResponseMessage("Hello " + request.getClientName() + " !!!").build();
        logger.info(String.format("%1s sent a message: %1s", request.getClientName(),request.getRequestMessage()));
        responseObserver.onNext(setResponseMessage);
        responseObserver.onCompleted();
    }

}

由于此 POC 只记录了来自请求的客户端名称,因此服务器只是记录了传入消息。

6 grpc-client 项目

同样,使用 grpc-spring-boot-starter 的客户端库。我们通过 @GrpcClient("grpc-server") 定义 gRPC 客户端。该注解带有命名目标服务器的参数。我们应该在 application.properties 文件中配置目标服务器地址。创建的文件如下所示:

grpc.client.grpc-server.address=static://localhost:8000
grpc.client.grpc-server.negotiation-type=plAIntext
grpc.server.port=8001

@GrpcClient 注解中的目标服务器名称参数在这里用于配置地址和端口信息。

客户端代码如下:

package com.imertyildiz.grpcclient.Service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.imertyildiz.grpcproto.HelloWorldRequest;
import com.imertyildiz.grpcproto.HelloWorldResponse;
import com.imertyildiz.grpcproto.HelloWorldServiceGrpc.HelloWorldServiceBlockingStub;

import net.devh.boot.grpc.client.inject.GrpcClient;

@Service
public class GreeterClient {
    private static final Logger logger = LoggerFactory.getLogger(GreeterClient.class);

    @GrpcClient("grpc-server")
    private HelloWorldServiceBlockingStub helloWorldServiceStub;

    public void sayHello(String sender, String message) {
        HelloWorldRequest helloWorldRequest = HelloWorldRequest.newBuilder().setClientName(sender)
                .setRequestMessage(message).build();
        HelloWorldResponse helloWorldResponse = this.helloWorldServiceStub.helloWorld(helloWorldRequest);
        logger.info(String.format("Server sent a response: %1s", helloWorldResponse.getResponseMessage()));
    }

}

在我们为自动生成的服务注释 BlockingStub 对象之后,它就可以使用了。我们发送消息并获取响应,然后记录响应。

从主函数中触发请求函数。代码如下:

@SpringBootApplication
public class GrpcClientApplication {

 public static void main(String[] args) {
  ApplicationContext applicationContext = SpringApplication.run(GrpcClientApplication.class, args);
  GreeterClient greeterClientService = applicationContext.getBean(GreeterClient.class);
  greeterClientService.sayHello("Client", "Hello Server !!!");
 }
}

我们来看看结果:

首先启动了服务器,然后启动了客户端。结果如下:

图片gRPC 服务器的日志

图片gRPC 客户端的日志

总的来说,本文创建了简单的 Demo 项目,展示了在 Spring Boot、Java 中 gRPC 客户端和服务器的实现和通信,以及通过 protobuf 编译器生成客户端和服务器代码的单独 proto 项目。



Tags:gRPC   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
如何通过三行配置解决在Kubernetes中的gRPC扩展问题
一切都始于我向我们的高级软件工程师提出的一个问题: “忘掉通信速度。你真的觉得在gRPC中开发通信比REST更好吗?” 我不想听到的答案立刻就来了:“绝对是的。”在我提出这个问...【详细内容】
2023-11-07  Search: gRPC  点击:(362)  评论:(0)  加入收藏
在 Kubernetes 环境中实现 gRPC 负载均衡
前言前段时间写过一篇 gRPC 的入门文章,在最后还留了一个坑没有填:图片也就是 gRPC 的负载均衡问题,因为当时的业务请求量不算大,再加上公司没有对 Istio 这类服务网格比较熟悉...【详细内容】
2023-10-17  Search: gRPC  点击:(389)  评论:(0)  加入收藏
在Kubernetes中实现gRPC流量负载均衡
在尝试将gRPC服务部署到Kubernetes集群中时,一些用户(包括我)面临的挑战之一是实现适当的负载均衡。在深入了解如何平衡gRPC的方式之前,我们首先需要回答一个问题,即为什么需要平...【详细内容】
2023-10-09  Search: gRPC  点击:(294)  评论:(0)  加入收藏
gRPC对比REST,在Spring Boot 中使用gRPC
1 为什么选择 gRPCgRPC是一种高性能的先进RPC(远程过程调用)框架,是开源的,并且兼容不同的环境。它使用协议缓冲区作为消息交换格式。不同语言中的 gRPC 客户端和服务器通信示例...【详细内容】
2023-07-17  Search: gRPC  点击:(115)  评论:(0)  加入收藏
Nginx如何实现gRPC反向代理
Nginx可以用来实现gRPC的反向代理,这里简要介绍一下如何配置Nginx实现grpc反向代理。要实现grpc反向代理,需要进行以下步骤: 安装gRPC和protobuf在Nginx服务器上安装好gRPC和pr...【详细内容】
2023-04-21  Search: gRPC  点击:(452)  评论:(0)  加入收藏
Spring Boot+Nacos+gRPC,一个区别于 OpenFeign 的微服务通信方案!
gRPC 的基础知识前面跟小伙伴们分享了很多了,今天再写一篇给这个小小的系列收个尾。我们前面介绍的都是 gRPC 的基本用法,最终目的当然是希望能够在 Spring Boot 中用上这个...【详细内容】
2023-04-04  Search: gRPC  点击:(230)  评论:(0)  加入收藏
如何用一个端口同时暴露 HTTP1/2、gRPC、Dubbo 协议?
本文我们将介绍 Apache Dubbo 灵活的多协议设计原则,基于这一设计,在 Dubbo 框架底层可灵活的选用 HTTP/2、HTTP/REST、TCP、gRPC、JsonRPC、Hessian2 等任一 RPC 通信协议,同...【详细内容】
2023-03-17  Search: gRPC  点击:(84)  评论:(0)  加入收藏
技术选型:如何选择REST、GraphQL 和 gRPC
REST、GraphQL 和 gRPC 是现代 Web 应用程序中最流行的 3 种 API 开发技术。那么在做技术选型时,三者要如何选择呢?在本文中,我们将一起对比 REST、GraphQL 和 gRPC 的特性和用...【详细内容】
2023-03-17  Search: gRPC  点击:(290)  评论:(0)  加入收藏
Go 语言怎么一键生成一个 gRPC 服务?
本文我们介绍怎么使用命令行工具 micro new 创建一个 gRPC 服务,并且怎么构建和运行服务。​01 介绍Go 开源项目 Micro​ 为我们提供一套微服务解决方案,它主要包含两个部分...【详细内容】
2023-03-06  Search: gRPC  点击:(166)  评论:(0)  加入收藏
gRPC三种Java客户端性能测试实践
我之前分享了Java和Go语言版本的gRPC接口的服务端和客户端的开发,使用的基本都是基础的原声API,旧文如下: Grpc服务开发和接口测试初探【Java】 2022-04-20 gRPC服务开发和接口...【详细内容】
2022-07-07  Search: gRPC  点击:(260)  评论:(0)  加入收藏
▌简易百科推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  步步运维步步坑    Tags:架构   点击:(5)  评论:(0)  加入收藏
大模型应用的 10 种架构模式
作者 | 曹洪伟在塑造新领域的过程中,我们往往依赖于一些经过实践验证的策略、方法和模式。这种观念对于软件工程领域的专业人士来说,已经司空见惯,设计模式已成为程序员们的重...【详细内容】
2024-03-27    InfoQ  Tags:架构模式   点击:(13)  评论:(0)  加入收藏
哈啰云原生架构落地实践
一、弹性伸缩技术实践1.全网容器化后一线研发的使用问题全网容器化后一线研发会面临一系列使用问题,包括时机、容量、效率和成本问题,弹性伸缩是云原生容器化后的必然技术选择...【详细内容】
2024-03-27  哈啰技术  微信公众号  Tags:架构   点击:(10)  评论:(0)  加入收藏
DDD 与 CQRS 才是黄金组合
在日常工作中,你是否也遇到过下面几种情况: 使用一个已有接口进行业务开发,上线后出现严重的性能问题,被老板当众质疑:“你为什么不使用缓存接口,这个接口全部走数据库,这怎么能扛...【详细内容】
2024-03-27  dbaplus社群    Tags:DDD   点击:(11)  评论:(0)  加入收藏
高并发架构设计(三大利器:缓存、限流和降级)
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。引言1.高并发背景互联网行业迅速发展,用户量剧...【详细内容】
2024-03-13    阿里云开发者  Tags:高并发   点击:(6)  评论:(0)  加入收藏
如何判断架构设计的优劣?
架构设计的基本准则是非常重要的,它们指导着我们如何构建可靠、可维护、可测试的系统。下面是这些准则的转换表达方式:简单即美(KISS):KISS原则的核心思想是保持简单。在设计系统...【详细内容】
2024-02-20  二进制跳动  微信公众号  Tags:架构设计   点击:(36)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  ijunfu  今日头条  Tags:SpringBoot   点击:(10)  评论:(0)  加入收藏
PHP+Go 开发仿简书,实战高并发高可用微服务架构
来百度APP畅享高清图片//下栽のke:chaoxingit.com/2105/PHP和Go语言结合,可以开发出高效且稳定的仿简书应用。在实现高并发和高可用微服务架构时,我们可以采用一些关键技术。首...【详细内容】
2024-01-14  547蓝色星球    Tags:架构   点击:(115)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11    王建立  Tags:Spring Boot   点击:(124)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  互联网架构小马哥    Tags:Spring Boot   点击:(115)  评论:(0)  加入收藏
站内最新
站内热门
站内头条