Avro序列化和RPC实现

简介: 序列化和反序列化Maven:Pom.xml <dependencies> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro</artifactId> <version>1.

序列化和反序列化

  • Maven:Pom.xml
    <dependencies>
        <dependency>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro</artifactId>
            <version>1.8.2</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.avro</groupId>
                <artifactId>avro-maven-plugin</artifactId>
                <version>1.8.1</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>schema</goal>
                        </goals>
                        <configuration>
                            <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
                            <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • Avro:MapAvro.avsc
{
  "type":"record",
  "namespace":"com.qidai",
  "name":"Employee",
  "doc":"Test Employee bean",
  "fields":[
    {"name":"id","type":["null","int"]},
    {"name":"name","type":["null","string"]},
    {"name":"age","type":["null","int"]},
    {"name":"gender","type":["null","string"]}
  ]
}
  • 添加完依赖后直接点击maven插件install即可,就会产生对应的class
  • 序列化和反序列化(使用javaclass)
@Test
public void ser() throws Exception {
    Employee employee = Employee.newBuilder().setAge(12).setGender("NAN").setId(1).setName("tom").build();
    DatumWriter<Employee> employeeDatumWriter = new SpecificDatumWriter<>(Employee.class);
    DataFileWriter<Employee> dataFileWriter = new DataFileWriter<>(employeeDatumWriter);

    dataFileWriter.create(employee.getSchema(), new File("emp.avro"));

    dataFileWriter.append(employee);
    dataFileWriter.close();
}
@Test
public void deSer() throws Exception {
    DatumReader<Employee> employeeDatumReader = new SpecificDatumReader<>(Employee.class);
    DataFileReader<Employee> dataFileReader = new DataFileReader<>(new File("emp.avro"), employeeDatumReader);

    Employee employee = null;

    while (dataFileReader.hasNext()) {
        employee = dataFileReader.next();
        System.out.println(employee);
    }
}
  • 序列化反序列化(直接使用avro文件)
@Test
public void ser() throws Exception {
    Schema schema = new Schema.Parser().parse(new File("emp.avsc"));
    GenericRecord empRecord1 = new GenericData.Record(schema);
    empRecord1.put("id", 1);
    empRecord1.put("name", "Ben");
    empRecord1.put("age", 7);
    empRecord1.put("gender", "nv");
    File file = new File("empser.avro");
    DatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<>(schema);
    DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<>(datumWriter);
    dataFileWriter.create(schema, file);
    dataFileWriter.append(empRecord1);
    dataFileWriter.close();
}
@Test
public void deSer() throws Exception {
    //指定avro格式文件
    Schema schema = new Schema.Parser().parse(new File("emp.avsc"));
    //指定序列化好的数据文件
    File file = new File("empser.avro");
    DatumReader<GenericRecord> datumReader = new GenericDatumReader<>(schema);
    DataFileReader<GenericRecord> dataFileReader = new DataFileReader<>(file, datumReader);

    GenericRecord emp = null;

    while (dataFileReader.hasNext()) {
        emp = dataFileReader.next();
        System.out.println(emp);
    }
}

RPC实现

  • 编写avsc文件:user.avsc,作为要发送的实体类
{
"namespace":"com.qidai.bean",
"name":"User",
"doc":"test rpc class",
"type":"record",
    "fields":[
        {"name":"name","type":["string","null"]},
        {"name":"age","type":["int","null"]},
        {"name":"date","type":["string","null"]}
    ]
}
  • 编写协议文件:protomes.avdl
@namespace("com.qidai.proto")
protocol UserProtocol{
  import schema "user.avsc";           
  string sendMes(com.qidai.bean.User user);   //对应协议中的方法
}
  • 编写完毕之后检查maven pom文件
<dependencies>
    <dependency>
        <groupId>org.apache.avro</groupId>
        <artifactId>avro</artifactId>
        <version>1.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.avro</groupId>
        <artifactId>avro-ipc</artifactId>
        <version>1.8.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro-maven-plugin</artifactId>
            <version>1.8.1</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>schema</goal>
                        <goal>idl-protocol</goal>
                    </goals>
                    <configuration>
                        <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
                        <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
  • 检查没错之后,直接插件install生成avro类
  • 生成之后会看到一个User的传输类,还有一个proto包下的协议接口
  • 实现协议接口,重写自己的逻辑:server
public class UserProtocolImpl implements UserProtocol {
    @Override
    public CharSequence sendMes(User user) throws AvroRemoteException {
        System.out.println("Server --> 接收" + user.toString());
        return "Client sendMes " + user.toString();
    }
}
  • 实现协议接口,重写自己的逻辑:client
public class UserProtocolImpl implements UserProtocol {
    @Override
    public CharSequence sendMes(User user) throws AvroRemoteException {
        System.out.println("Client --> 发送" + user.toString());
        return "Client sendMes " + user.toString();
    }
}
  • 编写serverApp
public class ServerApp {
    public static void main(String[] args) throws IOException, InterruptedException {
        Responder responder = new SpecificResponder(UserProtocol.class,new UserProtocolImpl());
        SaslSocketServer server = new SaslSocketServer(responder,new InetSocketAddress(9999));
        server.start();
        Thread.sleep(5000000);
    }
}
  • 编写clientApp
