使用 Protocol Buffers 代替 JSON 的五个原因
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html
内部邀请码:C8E245J (不写邀请码,没有现金送)
国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为“中国PE第一股”,市值超1000亿元。
------------------------------------------------------------------------------------------------------------------------------------------------------------------
在Ruby和Rails开发者中,面向服务(Service-Oriented)架构有一个当之无愧的名声,它是一个缓解程序规模恶性增长的一个强有力的途径,可在大量应用程序中提取关注点。这些新生小巧的服务通常继续使用Rails或Sinatra,并使用JSON在HTTP上通信。尽管JSON作为一个数据相互交换格式,有很多优点:人类可读、可理解,并通常表现出色。
浏览器和JS并不直接处理数据--尤其是遇到内部服务时。我的观点是,结构化格式,例如谷歌的Protocol Buffers,是一个比JSON在编码方面更好的选择。如果你从来没有使用过Protocol Buffers,你可以参看 这里。不要担心,在说明为什么要选择Protocol Buffers而不是JSON之前,本文会简介如何使用在Ruby上使用它 。
Protocal Buffers的简短介绍
首先,什么是Protocol Buffers?文档中说:
“Protocol Buffers是一种以有效并可扩展的格式编码结构化数据的方式。”
Google开发了Protocol Buffers使用于内部的服务。 它是一种二进制格式允许你使用规范的语言定义一个模式,例如:
1
2
3
4
5
|
message Person { required int32 id = 1; required string name = 2; optional string email = 3; } |
你能在命名空间中封装他们或者用上面的方式在顶层声明他们。这个片段定义了Person数据类型的模式,有三个字段:id, name和email。除了命名字段,你能提供一个类型决定数据怎样编码和在线上发送,在上面我们看到有int32类型和string类型。还提供了关键字进行验证和结构化(required 和optional )。字段被编号,这有助于向后兼容,我将在以后详细的介绍。
Protocol Buffers规范已被多种语言实现:Java,C,Go等。如果你四处找找最现代的语言都有实现的方式。Ruby也不例外,有几个不同的Gems使用Protocol Buffers编码和解码数据。这就意味着,这个规范可以在不同语言实现的系统间传递数据。
例如,Ruby Gem安装被称为ruby-protoc的二进制可以和主Protocol Buffers库组合使用(在OSX中brew install protobuf),自动的产生桩类文件用于编码和解码数据。正在运行的二进制proto文件产生以下的Ruby类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/usr/bin/env ruby # Generated by the protocol buffer compiler. DO NOT EDIT! require 'protocol_buffers' # forward declarations class Person < ::ProtocolBuffers::Message; end class Person < ::ProtocolBuffers::Message set_fully_qualified_name "Person" required :int32 , :id , 1 required :string , :name , 2 optional :string , :email , 3 end |
正如你所见,通过支持这种模式(Protocol Buffer格式),用来编码和解码信息,我们就能自动得到一个类(查看代码ProtocolBuffers::Message的基类在Gem中有更多细节的介绍)。我们已经看到了一些信息,那么就让我们再来仔细看看这些特征点,让我尝试说服你考虑Protocol Buffers——这里有5个理由。
原因 #1: 模式本身很不错
有一种痛苦的讽刺指向一个事实,我们小心谨慎地在我们的数据库里面编写数据模型,维护各个层次的代码,保持这些数据模型处于控制之中,当我们想要发送数据连接到另一个服务的时候,要求所有的疑虑都要被考虑到。然而,我们往往依靠的是在边界上与我们的系统之间不一致的代码,我们的系统不能强制结构化我们的数据组件,这是如此的重要,编码的语义是你曾经的业务对象,在proto格式中,它足以帮助并保证应用程序之间的信号不会丢失,而界限就在你所创建并执行的业务规则。
原因 #2: 无偿地向后兼容
被编号的字段在proto的定义中排除了所需的版本检查,这是其中一个被明确表述的动机(为什么这样设计和实现Protocol Buffers)。如同开发者文档中声明的那样,协议被设计成能在一定程度上避免出现像下面这样的“丑陋的代码”,下面的代码用来检测协议的版本:
1
2
3
4
5
6
7
8
|
if (version == 3 ) { ... } else if (version > 4 ) { if (version == 5 ) { ... } ... } |
同编号字段一样, 你必须改变编码习惯,朝着能向老版本维护和向后兼容的方向改变。正如在文档中的声明那样,曾经 Protocol Buffers 是这样被介绍的:
“新的字段可以很容易被引入,并且不需要中间服务去检查数据就能被解析,通过数据不必知道所有的字段。”
已经部署各种JSON的服务器已经遭受各种与发展模式以及向后兼容的相关问题。我现在深信编号字段能防止错误,并且能在新功能和服务的推出上做到简化。
原因 #3: 更少的样本代码
除了显式的版本检查和缺乏后续的兼容性,JSON终端在HTTP上的基础服务通常依赖专门的手写样板代码去处理Ruby对象的编码和解码。解析和反解析类常常包含隐藏的业务逻辑,它暴露了手动解析每个新的数据类型的缺陷,当一个类通过Protocol Buffers产生(你一般就不会再去触碰它),它能提供大量相似的方法,还避免了大量头痛的事情。随着模式的发展,你将会用proto产生类(应当承认,一旦你更新他们),你可以把更多的空间留给你所关注的挑战(保持你的应用运行和持续构建产品)。
原因 #4: 验证和可扩展性
required,optional 和 repeated关键字在Protocol Buffers中的定义是非常强大的。它们允许你去编码,在模式级别,形象化你的数据结构和去实现类怎样工作(每种编程语言处理)的细节。Ruby的protocol_buffers库将会提升异常,例如:如果一个对象实例没有填写必填的字段,你试着去对这样一个对象实例编码,就会提升异常。通过简单地编辑一个新的编号字段的值,你可以把一个字段从required变成optional或者反之亦然。有了这种灵活编码的语义序列化格式,大大增强了其功能。
因为你还可以嵌入proto,定义内部的其他成员,你也可以拥有通用的Request和Response结构,它还允许其他数据结构的传输并确保传输连接上,它为服务器间通讯实现真正的灵活性和安全的数据传输提供了机会。类似Riak的数据库系统使用Protocol Buffers有巨大的效果——因为有了一些启示,我建议重新审视那些接口。
原因#5:建议的语言互操作性
因为Protocol Buffers已经被多种语言实现,在你的架构中多语言混合的应用程序之间的互操作性变得更简单。如果你引入了一个新的服务在JAVA或者GO中,甚至和用Node或者Clojure或者Scala实现的后端通讯,你只需简单的把proto文件交给目标语言编写的代码生成器,你将在这些架构之间获得较好的安全和互操作性。平台特定数据类型的细节被目标语言处理,你将更多的关注你的问题的困难部分,而不是匹配字段和数据类型在JSON的编码和解码方案中。
什么时候更适合使用JSON?
有些时候JSON比Protocol Buffers更适合,包括如下的场景:
你需要或者想让数据对人是可读的
来自于服务的数据是直接发送到web浏览器
你的服务端应用程序是用javaScript编写的
你不准备把数据模型绑定到模式上
你没有带宽添加另外一个工具到你的军火库
运行不同类型的网络服务的运营负担过大
可能还有更多的情况。最后,总之,这是很重要的在心里权衡和不要盲目的选择一项技术
结论
Protocol Buffers提供了几种相对JSON在内部服务之间在线传输数据的引人注目的优势。并没有完全的替换JSON,特别是服务和web浏览器直接通讯的情况,Protocol Buffers提供了真正的优势不仅在上面概述的方法,也编解码的速度和数据大小上有更多的优势。
你可以从你的应用程序中提取出哪些服务?如果你今天不得不做出选择,你会选择JSON还是Protocol Buffers?让我们讨论讨论-我们愿意在下面的评论中听到更多关于你在使用JSON和Protocol Buffers上的经验。
使用 Protocol Buffers 代替 JSON 的五个原因的更多相关文章
- protocol buffers vs json vs XML
原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com 在分布式系统中,数据序列化传递的情形非常常见,主流的三种,JSON.XML.Protobuf. XML现在 ...
- Protocol buffers--python 实践(二) protocol buffers vs json
为什么专门开一个坑,来使用pb.放弃本在各平台上都支持得很好的json而使用pb的一个归根到底的理由,就是希望在保证强类型和跨平台的情况下,能够更轻,更快,更简单.既然是奔着这个目标去的,到底多快我需 ...
- golang gin框架中使用protocol buffers和JSON两种协议
首先,我使用protobuf作为IDL,然后提供HTTP POST + JSON BODY的方式来发送请求. 能不能使用HTTTP POST + PB序列化后的二进制BODY呢? 做了一下尝试,非常简 ...
- Protocol Buffers(1):序列化、编译与使用
目录 序列化与反序列化 Protocol Buffers概览 Protocol Buffers C++ 编译 Protocol Buffers C++ 使用 Protocol Buffers的可读性 ...
- Xml,Json,Hessian,Protocol Buffers序列化对比
简介 这篇博客主要对Xml,Json,Hessian,Protocol Buffers的序列化和反序列化性能进行对比,Xml和Json的基本概念就不说了. Hessian:Hessian是一个轻量级的 ...
- 让Web API支持Protocol Buffers
简介 现在我们Web API项目基本上都是使用的Json作为通信的格式,随着移动互联网的兴起,Web API不仅其他系统可以使用,手机端也可以使用,但是手机端也有相对特殊的地方,网络通信除了wifi, ...
- C#/net 使用Protocol Buffers入门
Protocol buffers 是一个由谷歌开发的开源的编码机制用于将结构化的数据序列化或者反序列化,被设计成语言以及平台中立,protobuff比xml更简单比json还要紧凑一些,网上有一些关于 ...
- protocol buffers的使用示例[z]
[http://blog.csdn.net/zhu_xun/article/details/19397081] protocol buffers的使用示例 如果不了解protocol buffers, ...
- 理解netty对protocol buffers的编码解码
一,netty+protocol buffers简要说明 Netty是业界最流行的NIO框架之一优点:1)API使用简单,开发门槛低:2)功能强大,预置了多种编解码功能,支持多种主流协议:3)定制能力 ...
随机推荐
- Android内存控制小技巧-使用矢量图来节省你的内存并简化你的开发。
先上一个 位图和矢量图的 说明.http://zhidao.baidu.com/link?url=xwvs5CBzWeh15O3Ee4bICwCqg4PCQWwg5oZ0a6CVydbVZzufqrI ...
- 如何定义java中的类
3步走,如下示例代码所示: package com.imooc; //1.定义一个类 public class Telphone { //2.属性(成员变量)有什么 float screen; flo ...
- 使用Jquery Mobile设计Android通讯录
本系列教程将指导大家一步步使用Jquery Mobile设计一个Android的通讯录应用.其中在应用的界面部分,将使用jQuery Mobile框架,并且会指导大家如何使Android中提供的web ...
- hdu 2732 Leapin' Lizards(最大流)Mid-Central USA 2005
废话: 这道题不难,稍微构造一下图就可以套最大流的模板了.但是我还是花了好久才解决.一方面是最近确实非常没状态(托词,其实就是最近特别颓废,整天玩游戏看小说,没法静下心来学习),另一方面是不够细心,输 ...
- 使用命令行设置svn忽略列表
Windows 上的 TortoiseSVN 设置 svn 的忽略列表是非常方便的,但是在Mac OS X上,好用的图形化 svn 客户端都有点儿贵,比如 Versions 和 CornerStone ...
- DuiLib消息处理剖析
本来想自己写写duilib的消息机制来帮助duilib的新手朋友,不过今天发现已经有人写过了,而且写得很不错,把duilib的主干消息机制都说明了,我就直接转载过来了,原地址:http://blog. ...
- css3 --- 翻页动画 --- javascript --- 3d --- 准备
用css3和javascript做一个翻页动画<知识准备部分> 如有更多疑问请参照:http://www.imooc.com/learn/77 这是用css3的-webkit-transi ...
- ansible命令执行模块使用
ansible命令执行模块使用 1.命令执行模块-command 在远程节点上运行命令. 命令模块使用命令名称,接上空格-的分割符作为参数使用,但是不支持管道符和变量等,如果要使用这些,那么可以使用s ...
- MVC dropdownlist使用
View中代码 @{ ViewBag.Title = "dropdownlist"; } <h2>dropdownlist</h2> @using (Htm ...
- Iframe的应用以及父窗口和子窗口的相互访问
点评:Iframe和FRAME的区别,方便大家以后在使用过程中根据实际需要取舍.- function getParentIFrameDocument(aID) { var rv = null; // ...