2019独角兽企业重金招聘Python工程师标准>>>

##开始

Avro是Apache的Hadoop家族的项目之一。具有性能高、基本代码少和产出数据量精简等特点。不过这是他们宣传广告,我最近也分别研究了Avro和Protobuf。基本的测试代码,不吐不快。

##安装

###Java

Avro是应运Hadoop而生的,因此主要也是以Java写就。 Java的安装比较简单,往项目中放入Avro及Avro-rpc的jar包便可。我喜欢使用Maven,因此Maven坐标如下:

<dependency><groupId>org.apache.avro</groupId><artifactId>avro</artifactId><version>1.7.2</version>
</dependency><dependency><groupId>org.apache.avro</groupId><artifactId>avro-ipc</artifactId><version>1.7.2</version>
</dependency>

###Python

熟悉Python模块安装应该很简单。avro的Python模块可以在 [https://pypi.python.org/pypi Python][https://pypi.python.org/pypi] 下载。下载<code>tar.gz</code>或者<code>zip</code>解压到硬盘任意目录。

打开终端,并用cd切换到avro解压的目录,执行:

python setup.py install

Ubuntu系统需要Root权限:

sudo python setup.py install

如果没有看到特殊的错误,一般都能顺利安装上。

##协议[Protocol]

Avro协议是以JSON结构性描述文本。协议定义了基本的通信的数据类型,名称。并且还包含可调用的方法等。如下我的示例是一个实现简单的HelloWord程序。

<pre class="prettyprint lang-javascript"> { "namespace":"avro", "doc":"This is a message.", "protocol":"messageProtocol", "name":"HelloWorld", "types":[ { "name":"nameMessage", "type":"record", "fields":[ {"name":"name", "type":"string"} ] } ], "messages":{ "sayHello":{ "doc":"say Hello to manbers", "request":[ { "name":"name", "type":"string" } ], "response":"nameMessage" } } } </pre>

我把它命名为helloward.json。之所以我命名为json后缀的文件是因为很多编辑器都能认识,并且还能格式化。<<Hadoop权威指南>>中命名为avro后缀的文件,这点在编辑器中支持不是很好。并且Avro协议是不论协议文件的,它只认内容。

上面的协议相当于我新定义了一种复杂数据类型,名字为nameMessage,并且包含一个属性name,类型为string。 用Java语言通俗的说,我新定义了一个Bean, 这个Bean中只有一个<code>String name</code>的属性。因此她也是包涵在types下面的,相当与新定义了数据类型。

record是复杂类型,也就是可以通过简单类型合成的组装类型。关于支持的简单数据类型见:

http://avro.apache.org/docs/current/spec.html

messages在协议中包含特殊的含义。相当于曝露给外部可以调用的接口。如上面的协议,相当与包含了sayHello的方法,方法入口参数为String name,返回值为一个自定义的类型nameMessage, 其实也是一个String类型的键值对。

##服务端[Java]

<pre class="prettyprint lang-java"> public class AvroHttpServer extends GenericResponder { private static Log log = LogFactory.getLog(AvroHttpServer.class); public AvroHttpServer(Protocol protocol) { super(protocol); } public Object respond(Message message, Object request) throws Exception { GenericRecord req = (GenericRecord) request; GenericRecord reMessage = null; if (message.getName().equals("sayHello")) { Object name = req.get("name"); // do something... //取得返回值的类型 reMessage = new GenericData.Record(super.getLocal().getType("nameMessage")); //直接构造回复 reMessage.put("name", "Hello, " + name.toString()); log.info(reMessage); } return reMessage; } public static void main(String[] args) throws Exception { int port = 8088; try { Server server = new HttpServer( new AvroHttpServer(Protocol.parse( new File("helloword.json"))), port); server.start(); server.join(); } catch (Exception e) { e.printStackTrace(); } } } </pre>

如上边的Java代码,Avro默认可以支持的Server有很多,如NettyServer,SocketServer等。目前为止我之发现了Avro Python客户端只支持的Http的方式的。

上面的代码能正常运行,并且运行后进程不会退出,一直等待客户端链接。

##客户端

###Java

我是Java程序员, 因此每个例子我都会用Java首先实现一遍。

<pre class="prettyprint lang-java"> private Protocol protocol; private GenericRequestor requestor = null; @Before public void setUp() throws Exception { protocol = Protocol.parse(new File("src/main/resources/helloword.json")); Transceiver t = new HttpTransceiver(new URL("http://localhost:8088")); requestor = new GenericRequestor(protocol, t); } @Test public void testSendMessage() throws Exception { GenericRecord requestData = new GenericData.Record(protocol.getType("nameMessage")); // initiate the request data requestData.put("name", "zhenqin"); System.out.println(requestData); Object result = requestor.request("sayHello", requestData); if (result instanceof GenericData.Record) { GenericData.Record record = (GenericData.Record) result; System.out.println(record.get("name")); } System.out.println(result); } </pre>

上面的是一个JUnit的测试用例,可以直接用来测试。

###Python

<pre class="prettyprint lang-python"> #!/usr/bin/env python #!encoding:utf-8 import json import avro.protocol as proto import avro.ipc as ipc import avro.io as avroio import avro.schema as schema __author__ = 'zhenqin' PROTOCOL = proto.parse(open("helloword.json", "r").read()) def testPro(): client = ipc.HTTPTransceiver("zhenqin-k45vm", 8088) requestor = ipc.Requestor(PROTOCOL, client) message = dict() message["name"] = "ZhenQin" v = requestor.request('sayHello', message) print("Result: " + str(v)) # cleanup client.close() if __name__ == '__main__': testPro() </pre>

Python如上边的代码,helloword.json是HelloWord的协议。运行无论是Java或者Python,都会成功的输出:

Result: {u'name': u'Hello, ZhenQin'}

上面提到,Python目前仅仅支持Http的方式调用,因为avro python只提供了一个HTTPTransceiver, 我查看HTTPTransceiver的代码, 都很简单,但是以我的Python造诣还不能够给写一个SocketTransceiver。我相信Python高人能轻易实现一个支持Socket通信的SocketTransceiver不是难事。

在说一遍,Python目前只有一个HTTPTransceiver实现, 因此服务端Java还必须使用HttpServer,它是一个嵌入的Jetty的Http服务器。

##写在后边的话

测试了Avro, 我怎么觉得它更像是以json的webservice呢? 开发是如此的罗嗦? 并且丝毫体现不了便捷。难道多语言跨平台的RPC调用真的有这么难麽?当然也有简单的方式是把服务端的Responder换成ReflectResponder就可以直接注册接口和实现类的对象,但是这样会失去对多语言的支持。

希望广大同行能给以指正。

Protobuf, Next。

转载于:https://my.oschina.net/zhzhenqin/blog/151040

多语言跨平台远程过程调用【Avro】相关推荐

  1. Hprose 是轻量级跨语言跨平台的面向对象的高性能远程动态通讯中间件

    High Performance Remote Object Service Engine: 一个MIT开源许可的新型轻量级跨语言跨平台的面向对象的高性能远程动态通讯中间件 hprose 是一个新的远 ...

  2. 2.Java语言跨平台原理?

    2.Java语言跨平台原理? 理解 为主 Java程序并非是直接运行的,Java编译器将Java源程序编译成与平台无关的字节码文件(class文件),然后由Java虚拟机(JVM)对字节码文件解释执行 ...

  3. 【JAVA】Java概述(1、Java语言发展史;2、Java语言跨平台原理;3、JRE和JDK;4、JDK的下载与安装)

    Java概述 重新学习Java第一篇 文章目录 Java概述 1.JAVA语言发展史 1.1Java语言 1.2Java语言发展史 2.Java语言跨平台原理 2.1平台 2.2跨平台 2.3跨平台原 ...

  4. c语言休眠函数 vs,编纂C语言跨平台函数(以清屏和休眠函数为例)

    编写C语言跨平台函数(以清屏和休眠函数为例) 支持C语言的平台有许多,常见的编译器如VC.gcc.Clang等.不同的编译器共同点是都支持标准C(ANSI C),但是各自却又有自己独立的.平台相关的功 ...

  5. python语言跨平台语言吗_python属于跨平台语言吗?

    Python是跨平台的,免费开源的一门计算机编程语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的开 ...

  6. Java语言跨平台性质的优点和缺点_机器人热门编程语言及优缺点分析

    机器人编程语言最早于20世纪70年代初期问世,到目前为止已有多种编程语言出现,在众多机器人编程语言中究竟哪种编程语言最好呢?这个问题困扰了很多新手学者,但遗憾的是,这是一个没有准确答案的问题,你问不同 ...

  7. 编写C语言跨平台函数(以清屏和休眠函数为例)

    支持C语言的平台有许多,常见的编译器如VC.gcc.Clang等.不同的编译器共同点是都支持标准C(ANSI C),但是各自却又有自己独立的.平台相关的功能以及函数接口.这通常为程序的移植性带来很多问 ...

  8. 谷歌正式开源其多语言跨平台加密库Tink

    在谷歌,很多产品团队使用加密技术来保护用户数据.在加密技术领域,一个很细微的错误都会产生非常严重的后果.想要正确实现加密技术,可能需要先消化数十年的学术文献.毋庸置疑,很多开发人员没有这么多时间. 为 ...

  9. DBM、GDBM与C语言跨平台代码研究

    1.     简介 符合X/Open技术规范的UNIX版本自备了一个数据库.但这个数据库不符合ANSI标准的SQL技术规范(不支持SQL语句).它只是一个存储检索数据的例程. dbm.gdbm适合存储 ...

最新文章

  1. 很抱歉,这场大会我们没法卖票给你了
  2. php处理json请求(php获取post请求的json数据的实现方法)
  3. 如何查找计算机开机项,怎么查看电脑启动项 电脑开
  4. 内存中的调用别的软件程序加密解密函数_公司加密软件哪个最好用?
  5. [置顶] 总结工作中常用到的linux命令
  6. HTTP MIME Types
  7. Flex导出Excel
  8. ORA-01438错误的解决方法
  9. IOCP Thread Pool 在 C# 的Safe实现
  10. 数据导出到excel文件给客户端下载的几种方法
  11. JointJs快速入门
  12. ztree树默认根据ID默认选中该条数据
  13. pcd点云文件成功转成npy文件
  14. 新成员入群监控自动发送邮件效果如何实现?
  15. 用户解锁不存在_“sim卡无效,显示lte,电信掉3g,通讯录+86”等出现在卡贴“tmsi解锁模式”中的解决方法...
  16. P1967 货车运输( 最大生成树+LCA or Kruskal重构树)
  17. python爬虫检测ip是否有效
  18. 中美视觉谈标志设计分类
  19. 生命体征检测雷达,人体存在感知应用
  20. 团体标准补贴政策 2022年

热门文章

  1. 【网络】几种常见的协议
  2. win10环境,Eclipse安装Maven
  3. 软件测试--环境讲解
  4. golang mysql连接池原理_[Go] golang实现mysql连接池
  5. winfrom 如何让弹窗不影响主界面_「Win」电脑开机后不给我弹几个广告,我还不太习惯...
  6. mybatisplus 操作另一个数据库的数据_实例分析:python操作数据库项目
  7. 总有人黑 JavaScript?那是不知道它有多好用吧!
  8. web前端是什么?需要掌握什么技术?
  9. web前端开发面临挑战有哪些?
  10. 屏蔽关闭百度搜索风云热点的方法