Avro

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.引入avropom文件,然后在每个工程下,创建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.通过avroAPI实现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);
	}
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值