端到端轻量化网络通信协议设计方案

背景

        当前的产品端到端使用的数据交换协议是JSON,对于数据量大的客户来说,数据存储成本以及带宽的消耗已经成为整个产品的一大支出。在这种背景下,需要对数据交换协议进行优化,达到减少网络带宽以及存储消耗,提升数据传输效率

方案

       针对上述的背景,可以从两个方向来考虑问题:

  • 在当前协议类型不变的前提下进行转码或者数据格式转换,从而达到数据体积缩小的目的
  • 另起炉灶,彻底改变当前JSON的传输方式,改用其他高效率的数据传输协议(如protocolbuffer)

      下面分情况讨论下两种方案:

局部优化

不言而喻,在json基础上进行优化的好处就是改动量小,风险小,能够快速迭代,架构侵入较小,所以优先介绍该方案,并且该方案中的部分优化机制在下面的一个方案中同样适用。 首先先介绍下通用的优化方案:

  • 格式转换
  • 数值转换
  • 编码转换

格式转换

针对固定格式的数据,使用一定的规则进行转换,变成较小的消息体或者格式进行传输,包含如下几个规则:

  • 所有IP从字符串转化为int类型

  • 所有日期和时间转化为10位int类型

  • 所有的经纬度信息转化为geohash

这些规则直观上能减少相关类型数据的总长度,进而减少带宽消耗。如果不使用JSON而换成区分数据类型的协议(如protocolbuffer),则效果更明显

数值转换

针对固定格式的数据,使用一定的规则进行转换,削减数值的位数进行传输,包含如下几个规则:

  • 时间采用新格式进行存储,使用天数+绝对秒数的格式,具体如下:取一天的绝对秒数,最大值为86400,也就是5位。天数的位数取决于需要支持数据处理的时间段,如果处理一周内的数据,则只需要存星期数,1位即可,则时间总长度为6;如果处理一月内的数据,则只需要存DAY_OF_MONTH,最多2位即可,则时间总长度为6-7;如果处理一年内的数据,则只需要存DAY_OF_YEAR,最多3位即可,则时间总长度为6-8。解析时使用当前的DAY与解析后的DAY进行比较,如果是大于关系,则说明两者在同一周期内;如果是小于关系,则说明数据时间在上一周期内。根据此关系进行相应的处理即可;
  • 对于部分字符串,如域名或者包名等格式相近的字符串,部分子串重复率极高,如com、android、org等,可以使用特殊标识在客户端进行转码传输,在服务端进行解码;

编码转换

针对JSON的key或者value中类似枚举或者值固定的数据,进行转码传输,包含如下几个规则:

  • 原JSON的key全部编码,在客户端编码进行传输,在服务端解码,在减小消息体的同时,也提升了消息的安全性
  • 针对部分value是枚举类型或者固定值的情况,对这部分值进行编码转换,在服务端解析,在减小消息体的同时,也提升了消息的安全性

整体优化

上面是通用的优化规则,也是局部优化方法,下面说一下整体优化的思路,主要分为以下几点:

  • 硬编码 vs 可配置
  • 字符串  vs 字节流
  • JSON+gzip vs protocolbuffer

硬编码 vs 可配置

        上面的通用方案中都存在编码转换的需求,那么针对这么需求,转换的规则是硬编码还是可配置就需要界定下。当前我认为对于基本上不会改变的值,如国家以及操作系统类型这种直接约定好规则两端同时编解码即可;对于可能存在变化的值,如域名中重复率较高的值可以做成可配置的规则,随时追加或者删除,在服务端更新,通过http请求的返回值将相关的更新上行到客户端。

        此外,可以通过key的拼接来完成对value的解析,如“处理方式+key编码”,通过key的编码解析来获取对应value的含义,然后将通用value处理方式也同样进行编码,在服务端解码后对value进行反解析得到原始值。这种方式兼顾了数据加密,数据体积减少以及处理方式可配置可扩展的需求。

字符串 vs 字节流

      字符串协议代表性的实现就是JSON,JSON的好处就是通用的、跨平台、跨语言且可读性强,这些优势相当强大,但是JSON为代表的字符串协议同样有自己的缺点:

  • JSON为了达到易读性使用字符串来存储所有数据,这对于非字符串的数据来说,如float或者double类型的数据,会带来存储浪费以及精度损失。如9999.999999F,这种32位的浮点数在内存中占用为4 bytes的空间,而如果使用字符串存储使用的utf8方式来存储的话,则需要占用11 bytes,对于JavaScript使用utf16表达字符串的环境中,需要占用 22 bytes的空间,空间的浪费可见一斑
  • JSON使用正则表达式进行数据解析,在面对非字符数据时显得十分低效,不仅要耗费大量的运算解析数据结构,还要将字面量转换成对应的数据类型。

       而字节流协议的特点恰好与字符串协议的特点相反,即可读性差,跨语言和跨平台会有限制,但是数据按类型存储,按类型解析,不管是大小还是效率都会更高。所以如果排除可读性的因素,在跨平台支持允许的条件下,字节流协议的效率以及成本应该会比字符串协议好一些。尤其在字符串协议为了减小消息体牺牲可读性而使用gzip压缩的前提下

JSON+gzip VS protocolbuffer

       书接上文,这两种方式应该是字符串协议以及字节流协议两者方式的代表。由于JSON使用了gzip,所以JSON在可读性上的优势已经被抵消;至于跨平台,protocolbuffer能够支持java,C以及JavaScript,基本上能够满足业务上的需求,所以这点也不必考虑了,剩下的就是数据体积以及处理速度的比较了。

       经过特点分析以及数据测试,在JSON开启了gzip压缩的前提下,数据体积上基本上和protocolbuffer不相上下。整体来说,JSON更擅长和适合处理字符串,而protocolbuffer更擅长和适合处理数值类型;在处理速度上,protocolbuffer在处理字符串上和JSON差距不明显,略优于JSON,而处理数值类型的时候,protocolbuffer优势明显,处理速度和效率是JSON的几倍甚至十几倍。

结论

       从上述结论来看,protocolbuffer还是比json更有优势一些,但是有两个问题需要验证以及评估:

  • 穿透性测试:JSON的穿透性毋庸置疑,肯定是最好的,而protocolbuffer的穿透性网上的资料以及数据比较少。能查到的是腾讯的IM的网络协议数据传输使用到了protocolbuffer,所以需要在现实环境中进行网络穿透性测试。
  • 架构侵入:protocolbuffer对于整个架构以及接口的侵入性还是比较强的,所以为了适配protocolbuffer,还是需要不少工作量的,涉及到客户端以及服务端,这个需要仔细评估。

      综上,建议先对上面的通用优化方案进行落地,不管是JSON还是protocolbuffer都会从此受益,后续根据业务需求以及工期安排,将protocolbuffer的改造作为一个大的改进点加入到某一个迭代中实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值