上次我们专门通过一个简单的HelloWorld示例来了解了gRPC的基本概念和使用方法。今天,我们将继续深入探讨gRPC,重点讨论一些在实际应用中需要特别注意的要点。实际上,gRPC的核心目标是简化远程调用的过程,它通过定义清晰的接口,利用Protocol Buffers(简称proto协议)来生成不同编程语言的接口代码,从而实现跨语言、高效的通信。

在回顾了gRPC的基本工作原理之后,我们今天将进一步扩展视野,继续探讨一些更细节的部分。

gRPC

是否会覆盖

今天,我特别添加了一个新的测试接口,目的是测试在进行重新编译时,系统是否会丢失之前定义的接口和相关业务逻辑。为了简化说明,实体类部分就不再重新编写了,它与之前定义的内容完全一致。具体细节请见下图:

在我重新进行编译后,我发现除了这个特定的类需要单独手动编写之外,其他的内容都已经自动生成完毕。这意味着,我们不需要担心会因编译过程而导致已有内容被直接覆盖掉。

实际上,Maven 工具本身也可以配置,以控制在执行时是否删除目录中的某些内容并重新生成。虽然这里不作详细讨论,但从正常业务操作的角度来看,我们通常都不希望自己辛苦编写的代码在没有任何警告的情况下,因他人的误操作或一键执行而被完全删除。

字段编号有何用

在我们讨论实体类消息体中为何会出现数字时,首先要明确的是,虽然我们在定义字段时已经给它们起了具体的名字,但这远不够。特别是在使用 gRPC 进行服务通信时,你需要从传统的 JSON 格式(键值对结构)中跳脱出来,重新理解字段的表示方式。

在 gRPC 中,数据是通过 Protocol Buffers(Protobuf) 进行序列化和传输的,而 Protobuf 的一个关键概念就是 字段编号(Field Numbers)。如图所示:

其实作用最主要的就是序列化和反序列化,当 Protobuf 序列化消息时,它并不直接存储字段名(如 name、age 等),而是存储字段编号和字段值的对应关系。这样,这使得数据传输时比使用 JSON 或 XML 更加紧凑。

我们简单看下后台输出的日志,你大概就能理解了,如图所示:

我们把这些字节全拿出来看下。比如:

  1. 00 00 00 00:这些是四个字节,通常是用来表示某个字段的填充数据,可能是某种标识符、长度或者预留字节。
  2. 07:这个字节通常表示某种数据的长度或其他编码标识。
  3. 0a:这个字节也有可能是长度或某种控制符号。
  4. 05:又是一个字节,通常也表示控制信息。
  5. 57 6f 72 6c 64:这些字节代表的是ASCII编码字符。它们对应的字符为:
    • 57 → 'W'
    • 6f → 'o'
    • 72 → 'r'
    • 6c → 'l'
    • 64 → 'd'

因此,57 6f 72 6c 64 对应的字符串是 "World"。

同理,我们看下返回的数据也是一样的字节。然后反序列化成我们所需要的字段值,具体的我们就不探讨了。了解下他的优点即可。

这串字节 00000000150a137869616f79753a2048656c6c6f20576f726c64 可以被解释为:

  • 一些前导字节(如 00 00 00 0015 0a 13)可能是标识符、长度字段或者控制信息。
  • 后面部分解码成了字符串 "xiaoyu: Hello World"

还有一个需要注意的就是,既然他有字段编号,所以你不要轻易去修改编号,就算不用了,也要去用新的编号进行标识处理。这是因为如果有老客户端仍在继续使用,会导致无法正确解析新版消息,会出现兼容性错误。

总结

通过今天的探讨,我们进一步加深了对gRPC和Protocol Buffers的理解,特别是在实际应用中可能遇到的一些细节和注意事项。我们了解了在重新编译时,系统如何自动生成接口代码并避免覆盖已有内容,从而减少了手动操作的风险。同时,深入探讨了Protocol Buffers中的字段编号机制,它不仅有助于数据的高效序列化和传输,也在版本兼容性上起到了至关重要的作用。尽管字段名称对开发者来说更具可读性,但最终传输的数据依赖于字段编号,而对编号的管理和修改必须小心谨慎,以确保不同版本之间的兼容性。

希望通过今天的讲解,大家能更好地理解gRPC的应用场景和实际操作中的细节。


我是努力的小雨,一名 Java 服务端码农,潜心研究着 AI 技术的奥秘。我热爱技术交流与分享,对开源社区充满热情。同时也是一位腾讯云创作之星、阿里云专家博主、华为云云享专家、掘金优秀作者。

我将不吝分享我在技术道路上的个人探索与经验,希望能为你的学习与成长带来一些启发与帮助。

欢迎关注努力的小雨!

