1.创建maven工程
2.导入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.tarena</groupId>
<artifactId>avro-add-contract</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>avro-add-contract</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler-plugin.version>2.3.2</compiler-plugin.version>
<avro.version>1.7.5</avro.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro-ipc</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.5</version>
<executions>
<!--phase 阶段的意思 比如maven在执行clean compile test 这些都是maven生命周期的一个阶段 在avro里,
<phase>generate-sources</phase>意思就是要用avro工作 得执行generate-sources这个阶段。 goal是maven最小的执行单元,比如run
是maven自己的goal 报错的原因:某些插件的goal,maven不认识,所以就报错了。 -->
<execution>
<id>schemas</id>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
<goal>protocol</goal>
<goal>idl-protocol</goal>
</goals>
<configuration>
<!-- sourceDirectory是avro的源目录,avro的模式文件,都要放在这个目录下 这样,插件才能找到 -->
<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
<!--outputDirectory 是avro的输出目录,根据模式文件生成java类,就输出到这个目录下 -->
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3.根据pom文件中<sourceDirectory>标签中的配置创建源目录
创建方法:右键-new-source folder
4.编写avsc文件
文件编写规范参考:《Avro Schema 格式说明+示例》(在我的资源中)
{"namespace":"avro.domain",
"type":"record",
"name":"User",
"fields":
[
{"name":"username","type":"string"},
{"name":"age","type":["int","null"]}
]
}
5.选择maven工程-右键-Run As-Maven generator_sources
6.如下图在指定目录中生成对象
7.avro创建对象
package com.liming.Avro;
import org.junit.Test;
import avro.domain.User;
public class TestAvro {
@Test
public void test01(){
User u1 = new User();
u1.setUsername("zuo");
u1.setAge(12);
User u2 = new User("zuo", 13);
User u3=User.newBuilder().setUsername("tom").setAge(23).build();
//基于某个对象修改其属性
User u4=User.newBuilder(u2).setAge(8000).build();
System.out.println(u1+"||"+u2+"||"+u2+"||"+u4);
}
}
8.avro序列化和反序列化的api使用
package com.liming.Avro;
import java.io.File;
import org.apache.avro.file.DataFileReader;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import org.junit.Test;
import avro.domain.User;
public class TestAvro {
@Test
public void write() throws Exception{
User u1=new User("tom",23);
User u2=new User("rose",25);
DatumWriter<User> dw=new SpecificDatumWriter<>(User.class);
DataFileWriter<User> dfw=new DataFileWriter<>(dw);
//schema 传入的是要序列化的对象类的schema
dfw.create(u1.getSchema(),new File("1.txt"));
dfw.append(u1);
dfw.append(u2);
dfw.close();
}
@Test
public void read() throws Exception{
DatumReader<User> dr=new SpecificDatumReader<>(User.class);
DataFileReader<User> dfr=new DataFileReader<>(new File("1.txt"),
dr);
while(dfr.hasNext()){
System.out.println(dfr.next());
}
dfr.close();
}
}
9.avro实现RPC通信
案例1:
通过rpc,实现1+1运算。
实现步骤:
a.创建两个maven工程,一个是client,一个是server
b.引入avro的pom文件,然后在每个工程下,创建src/main/avro
rpc通信的应用场景,用于数据通信和传输。rpc主内,即用于某个集群内部的网络通信。
http主外。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.tarena</groupId>
<artifactId>avro-add-contract</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>avro-add-contract</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler-plugin.version>2.3.2</compiler-plugin.version>
<avro.version>1.7.5</avro.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro-ipc</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.5</version>
<executions>
<!--phase 阶段的意思 比如maven在执行clean compile test 这些都是maven生命周期的一个阶段 在avro里,
<phase>generate-sources</phase>意思就是要用avro工作 得执行generate-sources这个阶段。 goal是maven最小的执行单元,比如run
是maven自己的goal 报错的原因:某些插件的goal,maven不认识,所以就报错了。 -->
<execution>
<id>schemas</id>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
<goal>protocol</goal>
<goal>idl-protocol</goal>
</goals>
<configuration>
<!-- sourceDirectory是avro的源目录,avro的模式文件,都要放在这个目录下 这样,插件才能找到 -->
<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
<!--outputDirectory 是avro的输出目录,根据模式文件生成java类,就输出到这个目录下 -->
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
c.编写协议文件(.avdl),这个要根据avro的模式要求去写
@namespace("avro.protocol")
protocol AddService{
int add(int i,int y);
}
.avdl文件编写模板参考《
利用AVRO定义avdl文件示例》(在我的资源中可以下载)
d.通过avro的API实现rpc
服务端要编写协议实现:
package avro.protocol;
import org.apache.avro.AvroRemoteException;
public class AddServiceImpl implements AddService {
@Override
public int add(int i, int y) throws AvroRemoteException {
return i+y;
}
}
package com.liming.Avro.Server;
import java.net.InetSocketAddress;
import org.apache.avro.ipc.NettyServer;
import org.apache.avro.ipc.specific.SpecificResponder;
import avro.protocol.AddService;
import avro.protocol.AddServiceImpl;
public class AvroServer {
public static void main(String[] args) {
//netty服务端
//new SpecificResponder()指明了接口和实现类-----是响应
//new InetSocket() 绑定了端口
new NettyServer(new SpecificResponder(AddService.class, new AddServiceImpl()),
new InetSocketAddress(8888));
while(true);
}
}
package com.liming.Avro.Client;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.specific.SpecificRequestor;
import avro.protocol.AddService;
public class AvroClient {
public static void main(String[] args) throws Exception {
//netty客户端
//new InetSocketAdress()指明了服务器地址
NettyTransceiver client = new NettyTransceiver(new InetSocketAddress("127.0.0.1", 8888));
//指明协议
AddService protocol=SpecificRequestor.getClient(AddService.class, client);
int add = protocol.add(2, 3);
System.out.println("服务器返回值为"+add);
}
}
案例2:
rpct通信通过对象传输
1.avdl文件、.avsc对象
2.服务端实现类
package avro.protocol;
import org.apache.avro.AvroRemoteException;
import avro.domain.User;
public class AddServiceImpl implements AddService {
@Override
public int add(int i, int y) throws AvroRemoteException {
return i+y;
}
@Override
public Void sendUser(User user) throws AvroRemoteException {
System.out.println("服务端收到了数据"+user.toString());
return null;
}
}
3.服务端和客户端
package com.liming.Avro.Client;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.specific.SpecificRequestor;
import avro.domain.User;
import avro.protocol.AddService;
public class AvroClient {
public static void main(String[] args) throws Exception {
//netty客户端
//new InetSocketAdress()指明了服务器地址
NettyTransceiver client = new NettyTransceiver(new InetSocketAddress("127.0.0.1", 8888));
//指明协议
AddService protocol=SpecificRequestor.getClient(AddService.class, client);
int add = protocol.add(2, 3);
System.out.println("服务器返回值为"+add);
User u1=new User("rose",23);
protocol.sendUser(u1);
while(true);
}
}
package com.liming.Avro.Server;
import java.net.InetSocketAddress;
import org.apache.avro.ipc.NettyServer;
import org.apache.avro.ipc.specific.SpecificResponder;
import avro.protocol.AddService;
import avro.protocol.AddServiceImpl;
public class AvroServer {
public static void main(String[] args) {
//netty服务端
//new SpecificResponder()指明了接口和实现类-----是响应
//new InetSocket() 绑定了端口
new NettyServer(new SpecificResponder(AddService.class, new AddServiceImpl()),
new InetSocketAddress(8888));
while(true);
}
}