gRPC协议详解

在这里插入图片描述

gRPC介绍

gRPC是一个高性能、开源和通用的RPC(远程过程调用)框架,由Google发起并开发,于2015年对外发布。它基于HTTP/2协议和Protocol Buffers设计,支持多种编程语言(如C++、Java、Python、Go、Ruby、C#、Node.js等)。
gRPC的核心思想是基于接口定义语言(IDL)来定义服务,在编译期间自动生成具体的服务端和客户端代码。这种设计使得服务端和客户端可以完全专注于业务,而无需关心通信协议的细节。
gRPC提供了四种不同类型的服务:Unary RPC、Server Streaming RPC、Client Streaming RPC和Bidirectional Streaming RPC。其中,Unary RPC是最常用的一种,它是一种普通的RPC调用,即客户端向服务器发送一个请求,服务器返回一个响应。而Streaming RPC则是一种支持流式数据传输的RPC调用方式,它可以实现更加复杂的通信模式,如实时聊天、视频流传输等。
gRPC还支持多种认证和授权机制,如基于TLS的认证、OAuth2授权等。同时,它还提供了一系列的性能优化机制,如连接复用、流控制、压缩等,可以大大提升RPC调用的效率和性能。
gRPC被广泛应用于微服务架构中,是一种高效、直观且方便进行数据传输和处理的远程过程调用协议。

在这里插入图片描述

gRPC协议特点

  • 支持多种语言 :gRPC支持多种编程语言,如C++、Java、Python、Go、Ruby、C#、Node.js等,使得在不同语言环境下进行RPC调用变得更加容易。
  • 通信协议基于HTTP/2设计 :gRPC使用HTTP/2作为通信协议,具有连接复用、双向流、消息头压缩、单TCP的多路复用等特点,可以节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。
  • 序列化支持PB(Protocol Buffer)和JSON :gRPC支持PB和JSON两种序列化协议。PB是一种语言无关的高性能序列化框架,基于HTTP/2 + PB,保障了RPC调用的高性能。同时,gRPC也支持JSON序列化,使得数据传输更加方便。
  • 基于IDL文件定义服务 :gRPC使用IDL(Interface Definition Language)文件定义服务,通过proto3工具生成指定语言的数据结构、服务端接口以及客户端Stub。这种设计使得服务端和客户端可以完全专注于业务,而无需关心通信协议的细节。
  • 支持流式调用 :gRPC支持四种不同类型的服务,包括Unary RPC、Server Streaming RPC、Client Streaming RPC和Bidirectional Streaming RPC。其中,Streaming RPC支持流式数据传输,可以实现更加复杂的通信模式,如实时聊天、视频流传输等。
  • 安全性 :gRPC支持多种认证和授权机制,如基于TLS的认证、OAuth2授权等,提高了通信的安全性。
  • 高效 :gRPC具有高效的性能优化机制,如连接复用、流控制、压缩等,可以大大提升RPC调用的效率和性能。

在这里插入图片描述

gRPC应用场景

gRPC被广泛应用于微服务架构中,是一种高效、直观且方便进行数据传输和处理的远程过程调用协议。它非常适合用于服务之间的通信,提供高性能、类型安全和易于维护的通信机制。此外,gRPC还支持多种编程语言,因此可以轻松地在不同的技术栈中进行通信,对于跨团队协作、不同技术栈的应用程序集成以及构建多语言系统非常有用。
gRPC的应用场景包括:

微服务架构 :gRPC非常适合用于微服务架构中,可以用于服务之间的通信,提供高性能、类型安全和易于维护的通信机制。

跨语言通信 :gRPC支持多种编程语言,因此可以轻松地在不同的技术栈中进行通信。这对于跨团队协作、不同技术栈的应用程序集成以及构建多语言系统非常有用。

移动应用通信 :gRPC的轻量级性能使其成为移动应用与后端服务器之间进行高效通信的理想选择。它可以用于移动应用与云服务或后端API之间的通信,以获取数据或执行操作。

设计语言独立、高效、精确的新协议 :gRPC基于HTTP/2设计,具有连接复用、双向流、消息头压缩、单TCP的多路复用等特点,可以节省带宽、降低TCP链接次数、节省CPU。

便于各方面扩展的分层设计 :gRPC支持多种认证和授权机制,如基于TLS的认证、OAuth2授权等,提高了通信的安全性。此外,它还提供了一系列的性能优化机制,如连接复用、流控制、压缩等,可以大大提升RPC调用的效率和性能。

Java实现gRPC案例

  1. 首先,定义一个gRPC的服务接口,这里我们定义一个简单的HelloService,只有一个sayHello的方法,返回一个HelloReply类型的对象:
public interface HelloService extends Service<HelloRequest, HelloReply> {
    @Override
    HelloReply sayHello(HelloRequest request);
}
  1. 实现这个服务接口。在实现类中,我们需要实现sayHello方法:
public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase implements HelloService {
    @Override
    public HelloReply sayHello(HelloRequest request) {
        return HelloReply.newBuilder()
                .setMessage("Hello " + request.getName())
                .build();
    }
}
  1. 在服务器端,我们需要注册并启动这个服务:
public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {
        Server server = ServerBuilder.forPort(50051)
                .addService(new HelloServiceImpl())
                .build();
        server.start();
        server.awaitTermination();
    }
}
  1. 在客户端,我们可以调用这个服务:
