1FIX6.0协议介绍朱立上海证券交易所技术规划与服务部,上海200120Email:lzhu@sse.com.cn摘要:FIX协议(及由此衍生的STEP协议)已在国内证券业界获得了广泛应用。FIX协议本身并不完美,尤其是在当前全球证券业界极力追求降低交易时延的风潮下,FIX协议在性能方面的问题显得尤为突出。FIX标准化组织当前正致力于制订可用于高性能数据传输的FIX6.0,本文拟对此协议的最新状况作一介绍。关键词:FIX,会话层协议,编码1引言FIX(FinancialInformationeXchange)协议最初是由多个致力于提升其相互间交易流程效率的金融机构和经纪商于1992年共同发起。这些企业把他们及他们的行业视为一个整体,认为能够从对交易指示,交易指令及交易执行的高效电子数据交换的驱动中获利。在以后的日子里,FIX协议逐步获得了全球金融机构的广泛接受及认同,中国也于2004年基于FIX4.4版本制订并发布了STEP1.0协议(SecuritiesTradingExchangeProtocol),用于证券交易所交易系统与市场参与者系统之间的证券交易和市场数据发布。FIX协议自诞生之初就存在若干设计缺陷,对这些缺陷的持续改进伴随着FIX协议的版本发展。虽然在1992年时ISO/OSI的七层模型早已确立多年,但FIX协议最初的设计者没有有效地对会话层和应用层进行区分,要使用FIX应用层协议就必须同时使用FIX会话层协议,因为二者共享同一个协议版本,因此各自是整体协议的一部分。虽然到了2000年已经出现了多种成熟的消息传输中间件,遵循协议的用户却不能用这些中间件来简单替换复杂的FIX会话层协议,因此限制了用户的选择,提升了用户的成本。为解决这个问题,在2006年10月发布的FIX5中引入了TI(TransportIndependence)框架以分离FIX会话层和应用层协议,使得应用层协议消息可以通过任意合适的传输技术进行传送,原先的FIX会话层协议(FIXT)则降格为FIX应用层消息的可选传输协议之一。但是因为FIX4.2和FIX4.4暂时仍然保有众多用户,因此对这些用户而言问题依然存在。除此之外,FIX协议最早的设计者没有意识到纯文本的tag/value编码方式带来的网络带宽开销,而协议设计的本意却是要来互联多个不同的金融业务实体,因此两者之间不太可能基于局域网进行互联,这样就构成了一对矛盾。2005年,FIX标准化组织(当时叫FPL)开始制订FAST协议以求降低网络带宽。FAST编码解码有效降低了网络带宽,但因其编解码效率较低,因此在当今极力追求降低交易和行情时延的流行风潮下显得略有不合时宜。在FIX会话层协议中规定了一套用于维护消息有序无失传输的机制。因为其下的传输层有不同的特性,其上的应用层也有不同的需求,因此并非在任何场合下这套机制都是必要的。一刀切的强制规定丧失了通过降低服务等级提升性能的可能性。由于性能方面的制约,FIX协议在获得广泛应用的同时,也面临着巨大的挑战。很2多时候FIX协议面临着这样一种尴尬的场面:在某公司刚进入某个市场开展交易的时候,出于快速搭建互联交易通道的考虑,初期他会使用FIX协议接口完成交易;随着业务的开展,由于时延等方面的压力,最终这些公司都会转向该市场提供的私有二进制协议接口。为了应对高性能的挑战,FIX标准化组织于2010年设立了高性能工作组(HPWG),专注于适用于高性能计算环境的FIX6的制订工作,目前协议制订工作接近完成。作为HPWG的成员之一,本文作者得以于第一时间了解其最新状况,在此谨对其作一介绍。2FIX6的协议分层FIX6的逻辑分层完全参照ISO/OSI网络七层模型,参见图1。SBEFIXP(FIX高性能会话层协议)如TCP/UDP如IP如802.3应用层表示层会话层传输层网络层数据链路层物理层FIX应用层/其他应用协议GPBASN.1FASTTag-ValueSOF(可选)FIXP具体编码方式图1FIX6协议栈的逻辑分层FIX6并不覆盖全部七层协议,事实上它只对应用层、表示层和会话层分别进行了规范。虽然规范之间彼此独立,但又能通过组合来满足用户需求,深得协议分层的三昧。FIX6的一个特点是对应用层和表示层进行了明确区分,本质是将信息和信息编码进行区分。因此,FIX6的应用层并不就是传统的tag=value文本,而是对每条业务消息的逻辑格式。与之相应地,FIX6允许应用层消息采用各种可能的编码方案,只要通信双方彼此认可。FIX高性能工作组还为此专门成立了三个子工作组,各自设计(或移植)了一套FIX应用层编码规范,分别是SBE(SimpleBinaryEncoding)、GPB(GoogleProtocolBuffer)和ASN.1(AbstractSyntaxNotationOne)。由于某些编码方案本身不具备标识消息边界的作用,或者出于在一次通信过程中对不同消息采用不同编码方式的需要,FIX6中加入了一个可选的消息分帧协议,称为SOF(SimpleOpenFraming)。SOF协议也构成了表示层的一部分。FIX6的会话层协议(FIXP)可谓推倒重来,完全废除了传统的设计。和FIX6的应用层一样,FIXP也只定义了消息的逻辑格式,本身并未预设任何编码方式。FIXP的主要功能是处理登录、登出、心跳交换等等功能,并允许选用不同级别的传输服务。FIXP消息最终必须体现为具体的编码,因此也有其自身的表示层。另一方面,出3于提升编解码性能的考虑,FIX6并不将上层应用层信息编码打包后嵌入特定会话层消息内部(隧道方式)进行传输,而是将编码后的应用层消息和会话层消息首尾相接地串行传送。如果采用隧道方式,要提取应用层消息就必须经历两次解码操作,这样做有悖协议设计的初衷。因其采用串行传送方式,虽然协议的逻辑分层仍如图1所示,但在具体实现上则是将FIXP提升到和应用层相同的层面予以处理,称之为“代理”(delegation)。SBEFIXP(FIX高性能会话层协议)如TCP/UDP如IP如802.3应用层表示层会话层传输层网络层数据链路层物理层FIX应用层GPBASN.1FASTTag-ValueSOF(可选)FIXP具体编码方式代理FIXP图2FIX协议栈的实现分层3FIX6表示层3.1简单二进制编码(SBE)高性能的表示层编码是FIX6降低时延的重要因素。由于FIX6的表示层允许采用各种编码方案,因此HPWG工作组设立了三个子工作组分头设计方案。其中,GPB子工作组制订了如何用google的GPB对FIX应用层进行编码的规范,ASN.1子工作组则考虑如何用ISO/ITU-T的ASN.1解决同样的问题,SBE子工作组则完全自行设计方案。三种方案各有特色,但总体思路多有相同之处,故此这里只对SBE进行简单分析介绍。SBE的设计目标可以总结为:针对高性能交易系统,为编解码的低延时而优化,同时将带宽占用保持在合理的低水平。FIX的tag/value编码方式浪费了带宽,同时使得对于特定字段的直接访问变得困难。另一方面,文本格式的编码方式增加了字符串和本地二进制表示方式间的来回转换,这些都极大制约了对于消息的高性能解析及访问。SBE反其道而行之,同时也注意避免了FAST编码方式中对性能提升的制约因素,因此达到了极高的编解码及字段操纵性能。和FAST类似,SBE在两个层面规定了编码规范,其一是字段编码,其二是消息结构。字段编码解决的是如何将FIX语义类型映射为实际传送的二进制数据,消息结构解决的是如何将多个经过编码的字段组合成一条完整的二进制消息。每条FIX应用报文的具体编码用一个XML格式的模板表示,模板通过带外方式在通信双方间预先交换,类似FAST编码的实践。为了使得接收方能够选用正确的模板进4行解码,发送方发送的消息需要加上SBE标准头后才能发送,标准头中申明了模板编号。通常模板编号会一一对应于消息类型,因此很多时候实际编码后消息中并不需要真正出现消息类型。msgSize(uint16)templateID(uint16)msgmsgSizeSBE头msg依靠编号为templateID的模板进行SBE编码图3SBE标准头在模板中表示单个字段如何编码的方式举例如下:fieldtype=”uint8”name=”MaxPriceLevels”id=”1090”fixUsage=”int”maxValue=”6”presence=”optional”nullValue=”255”/”name”和”id”分别是字段的FIX名称和标签号,可以看出这是一个最大价格档位字段。”fixUsage”字段表示的是该字段在FIX中规定的类型,”type”则规定了实际在线上传输时的数据格式。由于最大值”maxValue”是6,因此实际传送时采用定长整数类型uint8进行编码。如果在线传送的数字是0xFF(256),则表示传送的是特殊的空值。另外可以看出,该字段是可选的。作为实例,十进制的3在线上传送的最终编码就是一个字节:03。因为模板的预先交换,在线上不需要再行传送字段标签信息,节省了带宽。为加快编解码速度,SBE不采用类似FAST的stopbit技术来缩短编码长度,而是尽量将字段映射为定长的本地二进制基本数据类型。为方便解码,在SBE中空值通过传送特殊预设值来表示,因此占据和非空值一样的字节数。为了进一步提升编解码性能,SBE编码还细分为BigEndian编码和LittleEndian编码,收发方可以根据自身情况选用。根据SBE对于消息结构的规定,编码后的字段按照模板中出现的顺序进行传送,而且在字段之间缺省不添加任何补空,或者以预先规定字段在消息编码中起始偏移量的方式来实现定宽补空的字段编码。通过将定长字段集中在消息前部,接收方可以借助模板中提供的知识直接访问消息的特定字段,加快了访问速度。这样做也使得SBE编码的消息可以无需解码就被路由给不同的目的地进行处理,非常适用于交易系统。SBE也支持可变长裸数据的编码,方式是先传送uint8或者uint16类型的数据长度信息,然后再传送给定长度的裸数据。重复组的编码方式也与之类似。3.2FIX6分帧协议SOFFIX6规定的分帧协议SOF非常简单,只包含了两个字段,第一个是识别帧边界的长度字段message_length,第二个是数据帧采用的实际编码方式encoding_type,后者使得在一次会话中可以混用多种编码方式。SOF协议头永远使用网络字节格式——BigEndian进行编码。5该协议是可选的。如果通信双方决定永远只使用同一种编码方式,而且编码后的数据帧自身带有编码后长度的字段(如SBE),则完全可以不启用SOF协议。msg_length(uint32)encoding_type(uint16)encodedmsgmsg_lengthSOFHeaderinbigendianmsgEncoding:SBE/GPB/ASN.1/FAST图4SOF分帧协议头4FIX6会话层(FIXP)4.1设计理念FIX6中高性能会话层协议FIXP(FIXPerformance)的设计目的是要创建一个能够提供可靠、高效率消息交换的增强型会话层协议,用来支持高性能金融消息传递。FIXP保持了清晰的协议分层,甚至可被用于其他业务领域,而不局限于金融市场和交易业务,FIXP也不对消息编码及底层传输协议作出任何预设。为了适应不同应用层的实际需要,也为了充分利用不同底层传输的技术特性,FIXP定义了三种级别的流,并且在通信的两个方向上可以组合使用不同的流,力求只为实际需要的部分支付性能代价。FIXP本身不处理安全问题,依赖其他层面达成安全,比如依赖于双向SSL传输层完成通信加密和基于证书的双向认证。这样做的目的是为了简化协议,集中处理会话问题。4.2会话、传输、多路复用、流典型地,同一交易日中某会员席位到交易所的报盘通信就是一次会话,每个会话都必须由一个唯一的UUID唯一标识,且原则上不允许在会员之间彼此重复,且不能与历史上用过的UUID重复。由于UUID的长度非常大,