gRPC in ASP.NET Core 3.x -- Protocol Buffer(3)更新消息类型

当你第一次定义Protocol Buffer的消息的时候,你肯定会给消息设定一套规则需求。但是随着时间的推进,你的业务可能会发生了变化,与此同时,你的Protocol Buffer消息类型的需求也会随之变化。

也就是说:有一些字段可能会发生变化,可能会添加一些字段,也可能会删除一些字段。但是可能有很多程序正在使用/读取你的Protocol Buffer的消息,但是它们没法都随着需求进行更新。所以,在你对源数据进行演进的时候,一定不要引起破坏性变化,否则其它的程序可能就无法正常工作了。

 

主要有这两种情景:

  1. 向前兼容变更:使用新的.proto文件来写数据 --- 从旧的.proto文件读取数据 

  2. 向后兼容变更:使用旧的.proto文件来写数据 --- 从新的.proto文件读取数据

有时候这两种情况同时存在,也就是全兼容变更。

 

为了达到此目的,Protocol Buffer制定了一些更新消息类型的规则:

  1. 不要修改任何现有字段的数字(tag)

  2. 你可以添加新的字段,那些使用旧的消息格式的代码仍然可以将消息序列化,您应该注意这些元素的默认值,以便新代码可以与旧代码生成的消息正确交互。类似的,新代码所创建的消息也可以被旧代码解析:旧的二进制在解析的时候会忽略新的字段。

  3. 字段可以被删除,只要它们的数字(tag)在更新后的消息类型中不再使用即可。你也可以把字段名改为使用“OBSOLETE_”前缀而不是删除字段,或者把这些字段的数字(tag)进行保留(reserved),以免未来其它开发者不消息使用了删除字段的数字。

  4. 对于数据类型的变化,例如int32到int64,string到bytes等等,可以参考官方文档:
    https://developers.google.com/protocol-buffers/docs/proto3#updating。但是建议还是尽量不要去修改字段的数据类型。

 

添加字段

原来的proto是这样的:

 

然后我添加一个name字段:

 

而这时,如果把新的消息发送到旧的代码的时候,旧代码不知道2这个数字tag对应的是什么,所以name这个字段就会被忽略掉。

反过来,如果我们使用新的代码读取旧的数据,那么就会找不到新的字段,这时候就会使用该字段类型的默认值(空字符串)。

所以,处理默认值的时候一定要非常的小心

 

对字段重命名

现在我把name这个字段的名改成了full_name,而它的数字不变:

这样做是没有任何问题的。

你可以随意改变字段的名字,只要它的数字tag不变就行,因为Protocol Buffer里面这个数字tag才是最重要的。

 

删除字段

现在我又把full_name字段删除了:

这时候,如果旧的代码找不到这个字段了,那么就会采用默认值。

反过来,如果我们使用新的代码读取旧的数据,那么已删除的字段将会被忽略/丢弃。

 

但是,在删除字段的时候,你应该一直都保留字段的数字tag以及字段名,像这样:

这样做是防止数字tag和名称被重复使用,避免在以后的代码库里造成冲突。

 

使用OBSOLETE

之前说了,可以把字段名改为 OBSOLETE_字段名 来代替删除字段,但是这样做的缺点就是:你还是需要把这个字段的值计算出来。我还是建议使用reserve的方式进行删除字段的管理。

 

Reserved

  • 你可以保留字段的数字tag和字段名;

  • 但是不可以在同一行语句里混合reserved数字tag和字段名,应该分成两个语句:

 

  • 保留字段数字tag的目的就是防止数字tag被重复使用;

  • 而保留字段名的目的就是防止出现一些程序bug;

注意:一定不要移除reserved的数字tags。

 

默认值

默认值在更新Protocol Buffer消息定义的时候有很重要的作用,它可以防止对现有代码/新代码造成破坏性影响。它们也可以保证字段永远不会有null值。

但是,默认值还是非常危险的:

  • 你无法区分这个默认值到底是来自一个丢失的字段还是字段的实际值正好等于默认值。

那么应该怎么办?

  • 需要保证这个默认值对于业务来说是一个毫无意义的值。例如 int32 pop(人口)默认值就可以设置为-1。

  • 再就是,可能需要在你的代码里来做一些对默认值的判断,从而进行处理。

 

枚举

enum同样可以进化,就和消息的字段一样,可以添加、删除值,也可以保留值。

但是如果代码不知道它接收到的值对应哪个enum值,那么enum的默认值将会被采用。

例如这个enum:

如果程序代码接收到了5这个数值,那么它找不到对应的枚举值,所以就会使用这个枚举的默认值0(UNSPECIFIED)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opengl如何画出一个球_少儿美术绘画教程:毛线球

小朋友们,你们平时画画有没有遇到过没有灵感的时候,面对画纸却不知道画些什么呢?今天我们来介绍一种创意思维,叫发散性思维。以一个毛线球为出发点。通过毛线球,我们可以想到圆球,通过圆球我们可以想到圆形…

数据结构---后序和中序遍历的二叉树序列还原二叉树

数据结构—后序和中序遍历的二叉树序列还原二叉树 代码&#xff1a; #include<stdio.h> #include<stdlib.h> typedef struct bstTree {char data;struct bstTree* lchild, *rchild; }bstTree; bstTree * reStoreTree(char* pre, int preSt, int preEnd, char *mi…

Asp.Net Core 混合全球化与本地化支持

前言最近的新型冠状病毒流行让很多人主动在家隔离&#xff0c;希望疫情能快点消退。武汉加油&#xff0c;中国必胜&#xff01;Asp.Net Core 提供了内置的网站国际化&#xff08;全球化与本地化&#xff09;支持&#xff0c;微软还内置了基于 resx 资源字符串的国际化服务组件。…

