通信协议与序列化方案的纠结: Protocol Buffer, thrift or hessian?

June 2, 2011 by
Filed under: java 

最早我用hessian作为java搜索服务中的通信协议和序列化方案。松耦合,部署,调用方便。这两年很多人跟我提起protocol buffer,thrift。特别是最近从不少地方的信息看到很多地方在用,也找到一些改用protocol buffer或者apache thrift的理由:

1.在趋势科技的时候,病毒清理引擎里面用的也是protocol buffer作为序列化,实际上在Trend,PB用的很广泛。

2. Jeff Dean推荐分布式系统中使用Protocol Description Language。 (理由是协议描述语言支持接口的版本演进,即可以自动忽略不认识的属性,但不是如很多中文文章翻译中所说的为了减少通信的代码量。) 参考:
http://www.parallellabs.com/2010/12/02/jeff-dean-on-google-system-architecture/
http://peopleyun.com/?p=794

3.Quora也在用Protocol Buffer。参考Quora’s Technology Examined

更为重要的是,在我们项目中.net以hessian协议调用java的过程中多次出现接口中的类版本变化,导致无法调用,且hessian并不显示有提示作用的错误信息。 调试和定位问题相当的困难和耗时。因此决定尝试 PB和thrift, 对比了两者, 发现thrift更好用,
1. thrift支持map
2. thrift提供各种语言的RPC实现,不用另外再写RPC服务器。
3. thrift官方原生版本可以自动生成各种语言的客户端,大大减少开发工作量。
参考 ”thrift与protocol buffer的比较
(注意两点,1.有评论者说thrift runtime不支持windows,实际上现在支持的 2.另一个说开始的测试结果表明Hessian比PB要快,但后来重新测试PB要快。)

但不方便的是thrift也同protocol buffer一样,需要编写定义文件, 需要生成代码, 代码中有一堆生成的方法和属性, 不如直接使用Hessian方便, 使用hessian的时候, 要开放服务的接口中压根就不需要增加任何额外的方法和属性。

使用hessian过程中,最大的问题在于前面所描述的,.net调用java hessian服务,当接口中的类版本有变化时,会调用失败。但java调用java hessian并没有这个问题。

后来到stackoverflow上查关于hessian, protocol, buffer的选择问题, stackoverflow上几个人推荐使用简洁、清晰、松耦合的hessian。最终决定仍然使用hessian,不迷信google,迷信quora,不再考虑使用thrift/java。

总结在几者之间选择的考量:
1. 如果你不需要很多语言相互调用, 希望保持清晰的java接口代码(无任何业务不相关的接口继承和方法,属性定义),减少开放工作量,推荐Hessian。

2. 如果你的系统之间传输的数据量不是很大(<2M都不算大), 推荐Hessian。 3. 如果需要支持大数据量的传输,多语言调用,极高的并发支持,推荐使用thrift/protocol buffer。 通常我们并发很难超过1000 req/s,如果超过1000 req/s,在国内互联网排名绝对前5,那么恭喜你。因此一般而言,用Hessian就够了。 Conclusion: don't bother me with Protocol Buffer or Thrift.

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Comments

2 Comments on 通信协议与序列化方案的纠结: Protocol Buffer, thrift or hessian?

  1. 王森林 on Thu, 2nd Feb 2012 3:53 pm
  2. 大哥,我有一个问题,当我使用C#(windows mobile6)用Hessianmobileclient.dll
    1.3.2版本访问java服务器时,提示出错,求解决:
    使用第一种方式:
    IHessianTest test = factory.Create(typeof(IHessianTest), url) as IHessianTest;
    错误:not supported in compact version
    第二种方式反射:
    CHessianMethodCaller methodCaller = new CHessianMethodCaller(factory, new Uri(url));
    MethodInfo mInfo_1 = typeof(IHessianTest).GetMethod(“login”);
    object result = methodCaller.DoHessianMethodCall(new object[] { “999”, “999” }, mInfo_1);
    错误:Could not establish connection to network

  3. euler on Sat, 4th Feb 2012 10:29 pm
  4. windows mobile上的framework不支持第1种方式。 第2种方式连不到网络?