public class ClientApp {
    public static void main(String[] args) throws IOException {
        SaslSocketTransceiver transceiver = new SaslSocketTransceiver(new InetSocketAddress(9999));
        UserProtocol client = SpecificRequestor.getClient(UserProtocol.class, transceiver);
        Scanner scanner = new Scanner(System.in);
        while (scanner.next() != null) {
            User user = new User();
            user.setName("xiaofen");
            System.out.println(client.sendMes(user));
        }
    }
}
  • 测试:先启动serverApp,然后启动clientApp,这时候在client的console中输入任意值,会发现服务端和客户端都会输出消息

    • server
    Server --> {"name": "xiaofen", "age": null, "date": null}
    Server --> {"name": "xiaofen", "age": null, "date": null}
    Server --> {"name": "xiaofen", "age": null, "date": null}
    Server --> {"name": "xiaofen", "age": null, "date": null}
    Server --> {"name": "xiaofen", "age": null, "date": null}
    Server --> {"name": "xiaofen", "age": null, "date": null}
    Server --> {"name": "xiaofen", "age": null, "date": null}
    • client
    1
    Client sendMes {"name": "xiaofen", "age": null, "date": null}
    1
    Client sendMes {"name": "xiaofen", "age": null, "date": null}
    1
    Client sendMes {"name": "xiaofen", "age": null, "date": null}
    1
    Client sendMes {"name": "xiaofen", "age": null, "date": null}
    1
    Client sendMes {"name": "xiaofen", "age": null, "date": null}
    1
    Client sendMes {"name": "xiaofen", "age": null, "date": null}
    1
    Client sendMes {"name": "xiaofen", "age": null, "date": null}
  • 对于server的client的实现有如下几种
    1.基于jetty的http实现:HttpServer 和HttpTransceiver

2.基于netty的实现:NettyServer和NettyTransceiver
3.基于TCP的实现:SocketServer和SocketTransceiver
4.基于UDP的实现:DatagramServer和DatagramTransceiver
5.基于加密的TCP实现:SaslSocketServer和SaslSocketTransceiver

目录
相关文章
|
7月前
|
消息中间件 Dubbo Java
Simple RPC - 02 通用高性能序列化和反序列化设计与实现
Simple RPC - 02 通用高性能序列化和反序列化设计与实现
46 2
|
10月前
|
消息中间件 Java Kafka
kafka 客户端使用Avro序列化
kafka 客户端使用Avro序列化
127 0
|
11月前
|
存储 JSON 网络协议
阿里一面灵魂一问:RPC或者HTTP什么时候需要序列化和反序列化?
大家好,我是热心网友 —— 小林。 有位读者问了,我这么一个问题:
|
12月前
|
XML 存储 JSON
RPC的序列化方案详解
网络传输的数据须是二进制数据,但调用方请求的出入参数都是对象: 对象不能直接在网络传输,需提前转成可传输的二进制,且要求可逆,即“序列化” 将对象转换成二进制数据
133 0
|
12月前
|
Dubbo Java 应用服务中间件
再谈序列化之rpc调用失败和jackson序列化时不允许Map中的key为null
再谈序列化之rpc调用失败和jackson序列化时不允许Map中的key为null
187 0
|
JSON Java 数据格式
RPC框架(4 - 实现一个基于 Kryo 的序列化器)
RPC框架(4 - 实现一个基于 Kryo 的序列化器)
|
设计模式 JSON Java
RPC框架(3 - 实现Netty传输和通用序列化接口)
RPC框架(3 - 实现Netty传输和通用序列化接口)
|
分布式计算 Java Hadoop
JAVA—其他—Avro序列化
Avro是hadoop的一个用于序列化的组件 理解特点: 1. 高效 2. 序列化后体积小 3. 动态 动态指的是数据的结构一旦定义,可以在多处语言生成实体类
256 0
|
JSON Dubbo 网络协议
分布式RPC框架Dubbo实现服务治理实用示例:集成Kryo实现高速序列化,集成Hystrix实现熔断器
本文在熟悉远程RPC服务调用的基础上,详细说明了Dubbo框架实现服务治理的实用的示例,Dubbo和Kryo集成可以实现高速序列化,Dubbo和Hystrix集成可以实现服务熔断,可以在生产端和消费端使用熔断器实现服务熔断的功能,集成Hystrix的框架可以通过Hystrix仪表盘实现对远程RPC调用的服务的治理。最后重点讲述了Hystrix的相关的实用分析。通过这篇文章,可以熟悉并会使用服务的熔断机制。
300 0
分布式RPC框架Dubbo实现服务治理实用示例:集成Kryo实现高速序列化,集成Hystrix实现熔断器
|
存储 分布式计算 Java
深入对比Java与Hadoop大数据序列化机制Avro
Java有自己提供的序列化机制,而我们的Hadoop也提供了自己的序列化机制,二者究竟有什么差异呢?为什么Hadoop要重新设计自己的序列化体系?序列化大数据对象的过程,Writable接口底层源码实现。
2082 0