Avro类型 |
说明 |
null |
没有值 |
boolean |
一个二级制布尔值 |
int |
32位有符号整数 |
long |
64位有符号整数 |
float |
32位单精度浮点数 |
double |
64位双精度浮点数 |
bytes |
8位无符号字节序列 |
string |
字符序列 |
类型 |
属性 |
说明 |
record |
|
class |
|
name |
a JSON string providing the name of the record (required). |
|
namespace |
a JSON string that qualifies the name(optional). |
|
doc |
a JSON string providing documentation to the user of this schema (optional). |
|
aliases |
a JSON array of strings, providing alternate names for this record (optional). |
|
fields |
a JSON array, listing fields (required). |
|
name |
a JSON string. |
|
type |
a schema/a string of defined record. |
|
default |
a default value for field when lack. |
|
order |
ordering of this field. |
Enums |
|
enum |
|
name |
a JSON string providing the name of the enum (required). |
|
namespace |
a JSON string that qualifies the name. |
|
doc |
a JSON string providing documentation to the user of this schema (optional). |
|
aliases |
a JSON array of strings, providing alternate names for this enum (optional) |
|
symbols |
a JSON array, listing symbols, as JSON strings (required). All symbols in an enum must be unique. |
Arrays |
|
array |
|
items |
he schema of the array’s items. |
Maps |
|
map |
|
values |
the schema of the map’s values. |
Fixed |
|
fixed |
|
name |
a string naming this fixed (required). |
|
namespace |
a string that qualifies the name. |
|
aliases |
a JSON array of strings, providing alternate names for this enum (optional). |
|
size |
an integer, specifying the number of bytes per value (required). |
Unions |
|
a JSON arrays |
Avro类型 |
json类型 |
举例 |
null |
null |
null |
boolean |
boolean |
true |
int,long |
integer |
1 |
float,double |
number |
1.1 |
bytes |
string |
"\u00FF" |
string |
string |
"foo" |
record |
object |
{"a": 1} |
enum |
string |
"FOO" |
array |
array |
[1] |
map |
object |
{"a": 1} |
fixed |
string |
"\u00ff" |
4.0.0
cn.tedu.zk
zebra-avro
0.0.1-SNAPSHOT
jar
zebra-avro
http://maven.apache.org
UTF-8
2.3.2
1.7.5
junit
junit
4.10
test
org.slf4j
slf4j-simple
1.6.4
compile
org.apache.avro
avro
1.7.5
org.apache.avro
avro-ipc
1.7.5
org.apache.maven.plugins
maven-compiler-plugin
${compiler-plugin.version}
org.apache.avro
avro-maven-plugin
1.7.5
schemas
generate-sources
schema
protocol
idl-protocol
${project.basedir}/src/main/avro/
${project.basedir}/src/main/java/
{
"namespace":"avro.domain", // 包名
"type":"record",
"name":"User", // 类名
"fields":
[
{"name":"username","type":"string"}, // 属性名以及属性类型
{"name":"age","type":"int"}
]
}
@Test
public void write() throws Exception{
User u1 = new User("Ken Tompson",194375);
User u2 = new User("丹尼斯·里奇",194170);
DatumWriter
DataFileWriter
// 创建底层的文件输出通道
// schema - 序列化类的模式
// path - 文件路径
dfw.create(u1.getSchema(),new File("1.txt"));
// 把对象数据写到文件中
dfw.append(u1);
dfw.append(u2);
dfw.close();
}
@Test
public void read() throws Exception{
DatumReader
DataFileReader
//--通过迭代器,迭代出对象数据
while(dfr.hasNext()){
System.out.println(dfr.next());
}
}
proto类型 |
Java类型 |
说明 |
double |
double |
双精度浮点型 |
float |
float |
单精度浮点型 |
int32 |
int |
使用可变长编码方式,编码负数的时候不够高效。如果编码负数,建议使用sint32 |
int64 |
long |
使用可变长编码方式。编码负数的时候不够高效。如果包含负数,建议使用sint64 |
uint32 |
|
对应于无符号整数int |
uint64 |
|
对应于无符号整数long |
sint32 |
int |
使用可变长编码方式。编码通常比int32高效 |
sint64 |
long |
使用可变长编码方式。编码通常比int64高效 |
fixed32 |
int |
固定4个字节。如果数值比228大的话,用此方式比较高效 |
fixed64 |
long |
固定8个字节。如果数值比256大的话,用此方式比较高效 |
sfixed32 |
int |
固定4个字节 |
sfixed64 |
long |
固定8个字节 |
bool |
boolean |
布尔值 |
string |
String |
字符串 |
bytes |
ByteString |
字节序列 |
Proto类型 |
Java类型 |
message |
class |
enum |
enum |
map |
Map |
service |
RPC interface |
package cn.tedu;
message Person {
// 定义int类型的属性id
// required表示该属性为必须属性
required int32 id = 1;
// 定义String类型的属性name
required string name = 2;
// 定义int类型的属性age
// optional表示可选属性
optional int32 age = 3;
}
public class ProtoBuffDemo {
public static void main(String[] args) throws FileNotFoundException, IOException {
// 创建对应的Person对象
// 注意:该创建方式是建造者模式
Person p = Person.newBuilder().setId(1).setName("Amy").setAge(15).build();
System.out.println(p);
// 序列化/反序列化对象
// 方式一:转化为字节数组
// byte[] data = p.toByteArray();
// Person px = Person.parseFrom(data);
// System.out.println(px);
// 方式二:利用流写出或者读取
p.writeTo(new FileOutputStream("person.data"));
Person px = Person.parseFrom(new FileInputStream("person.data"));
System.out.println(px);
}
}
API-RPC
package cn.tedu.rpc;
option java_generic_services=true; // 开启rpc
// 定义请求参数
message Req {
required double num1 = 1;
required double num2 = 2;
required string mname = 3;
};
// 定义返回结果
message Resp {
required double result = 1;
};
// 定义要执行的方法
service CalcService {
rpc add(Req) returns (Resp);
};
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import com.google.protobuf.Descriptors.MethodDescriptor;
import com.google.protobuf.Message;
import com.google.protobuf.RpcCallback;
import com.google.protobuf.RpcChannel;
import com.google.protobuf.RpcController;
import cn.tedu.rpc.Calc.CalcService;
import cn.tedu.rpc.Calc.Req;
import cn.tedu.rpc.Calc.Resp;
public class Client {
public static void main(String[] args) {
// 获取要调用的远程对象的本地存根
// 该存根和远程的方法一致
// 调用存根的任何方法,在底层都会调用传入的RPChannel中的callMethod方法
// 所以需要自己来实现callMethod方法来实现其中的真正远程调用
CalcService stub = CalcService.newStub(new RpcChannel() {
@Override
public void callMethod(MethodDescriptor md, RpcController controller, Message req, Message resp,
RpcCallback
try {
Socket s = new Socket();
s.connect(new InetSocketAddress("127.0.0.1", 8080));
// 获取指向远程服务器的输出流
OutputStream out = s.getOutputStream();
// 序列化请求对象
byte bs[] = req.toByteArray();
// 进行发送
out.write(bs);
s.shutdownOutput();
// 获取返回结果
Resp rx = Resp.parseFrom(s.getInputStream());
s.shutdownInput();
// 调用回调对象
cb.run(rx);
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
// 准备请求对象
Req req = Req.newBuilder().setNum1(3).setNum2(5).setMname("add").build();
// 调用方法
stub.add(null, req, new RpcCallback
@Override
public void run(Resp resp) {
System.out.println("获取到远程调用的结果:" + resp.getResult());
}
});
}
}
}
}
import java.net.ServerSocket;
import java.net.Socket;
import com.google.protobuf.BlockingService;
import com.google.protobuf.Descriptors.MethodDescriptor;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;
import cn.tedu.rpc.Calc.CalcService;
import cn.tedu.rpc.Calc.Req;
import cn.tedu.rpc.Calc.Resp;
import cn.tedu.rpc.Calc.CalcService.BlockingInterface;
public class Server {
public static void main(String[] args) throws Exception {
// 创建服务器端对象
ServerSocket ss = new ServerSocket(8080);
Socket s = ss.accept();
// 获取请求参数
Req req = Req.parseFrom(s.getInputStream());
s.shutdownInput();
// 创建真正的远程调用对象,用于处理客户端发送来的调用请求
CalcServiceImpl calc = new CalcServiceImpl();
// 包装calc对象,可以便捷的实现利用方法名来调用真正的方法
BlockingService service = CalcService.newReflectiveBlockingService(calc);
// 获取方法名以及对应的实际方法
MethodDescriptor descriptor = service.getDescriptorForType().findMethodByName(req.getMname());
// 执行方法
Resp resp = (Resp) service.callBlockingMethod(descriptor, null, req);
// 写出数据
resp.writeTo(s.getOutputStream());
s.shutdownOutput();
// 关流
ss.close();
}
}
class CalcServiceImpl implements BlockingInterface {
@Override
public Resp add(RpcController controller, Req request) throws ServiceException {
// 计算结果
Resp resp = Resp.newBuilder().setResult(request.getNum1() + request.getNum2()).build();
return resp;