gRPC对比REST,在SpringBoot中使用gRPC

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 构建系统中。


 org.xolstice.maven.plugins
 protobuf-maven-plugin
 ${protobuf-maven-plugin.version}
 
  
   com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
  grpc-java
  
   io.grpc:protoc-gen-grpc-java:${io.grpc.version}:exe:${os.detected.classifier}
 
 
  
   client-code-generation
   
    compile
   
  
  
   server-code-generation
   
    compile-custom
   
  
 

结果是,当项目通过 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。


    net.devh
    grpc-server-spring-boot-starter
    2.14.0.RELEASE
  
  
    com.imertyildiz
    grpcproto
    0.0.1-SNAPSHOT
  

该库在应用程序启动时启动 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 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 项目。

新闻名称:gRPC对比REST,在SpringBoot中使用gRPC
本文网址:http://www.36103.cn/qtweb/news49/14149.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联