rpc框架之avro 学习 1 - hello world

avro是hadoop的一个子项目,提供的功能与thrift、Protocol Buffer类似,都支持二进制高效序列化,也自带RPC机制,但是avro使用起来更简单,无需象thrift那样生成目标语言源代码,目前支持的语言有java、c#、php、c++等(详情见:https://cwiki.apache.org/confluence/display/AVRO/Supported+Languages),hadoop生态圈中的hive、pig已经在使用avro

avro-client模块中的pom.xml参考以下内容:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6
 7     <groupId>yjmyzz.avro</groupId>
 8     <artifactId>avro-client</artifactId>
 9     <version>1.0</version>
10
11     <properties>
12         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13         <compiler-plugin.version>2.3.2</compiler-plugin.version>
14         <avro.version>1.7.5</avro.version>
15     </properties>
16
17     <dependencies>
18         <dependency>
19             <groupId>junit</groupId>
20             <artifactId>junit</artifactId>
21             <version>4.10</version>
22             <scope>test</scope>
23         </dependency>
24         <dependency>
25             <groupId>org.slf4j</groupId>
26             <artifactId>slf4j-simple</artifactId>
27             <version>1.6.4</version>
28             <scope>compile</scope>
29         </dependency>
30         <dependency>
31             <groupId>org.apache.avro</groupId>
32             <artifactId>avro</artifactId>
33             <version>${avro.version}</version>
34         </dependency>
35         <dependency>
36             <groupId>org.apache.avro</groupId>
37             <artifactId>avro-ipc</artifactId>
38             <version>${avro.version}</version>
39         </dependency>
40
41         <dependency>
42             <groupId>yjmyzz.avro</groupId>
43             <artifactId>avro-contract</artifactId>
44             <version>1.0</version>
45         </dependency>
46     </dependencies>
47
48     <build>
49         <plugins>
50             <plugin>
51                 <groupId>org.apache.maven.plugins</groupId>
52                 <artifactId>maven-compiler-plugin</artifactId>
53                 <version>${compiler-plugin.version}</version>
54             </plugin>
55             <plugin>
56                 <groupId>org.apache.avro</groupId>
57                 <artifactId>avro-maven-plugin</artifactId>
58                 <version>${avro.version}</version>
59                 <executions>
60                     <execution>
61                         <id>schemas</id>
62                         <phase>generate-sources</phase>
63
64                         <goals>
65                             <goal>schema</goal>
66                             <goal>protocol</goal>
67                             <goal>idl-protocol</goal>
68                         </goals>
69                     </execution>
70                 </executions>
71             </plugin>
72         </plugins>
73     </build>
74
75
76 </project>

View Code

一、定义文件示例

Person.avsc

{
  "namespace": "yjmyzz.avro.study.dto",
  "type": "record",
  "name": "Person",
  "fields": [
    {
      "name": "age",
      "type": "int"
    },
    {
      "name": "name",
      "type": "string"
    },
    {
      "name": "sex",
      "type": "boolean"
    },
    {
      "name": "salary",
      "type": "double"
    },
    {
      "name": "childrenCount",
      "type": "int"
    }
  ]
}

QueryParameter.avsc

{
  "namespace": "yjmyzz.avro.study.dto",
  "type": "record",
  "name": "QueryParameter",
  "fields": [
    {
      "name": "ageStart",
      "type": "int"
    },
    {
      "name": "ageEnd",
      "type": "int"
    }
  ]
}

DemoService.avdl

@namespace ("yjmyzz.avro.study.service")
protocol DemoService
{
    import schema "Person.avsc";
    import schema "QueryParameter.avsc";
    string ping();
    array<yjmyzz.avro.study.dto.Person> getPersonList(yjmyzz.avro.study.dto.QueryParameter queryParameter);
}

二、服务端

DemoServiceImpl.java

package yjmyzz.avro.study;

import yjmyzz.avro.study.dto.Person;
import yjmyzz.avro.study.dto.QueryParameter;
import yjmyzz.avro.study.service.DemoService;
import java.util.ArrayList;
import java.util.List;

public class DemoServiceImpl implements DemoService {

    public String ping() {
        System.out.println("ping()");
        return "pong";
    }

    public List<Person> getPersonList(QueryParameter parameter) {
        //System.out.println(parameter.getAgeStart() + " - " + parameter.getAgeEnd());

        List<Person> list = new ArrayList<Person>(10);
        for (int i = 0; i < 10; i++) {
            Person p = new Person();
            p.setAge(i);
            p.setChildrenCount(i);
            p.setName("test" + i);
            p.setSalary(10000D);
            p.setSex(true);
            list.add(p);
        }
        return list;
    }
}

AvroServer.java

package yjmyzz.avro.study;

import org.apache.avro.ipc.NettyServer;
import org.apache.avro.ipc.Server;
import org.apache.avro.ipc.specific.SpecificResponder;
import yjmyzz.avro.study.service.DemoService;

import java.net.InetSocketAddress;

public class AvroServer {

    public static void main(String[] args) {

        System.out.println("Starting avro server...");

        Server server = new NettyServer(new SpecificResponder(DemoService.class,
                new DemoServiceImpl()),
                new InetSocketAddress(65111));

        System.out.println("Avro erver started.");
    }
}

三、客户端

AvroClient.java

package yjmyzz.avro.study;

import org.apache.avro.AvroRemoteException;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.specific.SpecificRequestor;
import yjmyzz.avro.study.dto.QueryParameter;
import yjmyzz.avro.study.service.DemoService;

import java.net.InetSocketAddress;

public class AvroClient {

    public static void main(String[] args) throws Exception {

        NettyTransceiver client = new NettyTransceiver(new InetSocketAddress(65111));
        DemoService proxy = (DemoService) SpecificRequestor.getClient(DemoService.class, client);

        System.out.println(proxy.ping());

        int max = 100000;

        Long start = System.currentTimeMillis();

        for (int i = 0; i < max; i++) {
            call(proxy);
        }

        Long end = System.currentTimeMillis();

        Long elapse = end - start;

        int perform = Double.valueOf(max / (elapse / 1000d)).intValue();

        System.out.print("avro " + max + " 次RPC调用,耗时:" + elapse + "毫秒,平均" + perform + "次/秒");

        // cleanup
        client.close();
    }

    private static void call(DemoService proxy) throws AvroRemoteException {

        //client.ping();
        //System.out.println("ping()=>" + client.ping());

        QueryParameter parameter = new QueryParameter();
        parameter.setAgeStart(5);
        parameter.setAgeEnd(50);

        proxy.getPersonList(parameter);
        //System.out.println(client.getPersonList(parameter));
    }
}

 avro 100000 次RPC调用,耗时:18617毫秒,平均5371次/秒

注:虽然很多关于thrift、avro的性能评测文章提到avro性能不输于thrift,但就本文的示例而言,在同一台笔记本上,avro的性能只有thrift的约1/2.

附:文中示例代码下载 http://code.taobao.org/svn/avro-rpc-demo/trunk/

参考文章:
https://github.com/phunt/avro-rpc-quickstart

http://avro.apache.org/docs/current/spec.html#Protocol+Declaration

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

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

Apache Avro 与 Thrift 比较

时间: 2024-09-28 05:22:21

rpc框架之avro 学习 1 - hello world的相关文章

rpc框架之 avro 学习 2 - 高效的序列化

同一类框架,后出现的总会吸收之前框架的优点,然后加以改进,avro在序列化方面相对thrift就是一个很好的例子.借用Apache Avro 与 Thrift 比较 一文中的几张图来说明一下,avro在序列化方面的改进: 1.无需强制生成目标语言代码 avro提供了二种使用方式,一种称之为Sepcific方式,这跟thrift基本一致,都是写定义IDL文件,然后用编译器(或插件)生成目标class,另一种方式是Generic,这种方式下,不用生成目标代码,而是采用动态加载定义文件的方式,将 Fi

rpc框架: thrift/avro/protobuf 之maven插件生成java类

thrift.avro.probobuf 这几个rpc框架的基本思想都差不多,先定义IDL文件,然后由各自的编译器(或maven插件)生成目标语言的源代码,但是,根据idl生成源代码这件事,如果每次都要手动敲命令,未免太无聊了,幸好这三种框架都提供了对应的maven插件来完成代码的自动生成,本文演示了这三种框架的maven插件用法. 一.maven-thrift-plugin 1 <?xml version="1.0" encoding="UTF-8"?>

rpc框架之gRPC 学习 - hello world

grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的rpc五花八门,国内比较著名的有百度的sofa-pbrpc,但是遗憾的是soft-pbrpc没有对应的java实现版本.rgpc还有一个独立的官网:http://www.grpc.io/,目前已经支持的语言有 C, C++, Java, Go, Node.js, Python, Ruby, Objec

rpc框架之 thrift 学习 1 - 安装 及 hello world

thrift是一个facebook开源的高效RPC框架,其主要特点是跨语言及二进制高效传输(当然,除了二进制,也支持json等常用序列化机制),官网地址:http://thrift.apache.org 跨语言通常有二种做法, 一是将其它语言转换成某种主流的通用语言,比如:delphi.net以前就是先将delphi转换成c#,然后再编译成IL,从而实现delphi在.net上的运行(好久没关注delphi了,不知道现在还是不是这种机制) 二是先定义一种规范文件(可以简单的理解为『母版』),然后

rpc框架之 thrift 学习 2 - 基本概念

thrift的基本构架: 上图源自:http://jnb.ociweb.com/jnb/jnbJun2009.html 底层Underlying I/O以上的部分,都是由thrift编译器生成的代码,其中: Your Code 这是根据thrift文件中定义的dto及service接口方法 FooService.Client及FooService.Processer是thrift生成的用于客户端及服务端的标准代码 Foo.read/write 参数对象及结果对象在传输时,最终需要在client.

一个轻量级分布式RPC框架--NettyRpc

1.背景 最近在搜索Netty和Zookeeper方面的文章时,看到了这篇文章<轻量级分布式 RPC 框架>,作者用Zookeeper.Netty和Spring写了一个轻量级的分布式RPC框架.花了一些时间看了下他的代码,写的干净简单,写的RPC框架可以算是一个简易版的dubbo.这个RPC框架虽小,但是麻雀虽小,五脏俱全,有兴趣的可以学习一下. 本人在这个简易版的RPC上添加了如下特性: * 服务异步调用的支持,回调函数callback的支持 * 客户端使用长连接(在多次调用共享连接) *

基于zeromq的高性能分布式RPC框架Zerorpc 性能测试

Zeromq 是基于zeromq.gevent和 msgpack开发的分布式RPC框架zerorpc-python.这个框架简单.易用. 1. 安装zeromq yum -y install zeromq yum install gcc gcc-c++ libuuid-devel python-uuid uuid wget http://download.zeromq.org/zeromq-2.1.9.tar.gz ./configure make make install 2.安装gevent

php实现的一个简单json rpc框架实例

 这篇文章主要介绍了php实现的一个简单json rpc框架实例,本文给出了RPC服务端和客户端代码以及应用实例,需要的朋友可以参考下     json rpc 是一种以json为消息格式的远程调用服务,它是一套允许运行在不同操作系统.不同环境的程序实现基于Internet过程调用的规范和一系列的实现.这种远程过程调用可以使用http作为传输协议,也可以使用其它传输协议,传输的内容是json消息体. 下面我们code一套基于php的rpc框架,此框架中包含rpc的服务端server,和应用端cl

RPC框架几行代码就够了

虽然以前也大概知道rpc的实现原理,也看过部分msgpack的实现,但是对于反射不是很了解. 现在看到一个简单完整的实现,也解决我的以前的另一个疑惑: http://topic.csdn.net/u/20111028/14/092f98d0-ecdc-48b2-bf8b-317d5071ab6f.html?seed=361547001&r=77648361#r_77648361 不过,还是不明白为什么msgpack只用函数名,没有结合参数列表来识别一个函数,为了和其它语言兼容? --------