public class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
                .usePlaintext()
                .build();
        try (HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(channel)) {
            HelloReply reply = stub.sayHello(HelloRequest.newBuilder().setName("World").build());
            System.out.println(reply.getMessage());
        } finally {
            channel.shutdown();
        }
    }
}

在这里插入图片描述

Protocol Buffers的特点

  1. 跨平台、跨语言:Protobuf支持跨平台和跨语言的特性,可以在不同的平台和编程语言中使用。生成的代码体积小,传输速度快,适用于各种不同类型的应用场景。
  2. 二进制序列化:Protobuf使用二进制格式进行序列化,相较于文本格式,具有更小的存储空间和更快的解析速度。这种格式也使得Protobuf在数据传输时更加紧凑和高效。
  3. 丰富的数据类型:Protobuf支持多种数据类型,包括整数、浮点数、布尔值、字符串、字节流等,可以满足不同类型的数据需求。
  4. 自定义消息结构:使用Protobuf时,首先需要定义好需要传输的数据的格式,即Proto文件。使用Proto文件定义数据格式后,就可以使用提供的代码生成工具生成对应语言的数据访问类,在应用中便可以使用这些类进行数据编解码。这种灵活的消息结构可以方便地添加新的字段或修改字段,而不会影响旧版本的代码。
  5. 高效的序列化:Protobuf使用二进制编码,相比于XML、JSON等文本标记语言,具有更小的存储空间和更快的序列化和反序列化速度。
  6. 安全性:由于Protobuf的二进制格式和严格的格式规范,解析速度非常高效。同时,其消息结构可以进行版本控制和演化,通过向已定义的消息中添加新的字段或修改字段,旧版本的代码仍然可以与新版本的消息进行兼容。

总的来说,Protocol Buffers是一种非常高效的数据交换格式,适用于数据传输量较大、网络带宽较小或数据响应速度要求较高的领域。

使用Protocol Buffers的Java案例

假设我们有一个Proto文件,名为person.proto,定义了一个Person消息类型,包含姓名和年龄两个字段:

syntax = "proto3";

message Person {
    string name = 1;
    int32 age = 2;
}

首先,我们需要使用Protocol Buffers的编译器生成Java代码。假设我们已经安装了Protocol Buffers编译器,可以在命令行中输入以下命令生成Java代码:

protoc --java_out=./ ./person.proto

这将生成一个名为Person.java的文件,其中包含Person消息类型的Java类定义。

接下来,我们可以使用生成的Java类来序列化和反序列化Person消息。以下是一个简单的Java程序,演示了如何使用Protocol Buffers进行序列化和反序列化:

import com.google.protobuf.util.JsonFormat;
import java.io.IOException;
import java.util.logging.Logger;

public class PersonExample {
    private static final Logger logger = Logger.getLogger(PersonExample.class.getName());