gRPC编译与字段编号的细节探讨的更多相关文章

  1. 传统D3D11程序面向VS2015编译环境的配置修正细节

    A.  配置细节 使用#include <unordered_map>替代<hash_map> 这个是c++标准建议的,没啥好说的 使用#include <directx ...

  2. windwos grpc 编译

    此文档是windwos grpc c++ 编译 ,基于 vs2015 编译完成 获取gRPC源码 gRPC是开源框架,项目代码在github上,所以首先要安装github.github安装后,在指定文 ...

  3. grpc编译错误解决

    berli@berli-VirtualBox:~/grpc$ make [MAKE]    Generating cache.mk [C]       Compiling src/core/lib/s ...

  4. grpc使用记录(一) gRPC编译(mscv/gcc)

    目录 1.编译前的准备工作 2.Windows下使用VS2019编译 2.1.使用cmake生成VS2019解决方案 2.2.使用msbuild工具进行编译 3.linux下编译 3.1 CentO ...

  5. gRPC编译教程

    windows平台的编译 一.编译openssl ① 安装perl(可以使用ActivePerl),执行perl Configure VC-WIN64A no-asm .在这里解释一下参数含义,VC- ...

  6. DataInputStream和DataOutputStream使用方法细节探讨

    DataInputStream和DataOutputStream都是Java中输入输出流的装饰类,用起来非常方便.今天就来讨论一下使用该类时候遇到的编码问题.  package com.vince ...

  7. php foreach 遍历细节探讨

    foreach 也是正常的语法循环结构,可以有 break 和 continue 等操作 遍历过程中值变量传递默认是值传递 输出结果为: 遍历过程中值变量可以认为设定为引用传递:foreach($数组 ...

  8. vue路由细节探讨

    1.使用router-link 不会让页面刷新,使用a标签会使页面刷新.2.router-link 里面的to="/路由地址" tag=""自定义标签" ...

  9. 编译gRPC

    编译gRPC 目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 无论通过哪种语言调用gRPC,都必须要编译gRPC,因为生成proto访问类时,除了产生标准的数据定义 ...

  10. 初识google多语言通信框架gRPC系列(二)编译gRPC

    目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 无论通过哪种语言调用gRPC,都必须要编译gRPC,因为生成proto访问类时,除了产生标准的数据定义类之外,还需要 ...

随机推荐

  1. 常见CDN绕过姿势

    CDN绕过: 1.子域名 子域名查询: 在一些网站中有可能只加速了主站,而一些其它子域名和主站在同一个C段或者同服务器 利用子域名查询工具: http://tool.chinaz.com/subdom ...

  2. HTML5+CSS3+JavaScript网页实战

    1. HTML5基础 HTML5,作为构建和呈现网页内容的标准标记语言,带来了许多革命性的变化.它不仅提供了更加语义化的标签,使得网页内容更具可读性和可访问性,还增加了对多媒体的原生支持,无需依赖第三 ...

  3. 枚举(C语言)

    1.枚举定义 枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量,它可以让数据更简洁,更易读. 枚举类型通常用于为程序中的一组相关的常量取名字,以便于程序的可读性和维护性. 定义一个枚 ...

  4. 《使用Gin框架构建分布式应用》阅读笔记:p251-p271

    <用Gin框架构建分布式应用>学习第14天,p251-p271总结,总21页. 一.技术总结 1.Docker & Docker Compose version: "3. ...

  5. Next.js 与 Node.js 全栈应用开发:API设计、数据库连接、身份验证 | 2024版

    书接上回,到目前为止,您的应用程序只有一个主页.让我们学习如何使用布局和页面创建更多路线. 在本章之中我们需要讨论: dashboard使用文件系统路由创建路由. 了解创建新路线段时文件夹和文件的作用 ...

  6. Jmeter并发线程场景下共享变量错乱问题解决

    问题复现 问题描述 使用IF控制器获取前一个请求的后置脚本中设置的全局变量->并发线程下通过vars.get获取变量时,第一个线程和第二个线程获取的变量值一样->导致不同基础数据的请求入参 ...

  7. 源码开放:WebSocket应用示例

    1 WebSocket概述 WebSocket是HTML5下一种新的协议(本质上是一个基于TCP的协议),它实现了浏览器与服务器之间的全双工通信,能够节省服务器资源和带宽,达到实时通讯的目的.WebS ...

  8. 《Django 5 By Example》阅读笔记:p651-p678

    <Django 5 By Example>学习第9天,p651-p678总结,总计28页. 一.技术总结 1.aggregate() (1)aggregate:ad-("to&q ...

  9. vue结合element UI做checkbox全选的tree结构

    由于element UI中的tree可能不能满足项目中的样式需求,所以自己动手结合element中的checkbox全选功能实现了一个符合项目需求的tree.效果如下: html部分: <tem ...

  10. 如何在wpf窗口中播放PPT。

    前一段时间接到一个需求(大概内容讲一下): 将PPT播放窗口嵌入到我们的系统中,用自己系统控制PPT的播放,在PPT页面上可以手写将手写内容记录下来. 一开始,对于WPF还是一个彩笔的我是懵逼的.后来 ...