最大连续子数组和 动态规划_剑指Offer算法题 33:连续子数组的最大和

题目描述HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢&#xf…

数据结构---顺序查找和二分查找

数据结构—顺序查找和二分查找 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> int n;//查找元素数组的长度 void seqCheckValue1(int* a) {//顺序查找1,有越界判断int v a[0];for (int i 1; i < n; i) {if(a[i…

git上托管的代码如何部署在阿里云上_居然仅用浏览器搞定Spring Boot应用的开发与部署...

最近有幸试用了一下阿里云的一个新产品&#xff1a;云开发平台&#xff0c;体验一把全新的开发模式&#xff01;虽然中间也碰到了一些问题&#xff0c;但整体的体验透露着未来感&#xff0c;因为整个过程都不需要使用我们最常用的IDEA&#xff0c;仅依靠浏览器就把一个Spring B…

Kubernetes 与 Helm:使用同一个 Chart 部署多个应用

k8s 集群搭建好了&#xff0c;准备将 docker swarm 上的应用都迁移到 k8s 上&#xff0c;但需要一个一个应用写 yaml 配置文件&#xff0c;不仅要编写 deployment.yaml 还要编写 service.yaml &#xff0c;而很多应用的配置是差不多的&#xff0c;这个繁琐工作让人有些望而却步…

数据结构---BF字符串模式匹配

数据结构—BF字符串模式匹配 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> int BF(char * S, char* T,int pos,int n,int m) {//暴力算法求解子串T在S中第一次出现的位置int i pos, j 0;while (i < n &&a…

windows系统如何cmake_Windows操作系统如何快速增加分区?建议收藏

现在新买的电脑大都是出厂单分区的设置&#xff0c;也就是只有系盘C&#xff0c;没有D、E之类。于是也问过厂商的工作人员&#xff0c;得到的答复是恢复备份的机制已经十分完善&#xff0c;保证用户使用安全毫无问题。不过&#xff0c;相信小伙伴们和我一样&#xff0c;内心还是…

大白技术控 | Windows10X 模拟器简单上手体验

点击蓝字“大白技术控”关注我哟加个“星标★”&#xff0c;每日 19:30&#xff0c;好文必达&#xff01;前言Windows10X 和 Windows10 有什么区别&#xff1f;当这个问题摆在我面前的时候&#xff0c;我就脱口而出&#xff1a;区别&#xff1f;双屏了呗&#xff01;这个答案有…

word List 21

word List 21 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

Asp.Net Core Identity 骚断腿的究极魔改实体类

前言默认的 Identity 实体类型在大多数时候已经基本够用&#xff0c;很多时候也只是稍微在 IdentityUser 类中增加一些自定义数据字段&#xff0c;比如头像。这次&#xff0c;我要向园友隆重介绍我魔改之后的 Identity 实体类&#xff0c;能支持一些特别风骚的操作。当然也完全…

[蓝桥杯2015决赛]四阶幻方

题目描述 把1~16的数字填入4x4的方格中&#xff0c;使得行、列以及两个对角线的和都相等&#xff0c;满足这样的特征时称为&#xff1a;四阶幻方。 四阶幻方可能有很多方案。如果固定左上角为1&#xff0c;请计算一共有多少种方案。 比如&#xff1a; 1 2 15 16 12 14 3 5 13 7…

数据结构---模式匹配

数据结构—模式匹配 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #define N 100 int next[N]; void getNext(char *T,int *next,int m) {//求解当前字符前面的最大公共前缀和后缀int j 1,k0;next[j] 0;//从1开始…

CKEditor 4编辑器已与Vue.js集成

虽然 CKEditor 4 不是目前主要维护的分支&#xff0c;不过官方并没有让它落后于潮流。近日&#xff0c;CKEditor 团队发布了与 Vue.js 框架原生集成的 CKEditor 4。这就意味着&#xff0c;开发者可以通过<ckeditor />标签以 Vue.js 组件的形式使用 CKEditor 4 &#xff0…

[蓝桥杯2016初赛]卡片换位-bfs

题目描述 你玩过华容道的游戏吗&#xff1f;这是个类似的&#xff0c;但更简单的游戏。看下面 3 x 2 的格子 在其中放5张牌&#xff0c;其中A代表关羽&#xff0c;B代表张飞&#xff0c;* 代表士兵。还有一个格子是空着的。 你可以把一张牌移动到相邻的空格中去(对角不算相邻…

数据结构---KMP模式匹配病毒感染人的DNA检测

数据结构—KMP模式匹配病毒感染人的DNA检测 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #define N 100 int next[N]; void getNext(char *T, int *next, int m) {//求解当前字符前面的最大公共前缀和后缀int j …

推荐一个很棒的开源工作流elsa-core

开源项目orchard主要开发人员Sipke Schoorstra 开源了一个netcore 工作流项目&#xff0c;地址&#xff1a;https://github.com/elsa-workflows/elsa-core&#xff0c;最新版本1.2&#xff0c;正在开发2.0版本 。Spike 是参照Orchard Core的工作流引擎的原理&#xff0c;将其转…

WTM系列视频教程:MVVM

WTM系列视频教程第三章&#xff1a;MVVM文字摘要&#xff1a;“要讲MVVM模式&#xff0c;我们先来讲一下传统的MVC模式&#xff0c;要讲MVC模式&#xff0c;我们先来讲一下没有模式。。。”“为了演示没有模式&#xff0c;咱们整个项目就保留一个Program.cs文件&#xff0c;不使…

word List 22

word List 22 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;