以小见大——那些基于 protobuf 的五花八门的 RPC(5 完)
赖勇浩(http://laiyonghao.com)
快刀斩乱麻,祭上最后两个 rpc 分析,再整上我自己的设计,这个系列就完结了。
protobuf-socket-rpc
好,废话不多说,看看这个 protobuf-socket-rpc,简介是 Java and Python protobuf rpc implementation using tcp/ip sockets,听说支持 java 的服务器和 python 的客户端,有点怪怪地哈?基本格式见:http://code.google.com/p/protobuf-socket-rpc/source/browse/trunk/proto/rpc.proto ,引用全文如下:
package protobuf.socketrpc; option java_package = "com.googlecode.protobuf.socketrpc"; option java_outer_classname = "SocketRpcProtos"; message Request { // RPC service full name required string service_name = 1; // RPC method name required string method_name = 2; // RPC request proto required bytes request_proto = 3; } message Response { // RPC response proto optional bytes response_proto = 1; // Error, if any optional string error = 2; // Was callback invoked optional bool callback = 3 [default = false]; // Error Reason optional ErrorReason error_reason = 4; } // Possible error reasons // The server-side errors are returned in the response from the server. // The client-side errors are returned by the client-side code when it doesn't // have a response from the server. enum ErrorReason { // Server-side errors BAD_REQUEST_DATA = 0; // Server received bad request data BAD_REQUEST_PROTO = 1; // Server received bad request proto SERVICE_NOT_FOUND = 2; // Service not found on server METHOD_NOT_FOUND = 3; // Method not found on server RPC_ERROR = 4; // Rpc threw exception on server RPC_FAILED = 5; // Rpc failed on server // Client-side errors (these are returned by the client-side code) INVALID_REQUEST_PROTO = 6; // Rpc was called with invalid request proto BAD_RESPONSE_PROTO = 7; // Server returned a bad response proto UNKNOWN_HOST = 8; // Could not find supplied host IO_ERROR = 9; // I/O error while communicating with server }
很眼熟啊,是的,跟之前看过的 fepss-rpc 几乎一样,除了这里定义了更多的错误类型,连注释都几乎一模一样啊,不知道谁抄谁的。所以没啥好说的了,唯一可以唠叨一下的是它跟 fepss-rpc 都采用无 ID 的设计,所以不能 parallel pipelining,细节见(http://blog.csdn.net/lanphaday/archive/2011/04/11/6316099.aspx )。
txprotobuf
以 Python 始,再以 Python 终,最后一个是 protocol buffers (http://code.google.com/p/protobuf/) RPC implemented using python twisted framework.,基于 twisted 的 rpc,虽然我不喜欢 twisted,但不影响我看 txprotobuf 哈。它的基本格式见:http://bazaar.launchpad.net/~proppy/txprotobuf/master/view/head:/protobuf/txprotobuf.proto ,照例全文引过来:
// Copyright (c) 2008 Johan Euphrosine // See LICENSE for details. message Call { required uint32 token = 1; required string method = 2; required bytes request = 3; } message Result { required uint32 token = 1; required bytes response = 2; } message Box { optional bytes call = 1; optional bytes result = 2; }
简洁,跟 casocklib 相似的设计。唯一能够说一下的就是只有 method 字段而没有 service 字段所以没有办法做到 multi-service。另外,Box 这个命名我很喜欢。
我自己的设计
本来想单独作为一篇的,后来发现前两个实在没啥好说啊,干脆就整合在一起得了。好,上代码:
enum PackageType { HEARTBEAT = 0; ERROR = 1; REQUEST = 2; RESPONSE = 3; }; message Heartbeat { }; message Error { required string info = 1; }; message Request { required string service = 1; required string method = 2; optional bytes request = 3; }; message Response { optional bytes response = 1; }; message Package { required PackageType type = 1; required uint32 identify = 2; required bytes serialized = 3; }; message Placeholder { };
首先是学习 server1 定义了几种数据包的类型,不过我扩展了一下,加了心跳和错误这两种包。心跳在这里就是简单的一个空包,只是激活一下 TCP 连接,以免超时断开。如果要复杂一点的,可以参考陈硕《分布式系统的工程化开发方法》 p.51 心跳协议的设计(http://blog.csdn.net/Solstice/archive/2010/10/19/5950190.aspx )。
message Error 很简单,只有一个 info 字段。之前也在想要不要加个数字枚举来让调用端了解一下基本出了啥错,后来我想还是不要了。主要是出错了对于调用端来说没有什么挽救手段啊,只能是往日志里写一句,然后该干啥干啥去,既然如此,又何必多此一举呢,直接把错误的文本从服务器端传过来就好了。
message Request 带了 service 和 method 字段,为的是明晰地表达咱支持 multi-service。而的 request 字段是 optional 的,为的是支持“空”参数调用 RPC。Message Response 的 optional bytes response 也是类似,为了支持“空”返回值。因为 protobuf 的 rpc 声明不支持 rpc XXX()returns() 这样的无参数无返回值的声明,所以我又在后面声明了一个 message Placeholder,这样 rpc 声明就可以写成 rpc XXX(Placeholder)returns(Placeholder)。调用代码时,可以直接写成 proxy.service.XXX() 这样子,由我们自己的 Proxy/Channel 实现去处理好这个占位参数和返回值就行了。
最后,整个连接上传输的数据包就只有一种:message Package,不论是 Heartbeat、Error、Rquest 或 Response,最后都会序列化到 Package.serialized 里去。
对比这么多实现,我的这个版本既没有像 protobuf-remote 般自由开放的调用参数机制,也没有 protobuf-rpc-pro 可以返回超大块数据的内置方案。不过我还是比较满意,太自由和太重量的方案不符合我的技术观。
我打算基于 gevent 实现这个 rpc。
===== 完 ======
以小见大——那些基于 protobuf 的五花八门的 RPC(5 完)相关推荐
- 以小见大——那些基于 protobuf 的五花八门的 RPC(2)
赖勇浩(http://laiyonghao.com ) 多看了三五个 rpc 实现之后,这个事儿就变得很有趣了,今儿来看 fepss-rpc 和 casocklib,分别基于 java 和 C++ 开 ...
- 以小见大——那些基于 protobuf 的五花八门的 RPC(4)
赖勇浩(http://laiyonghao.com ) protobuf-rpc-pro 不知道你还记不记得 protobuf-rpc,这货在后面加了个 pro,就真的重量级了许多.照例先看看简介:A ...
- 以小见大——那些基于 protobuf 的五花八门的 RPC(3)
赖勇浩(http://laiyonghao.com ) protobuf-remote 嘎~再来一枚 C++ 系的 RPC,它的简介是 RPC implementation for C# and C+ ...
- 以小见大——那些基于 protobuf 的五花八门的 RPC(1)
赖勇浩(http://laiyonghao.com ) Google protobuf(http://code.google.com/p/protobuf)提供了 service 关键字来描述 RPC ...
- 基于Protobuf的分布式高性能RPC框架——Navi-Pbrpc
基于Protobuf的分布式高性能RPC框架--Navi-Pbrpc 二月 8, 2016 1 简介 Navi-pbrpc框架是一个高性能的远程调用RPC框架,使用netty4技术提供非阻塞.异步.全 ...
- netty 基于 protobuf 协议 实现 websocket 版本的简易客服系统
https://segmentfault.com/a/1190000017464313 netty 基于 protobuf 协议 实现 websocket 版本的简易客服系统 结构 netty 作为服 ...
- CNN应用之基于Overfeat的物体检测-2014 ICLR-未完待续
转载自:深度学习(二十)CNN应用之基于Overfeat的物体检测-2014 ICLR-未完待续 - hjimce的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/ ...
- CNN应用之基于R-CNN的物体检测-CVPR 2014-未完待续
转载自: 深度学习(十八)CNN应用之基于R-CNN的物体检测-CVPR 2014-未完待续 - hjimce的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/hj ...
- 基于Protobuf的通讯库--Poppy简介
引言: 2011年12月,基础架构部总经理暨搜索业务线首席架构师朱会灿以<云计算平台的构架,设计和实现>为主题为大家做了一次技术讲座,对我们的"台风"云计算平台做了介绍 ...
最新文章
- 对象不支持“handleError”属性或方法 ajaxfileupload.js
- OpenCV差分二值化的实时场景文本检测的实例(附完整代码)
- windows和centos进行文件上传和下载
- python argv参数
- hdu 1565 方格取数(1)
- python去除图像光照不均匀_CVPR 2020 | 从重建质量到感知质量:用于低光照增强的半监督学习方法...
- python 消息框但不影响程序执行_还在用print()查找错误?日志消息不香嘛?| 原力计划...
- 强烈推荐:给去美国的新生说几句(转载),超实用
- 明小子动力上传拿webshell(1).zip
- 我如何进行简历的筛选与人员的选择
- ROS的学习(三)创建一个工作空间
- 第四章——变换域处理方法
- 【MVC】VS常用技巧
- Android LED电子表时钟字体digital font
- 微信扫一扫不能打开APK下载链接的问题
- 玩转基因组浏览器之IGV展示bam文件
- Java实现扫码枪二维码自动跳转网页(基于键盘监听)
- 规模决定利润 网吧规模扩充升级参考方案(转)
- Android密码管理器app
- 英文学习20171221