    public static void main(String[] args) throws IOException {
        // 创建一个Person对象
        Person person = Person.newBuilder()
                .setName("Alice")
                .setAge(25)
                .build();

        // 将Person对象序列化为二进制格式
        byte[] bytes = person.toByteArray();
        logger.info("Serialized person to " + bytes.length + " bytes");

        // 将二进制格式反序列化为Person对象
        Person deserializedPerson = Person.parseFrom(bytes);
        logger.info("Deserialized person: " + deserializedPerson);
    }
}

在上面的示例中,我们首先创建了一个Person对象,并设置了姓名和年龄字段。然后,我们使用toByteArray()方法将Person对象序列化为二进制格式。最后,我们使用parseFrom()方法将二进制格式反序列化为Person对象。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

es安装方式

es安装方式 1.下载镜像的方式 分词器 kibana和es和容器互通的方式 docker network create es-net开始拉去镜像的方式 docker pull kibana:7.12.1运行镜像的方式 docker run -d \--name es \-e "ES_JAVA_OPTS-Xms512m -Xmx512m" \-e "discovery.typesingle-…

论文笔记——BiFormer

Title: BiFormer: Vision Transformer with Bi-Level Routing AttentionPaper: https://arxiv.org/pdf/2303.08810.pdfCode: https://github.com/rayleizhu/BiFormer 一、前言 众所周知&#xff0c;Transformer相比于CNNs的一大核心优势便是借助自注意力机制的优势捕捉长距离…

【算法】堆排序

算法-堆排序 前置知识 堆&#xff08;即将更新&#xff09; 思路 我们现在有一个序列&#xff0c;怎么对它排序&#xff1f; 这是一个非常经典的问题&#xff0c;这里我们使用一个借助数据结构的算法——堆排序解决。 这里有一个序列&#xff0c;要对它升序排序 4 7 3 6 5 …

kubectl get nodes报错:The connection to the server localhost:8080

报错描述kubectl get nodes命令无法执行 在K8S-master初始化后&#xff0c;worker-node节点加入K8S集群后 kubeadm join 192.168.31.150:6443 --token 2n0t62.gvuu8x3zui9o8xnc \--discovery-token-ca-cert-hash sha256:d294c082cc7e0d5f620fb10e527a8a7cb4cb6ccd8dc45ffaf2c…

突发!奥特曼宣布暂停ChatGPT Plus新用户注册!

大新闻&#xff01;就在刚刚&#xff01; OpenAI的CEO Sam Altman宣布暂停ChatGPT Plus 新用户注册&#xff01; Sam Altman对此解释道&#xff1a; 由于OpenAI开发日后ChatGPT使用量的激增超出了我们的承受能力&#xff0c;我们希望确保每个人都有良好的体验。 您仍然可以在a…

51单片机应用从零开始(三)

51单片机应用从零开始&#xff08;一&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;二&#xff09;-CSDN博客 详解 KEIL C51 软件的使用建立工程-CSDN博客 详解 KEIL C51 软件的使用设置工程编绎与连接程序-CSDN博客 目录 1. 用单片机控制第一个灯亮 2. 认识单片…

Mendix 创客访谈录|低代码赋能IoT应用开发

本期创客 郑锴 舜宇光学科技&#xff08;集团&#xff09;有限公司信息技术部 毕业于浙江大学&#xff0c;三年软件设计开发经验。目前任职于舜宇光学科技&#xff08;集团&#xff09;有限公司信息技术部&#xff0c;担任软件开发工程师&#xff0c;主要负责工业互联网相关软件…

报错资源不足,k8s使用containerd运行容器修改挂载点根目录换成/home

运行k8s一段时间发现存储不足报错 发现这里用的是根路径的挂载&#xff0c;修改一下

深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解

深入学习 Android Framework 第三&#xff1a;深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解 文章目录 深入学习 Android Framework前言一、Android 系统的启动流程1. 流程图2. 启动流程概述 二、源码详解1. 时序图2. 源代码1、ZygoteInit # main…

opencv(1):创建和显示窗口, 读取保存图片

