高性能RPC over MINA&google protobuf 代码&实例 (一)
2014-08-11 12:28
597 查看
和protobuf-socket-rpc的区别
protobuf-socket-rpc(code.google.com/p/protobuf-socket-rpc/)是googlecode为rpc写的简单实现。本文介绍的代码和googlecode不同之处在于:1,基于NIO
2,增加了校验码
高性能RPC over google protobuf
Google's protocol buffer library makes writing rpc services easy, but it does not contain a rpc implementation. The transport details are left up to the user to implement.google把这问题留给了我们,那么看看应该怎么实现。hellow world伪代码应该是这样的:
Java代码
MessageLite message = getMessage(); // get a proto message object by proto file
OutputStream out = getOutputStream();
InputStream in = getInputStream();
message.writeDelimitedTo(out); // Like writeTo(OutputStream), but writes the size of the message as a varint before writing the data
messageBuilder.mergeDelimitedFrom(in);
好了,这样就实现了序列化和反序列化。在真正的内容之前加入内容长度,这是一种最简单的实现。为了能可靠的进行传输,我在消息长度前加入了2个byte的验证码,下面就开始逐步构建我的rpc代码。
定义你的proto文件,为传输多种消息,需要有“命令”字段:比如:Maoyidao.proto
List 1:
Java代码
package com.maoyidao.rpc;
message MaoyidaoPacket {
required int32 cmd = 1;
required int32 subcmd = 2;
optional bytes content = 3;
}
OK,compile it to Java class: protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
你会得到一个MaoyidaoPacket 类,然后你需要这样获得实例:
List 2:
Java代码
Maoyidao.MaoyidaoPacket packet = Maoyidao.MaoyidaoPacket.newBuilder()
.setCmd(mycmd)
.setSubcmd(mysubcmd)
.setContent(ByteString.copyFromUtf8("some message")).build();
我们先不讨论怎么基于MINA创建一个NIO,先假设我们获得了一个OutputStream,看看怎么把消息写出去(其中的关键是用一些特殊的字符来区分你的消息,这是RPC over TCP的基本要求):
List 3:
Java代码
private final void writeObject(OutputStream os, Maoyidao.MaoyidaoPacket packet) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
com.google.protobuf.CodedOutputStream cos = com.google.protobuf.CodedOutputStream.newInstance(baos);
cos.writeRawVarint32(3);
cos.writeRawVarint32(7);
cos.writeRawVarint32(packet.getSerializedSize());
vpacket.writeTo(cos);
cos.flush();
os.write(baos.toByteArray());
baos.close();
}
}
注意我不仅写了分隔符,还写了content长度。
读进来的时候要用相同的方式解析,假设我们得到了一个Bytebuffer,熟悉NIO的同学知道,你总是会从ByteBuffer中读取数据。同时我需要用到com.google.protobuf.CodedInputStream:Reads and decodes protocol message fields. This class contains two kinds of methods: methods that read specific protocol message constructs and field
types (e.g. readTag() and readInt32()) and methods that read low-level values (e.g. readRawVarint32() and readRawBytes(int)).)这样我就可以从inputstream中读到校验码:
Java代码
ByteBuffer in = getByteBuffer();
CodedInputStream cis = CodedInputStream.newInstance(in);
int flag1 = cis.readRawVarint32();
int flag2 = cis.readRawVarint32();
if(flag1 != 3 || flag2 != 7){
// find some error
}
int contentLength = cis.readRawVarint32();
int contentLength0 = contentLength + CodedOutputStream.computeRawVarint32Size(contentLength);
if(in.remaining() >= contentLength0){
try {
Maoyidao.MaoyidaoPacket.Builder builder = Maoyidao.MaoyidaoPacket.newBuilder();
CodedInputStream.newInstance(getBytesFromIn(in,contentLength0)).readMessage(
builder, ExtensionRegistry.getEmptyRegistry());
out.write(builder.build());
in.position(in.position() + protocolLength);
return true;
} catch (Exception e) {
//
}
}
// ByteBuffer没有足够的数据,等待下一次
// do something
截止目前,我们完成了带校验码的基于protobuf的消息序列化和反序列。在这个实现中,我更偏向把protobuf当做一个序列化工具来使用,整体还是依赖MINA本身提供的架构,这部分将在本系列的下一篇中详细阐述。
本文系maoyidao原创,转载请引用原链接:
http://maoyidao.iteye.com/blog/1636923
相关文章推荐
- 高性能RPC over MINA&google protobuf 代码&实例 (二)
- 高性能RPC over MINA&google protobuf 代码&实例 (一)
- 高性能RPC over MINA&google protobuf 代码&实例 (二)
- 高性能RPC over MINA&google protobuf 代码&实例 (一)
- Go实战--golang中使用gRPC和Protobuf实现高性能api(golang/protobuf、google.golang.org/grpc)
- 基于Google Protobuff和Mina的RPC
- 使用google protobuf RPC实现echo service
- 简单介绍google protobuf rpc框架使用方法
- 无法解析的外部符号 "__int64 google::protobuf::internal::empty_string_once_init_"
- 谷歌 Google ProtoBuf用法实例
- 基于Google Protobuff和Mina的RPC
- 集成libevent,google protobuf的RPC框架
- google protobuf 简单实例
- 基于Protobuf的分布式高性能RPC框架——Navi-Pbrpc
- google protobuf 简单实例
- gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架
- Google 新实现的Protobuf RPC: grpc
- grpc开源--Google Protobuf RPC实现
- grpc+protobuf 的C++ service 实例解析
- gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架