`
mgoann
  • 浏览: 250247 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

MM2协议简介

阅读更多

MM2协议简介

MM2协议简介

MM2协议采用TCP协议承载,二进制编码格式。除握手消息和心跳消息外,其它消息结构分为MM2协议头部和业务消息体两部分。

 

1MM2消息头定义为定长字段,字段定义固定总长度为(28个字节)。包括:

Length:消息总长度(4个字节)

MessageType:消息类型(4个字节)

SourceModuleType:源模块类型(2个字节)

SourceModuleID:源模块ID(2个字节)

SourceManagerType:源Manager类型(2个字节)

SourceManagerID:源ManagerID(2个字节)

TargetModuleType:目的模块类型(2个字节)

TargetModuleID:目的模块ID(2个字节)

TargetManagerType:目的ManagerType(2个字节)

TargetManagerID:目的ManagerID(2个字节)

SequenceID:由发送方填写,请求和响应消息必须保持一致(4个字节)

 

2MM2消息体定义:

数据类型 是否是必填数据 编码方式 说明

定长数据 直接将数据内容写入消息体

定长数据 可选字段 可选标识+数据内容(如果内容存在) 可选字段为1BYTE0标识不存在,1标识存在,后面跟数据内容。

变长数据 长度+数据内容 长度为4个字节

变长数据 可选字段 可选标识+长度+数据内容

上表中的’+’在实际码流中不存在,仅表示顺序关系。

 

3、通信过程:

MM2协议采用TCP协议承载,支持TCP长连接,不支持TCP短连接。

首先客户端向服务器端发起TCP连接请求建立TCP连接。

 TCP连接建立后,客户端向服务器端发送握手请求消息。握手请求消息中包含有客户端的能力信息,服务器端如果允许客户端握手,则返回握手成功响应消息,握手成功响应消息中包含服务器的能力信息。如果握手失败,则服务器返回握手失败响应。重连间隔时间默认为5秒,可修改。

 MM2连接建立成功之后,双方需要互相发送心跳消息维持连接。心跳消息没有响应。对于任何一方,如果发现在一段时间内没有收到对端发送过来的任何数据(注意:包括心跳消息、业务消息等任何消息)则主动断开连接,并尝试重连。心跳超时时间应设置大于对端的心跳发送间隔时间。默认设置:心跳间隔时间=2秒,心跳超时时间=心跳间隔时间*2

 

MM2协议特点

 

1.       高效

主要体现为:

(1) 长连接

由于Socket连接的建立和关闭很耗性能,所以MM2只建立一次连接,并把连接一致保持着。所谓的多路复用。

缺点:容易出现断连,

可以通过 netstat na | grep (portId)

命令来判断是否连接(有3种状态:LISTEN(监听)ESTABLISHED(连接)TIME_WAIT(等待)

(2) 约定大于配置

如模块双方通信,一方按照某一顺序封装发送消息,另一方则必须严格按照这个顺序进行读取。可以从MM2协议里看出MM2并没有将基本字段类型和结构体一些附加信息写入传输流中,都是通过约束来完成,这样达到了节省了传输负载,提供性能。

缺点:缺乏灵活性,易出去接口不同步。

可通过tcpdump i lo tcp port (portId) Xo 10000 vv

命令抓包进行问题的确认。

(3) 二进制传输

优点:节省流量,性能提高了。

 

2. 安全

(1) 心跳消息

心跳消息无需响应,由连着的双方互发消息。

(2) 握手消息

在建立Socket连接的时候,发送握手消息,进行身份的确认,确认成功才会进行后续的操作。

握手消息由客户端发起,服务端返回相应的响应消息。

 

3.  异构性

MM2协议中只规定了基本类型如何表示,所以不同编程语言实现的模块可以通过MM2协议来交互。

 

4. 支持各种编解码

 

5. 支持集合、数组、自定义结构体。

其中集合和数据是通过一个特殊的4字节标识来表示。

 

MM2java序列化的性能比较

 

1MM2java序列化的性能比较

   示例代码:

      //序列化对象

        TestSerializable ts = new TestSerializable("1001","zhangshun");

        long time = System.currentTimeMillis();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();;

        ObjectOutputStream oos = null;

        for (int i = 0; i < 100000; i++)

        {

            try

            {

                oos = new ObjectOutputStream(baos);

                oos.writeObject(ts);

            }

            catch (IOException e)

            {

                e.printStackTrace();

            }

        }

        System.out.println("serialize length="+baos.toByteArray().length/(1024*1024) +" M");

        System.out.println("serialize used time:" + (System.currentTimeMillis() - time) +"ms");

       

        time = System.currentTimeMillis();

        //MM2编码封装对象

        TestMM2 tmm = new TestMM2("1001","zhangshun");

        long mmLength = 0;

        for (int i = 0; i < 100000; i++)

        {

            byte[] bb = tmm.toByte();

            mmLength += bb.length + 28; //28MM2头长度

        }

        System.out.println("mm2 length = " + mmLength/(1024*1024) + " M");

        System.out.println("mm2 used time:" + (System.currentTimeMillis() - time) +"ms");

 

运行结果:

serialize length=9 M

serialize used time:1875ms

mm2 length = 4 M

mm2 used time:375ms

从中可以看出MM2性能无论是从时间还是空间都要优于java序列化.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics