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

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>

一、定义文件示例

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.

参考文章:
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-12-29 15:09:14

rpc框架之avro教程1-hello world的相关文章

rpc框架之thrift教程1 - 安装 及 hello world

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

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

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

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框架之HA/负载均衡构架设计

thrift.avro.grpc之类的rpc框架默认都没有提供负载均衡的实现,生产环境中如果server只有一台,显然不靠谱,于是有了下面的设计,这其实是前一阵跟北京一个朋友在qq群里交流的结果,分享一下: 主要思路: 1.rpc server端以多实例方式运行(多端口或多机部署均可),启动时每个实例向zk集群以临时节点方式注册(这样,遍历zk上/server下有多少个临时节点就知道有哪些server实例在线) 2.客户端自己实现一个连接池,连接池初始化时,从zk将在线的server实例信息同步

Java实现简单的RPC框架

一.RPC简介 RPC,全称为Remote Procedure Call,即远程过程调用,它是一个计算机通信协议.它允许像调用本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用).Hessian.Http invoker等.另外,RPC是与语言无关的. RPC示意图 如上图所示,假设Computer1在调用sayHi()方法,对于Computer1而言调用sayHi()方法就像调用本地方法一样,调用 –>返回.但从后续调用可以看出Computer1调用的是Computer2

gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架

gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架 Google Guava官方教程(中文版) | 并发编程网 - ifeve.com Google Guava官方教程(中文版)

[转]新兵训练营系列课程——平台RPC框架介绍

原文:http://weibo.com/p/1001643875439147097368 课程大纲 1.RPC简介 1.1 什么是RPC 1.2 RPC与其他远程调用方式比较 2.Motan RPC框架 2.1 RPC服务框架 2.2 Motan RPC框架中的角色 2.3 Motan RPC的调用流程 3.Motan RPC中各角色介绍 3.1 注册中心 3.2 RPC Service 3.3 RPC Client 4.Motan实战 4.1 Motan的使用方式 4.2 使用Motan提供R

RPC框架实践之:Apache Thrift

一.概述 RPC(Remote Procedure Call)即 远程过程调用,说的这么抽象,其实简化理解就是一个节点如何请求另一节点所提供的服务.在文章 微服务调用链追踪中心搭建 一文中模拟出来的调用链:ServiceA ---> ServiceB ---> ServiceC 就是一个远程调用的例子,只不过这篇文章里是通过RestTemplate这种 同步调用方式,利用的是HTTP协议在应用层完成的,这种方法虽然奏效,但有时效率并不高.而RPC可以不依赖于应用层协议,可以直接基于TCP进行远

RPC 框架之 Goole protobuf

Goole 的 protobuf  即 Protocol Buffers  是一个很好的RPC 框架,支持 c++ python  java 接下来进行官方文档的解读,然后你会对protobuf 会有一个很好的认识: Protocol buffers  are language-neutral, platform-netural extensible mechanism for serializing strutctured data ,think xml . but smaller,faste