下载源码&#xff0c;方便查看 API 信息。 快速在源码文件夹中搜索相关 api. grep“namedWindow(*-Rn// 限定 .h 文件 grep“namedWindow(*-Rn|grep "\.h" vscode 语法检测有问题 一直有波浪线 打开 vscode, setting 界面&#xff0c;搜索 python 在 setting.json…

【Shell脚本12】Shell 输入/输出重定向

Shell 输入/输出重定向 大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入&#xff0c;默认情况下&#xff0c;这恰好是你的终端。同样&#xff0c;一个命令通常将其输出写入到标准输出&#xff0c;默…

Linux系统编程——进程中vfork函数

函数原型 pid_t vfork(void);//pid_t是无符号整型 所需头文件 #include <sys/types.h> #include <unistd.h> 功能 vfork() 函数和 fork() 函数一样都是在已有的进程中创建一个新的进程&#xff0c;但它们创建的子进程是有区别的。 返回值 成功子进程中返回 …

RK3588平台开发系列讲解(摄像头篇)USB摄像头驱动分析

🚀返回专栏总目录 文章目录 一. USB摄像头基本知识1.1 内部逻辑结构1.2 描述符实例解析二. UVC驱动框架2.1、设备枚举过程2.2、数据传输过程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 USB摄像头驱动位于 drivers\media\usb\uvc\uvc_driver.c ,我们本篇重点看下…

rpmbuild 包名 version 操作系统信息部分来源 /etc/rpm/macros.dist

/etc/rpm/macros.dist openeuler bclinux src.rpm openssl-1.1.1f-13.oe1.src.rpm 打包名称结果 openeuler openssl-1.1.1f-13.aarch64.rpm bclinux openssl-1.1.1f-13.oe1.bclinux.aarch64.rpm 验证 修改openeuler配置文件macros.dist 重新在openeuler上执行rpmbuild…

opencv:从0到实现人脸识别

目录 opencv 人脸检查原理&#xff1a; 整体目录&#xff1a; 1.读取并展示图片 2.人脸检测 3.视频人脸检测 4.拍照保存 5 数据训练 6 人脸识别 opencv 人脸检查原理&#xff1a; OpenCV 中的人脸检测是基于哈尔特征分类器&#xff08;Haar Feature-based Cascade Cla…

EtherCAT从站EEPROM组成信息详解(1):字0-7ESC寄存器配置区

0 工具准备 1.EtherCAT从站EEPROM数据&#xff08;本文使用DE3E-556步进电机驱动器&#xff09;1 字0-字7ESC寄存器配置区组成信息详解 1.1 ESC寄存器配置区组成规范 对于EtherCAT从站来说&#xff0c;EEPROM的字0-字7组成的ESC寄存器配置区决定了从站上电后ESC能否正常工作…

【React】React-Redux基本使用

容器组件和 UI 组件 所有的 UI 组件都需要有一个容器组件包裹 容器组件来负责和 Redux 打交道&#xff0c;可以随意使用 Redux 的API UI 组件无任何 Redux API 容器组件用于处理逻辑&#xff0c;UI 组件只会负责渲染和交互&#xff0c;不处理逻辑 在我们的生产当中&#xff0…

C/C++最大质数 2021年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C比n小的最大质数 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C比n小的最大质数 2021年9月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 对于给定的n&#xff0c;求比n小的质数中…

零小时零信任:数据标记如何加速实施

现在是零信任的零小时。 虽然这个概念已经存在多年&#xff0c;但现在联邦政府实施它的时间已经紧迫。 拜登政府备忘录被誉为以战斗速度安全交付关键任务数据的解决方案&#xff0c;要求联邦机构在 2024 财年年底前实现具体的零信任安全目标。 此外&#xff0c;国防部正在努…

ClickHouse的数据类型

1 整型 固定长度的整型&#xff0c;包括有符号整型或无符号整型。 整型范围&#xff08;-2n-1~2n-1-1&#xff09;&#xff1a; Int8 - [-128 : 127] Int16 - [-32768 : 32767] Int32 - [-2147483648 : 2147483647] Int64 - [-9223372036854775808 : 9223372036854775807] 无符…