最近团队在开发基于移动互联网的项目,又一次涉及到post service,即在服务器集群之间投递消息。是的,又是一个RPC服务。RPC实现方式从笨重的CORBA,SOAP over HTTP,XMPP over TCP,到轻量级的protobuf,scribe和Avro。这里不想比较各自的应用场景(另外后面三种RPC方式极为接近,都是通过提供Object <-> 二进制映射来提高高效的传输),本文的目的是给大家一点可以实际操作的代码:java如何用protobuf 实现rpc
和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伪代码应该是这样的:
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:
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:
Maoyidao.MaoyidaoPacket packet = Maoyidao.MaoyidaoPacket.newBuilder()
.setCmd(mycmd)
.setSubcmd(mysubcmd)
.setContent(ByteString.copyFromUtf8("some message")).build();
我们先不讨论怎么基于MINA创建一个NIO,先假设我们获得了一个OutputStream,看看怎么把消息写出去(其中的关键是用一些特殊的字符来区分你的消息,这是RPC over TCP的基本要求):
List 3:
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中读到校验码:
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原创,转载请引用原链接:
分享到:
相关推荐
MINA是一个异步事件驱动的网络应用程序框架,它提供了一套可扩展的、高性能的、跨平台的网络通信工具。MINA的核心理念是基于事件驱动和非阻塞I/O模型,这使得它在处理大量并发连接时表现出色,尤其适合构建高性能的...
Mina(Multithreaded Internet Network Application)框架是由Apache软件基金会提供的一个高性能、可伸缩的网络编程框架,它主要应用于Java NIO环境下的网络通信开发。Mina通过采用多线程模型和异步I/O技术来提高...
Apache Mina是一个高度可扩展的网络通信框架,它允许开发者创建高性能、高效率的服务端和客户端应用程序。在Java世界中,Mina以其简洁的API和灵活性而受到青睐,尤其适用于处理大量的并发连接,如TCP/IP和UDP协议。...
Apache Mina是一个开源项目,它提供了一个高度可扩展且高性能的网络通信框架,支持多种协议,如TCP、UDP等。 首先,理解Mina的核心概念是必要的。Mina基于事件驱动和异步模型,允许开发者创建高效的网络应用。其...
由于这一系列的重大改进,使得 2.0.x 成为十分令人期待的一个版本 我们在惊叹 MINA 可以带来多么大便利的同时,还不得不为其卓越的性能而骄傲,据称使用MINA开发服务器程序的性能已经逼近使用 C/C++ 语言开发的...
Apache Mina是一个开源项目,它提供了一个高度可扩展和高性能的网络通信框架。这个实例是基于Mina框架构建的一个应用程序,名为"BTUSimulator",它可能是用来模拟某种网络通信或者服务的。让我们深入探讨一下Mina...
标题"基于Java的实例源码-高性能Java网络框架 MINA.zip"表明,这是一个关于Java网络编程的实例源代码包,使用的框架是MINA(Multipurpose Infrastructure for Network Applications)。MINA是一个高性能、异步事件...
它提供了高度可扩展和高性能的非阻塞I/O模型,使得开发者能够构建出高效的网络服务。MINA的目标是为Java开发者提供一个统一的API,无论底层网络通信是基于套接字(Socket)还是数据报(Datagram)。 Apache MINA的...
Apache Mina2是一个基于事件驱动的网络应用框架,主要应用于开发高性能和高可用性的网络服务器。它支持多种协议,如TCP、UDP、SSL/TLS等,且提供了一套完整的过滤器体系,允许开发者在数据传输过程中添加自定义处理...
它提供了高度可扩展和高性能的网络协议处理能力,支持多种传输层协议,如TCP/IP、UDP/IP和SSL/TLS等。在本示例中,我们关注的是"Mina客户端",即如何使用Mina库创建一个简单的客户端应用。 标题中的"mina客户端简单...
总的来说,Apache Mina为开发者提供了一套强大的工具,帮助他们轻松地构建高性能、可扩展的网络应用程序。通过学习和实践Mina实现长连接和短连接的例子,我们可以深入了解网络编程的细节,提升我们的技能,为构建...
Apache的Mina(Multipurpose Infrastructure Networked Applications)是一个网络应用框架,可以帮助用户开发高性能和高扩展性的网络应用程序;它提供了一个抽象的、事件驱动的异步API,使Java NIO在各种传输协议...
这就是一个基础的Mina入门实例,展示了如何使用Mina进行客户端-服务器间的通信。随着深入学习,你可以了解更多的Mina特性,如心跳机制、多线程处理、会话管理等,以构建更复杂、高效的网络应用。
Apache MINA是一个高性能、异步事件驱动的网络应用程序框架,主要设计用于简化开发服务器端的高性能网络应用。这个框架提供了一种抽象层,允许开发者使用相同的API处理多种不同的传输协议,如TCP/IP、UDP/IP以及SSL/...
Apache MINA(Multipurpose Infrastructure for Network Applications)是一个高性能、异步事件驱动的网络应用程序框架,专为开发基于TCP/IP和UDP/IP协议的应用程序而设计。MINA的目标是简化网络编程,使得开发者...
本文介绍了一种基于高性能Java NIO的MINA框架,用以构建高性能的即时通讯系统服务器。MINA框架(Multipurpose Infrastructure for Network Applications)是基于Java NIO设计的网络应用程序框架,其特点是采用松耦合...
Mina 服务器设计方法基于状态机的高性能服务器设计方法 Mina 服务器设计方法是基于状态机的高性能服务器设计方法,旨在提高服务器的性能和可靠性。该方法使用 Mina 网络应用程序框架和有限状态机,对服务器的设计和...
Apache MINA(Multipurpose Infrastructure for Network Applications)是一个Java框架,专为开发高性能和高度可扩展的网络应用程序而设计。MINA 提供了一种抽象层,允许开发者远离底层的Socket编程,专注于业务逻辑...
在IT行业中,网络通信是至关重要的一个领域,而Apache Mina作为一个高性能、事件驱动的网络应用框架,广泛应用于TCP、UDP等协议的开发。本文将深入探讨Mina框架中的长连接与短连接,并通过提供的Minaclient和...
Apache MINA(Multipurpose Infrastructure for Network Applications)是一个高级网络通信框架,主要针对Java平台设计,提供了高度可扩展和高性能的网络应用开发环境。MINA旨在简化网络编程,特别是对于TCP/IP和UDP...