UML软件工程组织

第三方模拟测试环境的搭建
陈志春
摘要: 应用软件与第三方实时通讯时,由于开发进度以及通讯条件的限制,需要模拟第三方的通讯程序,以利测试和维护。本文就此发表自己的一些观点。
  关键词:中间业务 模拟测试环境 server daemon、client daemon
  近年来我一直从事中间业务软件的开发与维护,所谓中间业务,就是银行作为中间人、代理人的角色帮客户和第三方委托单位办理的一些业务,比如各种话费代收、保险费代缴、水费代收等等。开发中间业务软件,难点在于银行方要与第三方(电信局等委托单位,以下简称第三方)实时交换数据,而银行与第三方的软件开发往往不是同一个软件公司承担,从而导致需求分析、接口定义的不一致性、复杂性,并且双方技术力量的不同经常导致开发进度的不一致,我行为保证开发进度以及软件质量,往往需要为第三方搭建一个模拟测试环境。以下是我在组建模拟测试环境的实践中总结的一些经验和方法。
  模拟环境要能够较为全面地模拟出第三方系统所能够实现的功能,从总体上来说,所有的交易可划分为两大块:由我方发起的交易和由对方发起的交易;为此在模拟机上要建立相应的模拟server 程序和模拟client 程序,server程序接收我方发起的交易而client程序发起对方的交易;
  模拟环境一般只模拟到对方的前置机一级,因为我方与对方系统要交换的只有请求报文和响应报文,至于各自系统中对每笔交易的帐务处理和流程对对方都是透明的。当然模拟环境也必须模拟到前置机一级,否则请求报文还没送到对方就被返回,根本没有测试到我方相关的通讯子程序,实际联调的时候还须先解决通讯中可能存在的问题,就没有起到模拟第三方的作用了。
  双方通讯采用标准的tcp/ip协议,报文交换则可有几种不同的方法,我们采用的主要有ISO8583国际标准包协议和自定义字符串方式两种,建议在对方允许的情况下尽量采用ISO8583包格式,既可减少通讯量又可利用统一的打包、解包函数。联系前面提到的server 和client 服务,则模拟前置机上可能用到的程序共有以下四个:采用ISO8583报文交换的server程序 和client程序 ,以及采用自定义字符串方式交换报文的server程序和client 程序。当然,针对某个特定的委托单位只会用到其中的一对程序。一般来说,server 程序要常驻内存,它接收请求然后返回模拟的响应报文,因为没有实际的第三方数据库可供检索和处理,server程序只能简单地根据不同的请求类型返回相对固定的响应数据,例如,对所有的用户的话费查询,server程序只能返回同样的话费余额和明细,当然,不同类型的请求报文返回的响应报文还是不一样的。如果时间充裕,还可以把server的功能做得尽可能完善:对接收到的请求报文格式作合法性检查,对每一种交易都可以有成功与失败两种返回结果,甚至考虑每一种交易的可能的自动冲正报文,等等;client 程序则做成一般的执行程序,每向我方前置机发起一个交易后即退出运行。client 程序应能模拟第三方发起的每种交易,并接收相应的返回。client 程序还应模拟第三方的可能的错误报文,以检验我方通讯程序能否正常处理。
  在确定了通讯协议和报文交换格式之后,对每一个交易,还存在一个长联接和短联接的问题:发起方发起请求后是一直保持原来的联接等待对方的响应呢还是立即断链,等对方取得响应报文后由对方重新建立新的联接?若采用前一种实现方法则称为长联接,实现起来较为简单,且可靠性较高,比较适合于业务量较小且对方业务处理延迟较小的单位和场合,长联接的缺点是不能缓冲请求报文与响应报文,当交易高峰期很多请求差不多同时到达的时候会拒绝一些请求,从而影响到业务的办理。短联接则不同,一般短联接都会在内存中建立两个消息队列,一个存放所有到达的请求报文,另一个存放所有收到的响应报文;对应每一个消息对列,有一个daemon 进程(即常驻后台运行的程序)专门处理其中的每一个报文,这样就把发起请求后等待响应报文的时间去掉了(这部分时间包括对方业务处理的时间和返回的传送时间,一般占整个交易时间的80%以上),请求daemon只管不停的把请求队列中的请求报文发出去,不需要等待任何一个响应报文的返回,而响应daemon 则专门处理收到的响应报文;这里要特别注意的是,由于业务处理系统的并发处理机制,发出去的请求报文顺序与接收到的响应报文顺序不一定相同,因而要确定一种请求报文与响应报文之间的连接方式,一般考虑用报文中某个唯一字段如主机流水号来建立两者之间的一一对应,以免造?quot;张冠李戴",即把后一个交易的响应报文作为前一个交易的响应返回给前台;当然短联接也有其缺点:对消息队列的管理不当有可能导致响应报文严重超时,例如第三方数据库down下来了,把所有的请求报文缓冲起来,等几分钟或几十分钟后数据库恢复正常,再对缓冲的请求报文进行处理,事实上此时的处理已经无效,因为发起请求的前端早就对此笔交易作超时处理,不需要它的返回报文了。
  下面简单介绍一下以socket编程的server程序和client 程序的一般处理流程:
server端:
1、通过socket()函数向系统申请一个套接字;
  一般用法: socket(AF_INET , SOCK_STREAM , 0 ) ;
  其中AF_INET SOCK_STREAM 为系统定义的常量,指明了所需套接字的用途。
2、调用 bind()函数为该次通讯定义一个侦听端口号
3、调用 listen()函数侦听可能的请求
4、组织循环,处理收到的每一笔请求:
4、1 用accept()函数建立交换数据的通道;
4、2 用read()函数读取请求报文
4、3 根据请求报文进行业务处理,形成响应报文
4、4 调用write()函数返回响应报文
4、5 调用close()函数关掉套接字
client端:
1、通过socket()函数向系统申请一个套接字;
2、调用 connect()函数与server 端建立连接
3、调用 write() 函数发出请求报文
4、调用 read()函数读取响应报文
5、调用 close()函数关掉套接字
  总之,第三方模拟测试环境的建立不仅有效的减少了合作双方的摩擦,提高了我方应用系统的开发进度,而且极大的方便了整个应用系统的联调,并且在系统运行、维护、优化等过程中也发挥了巨大的作用。

 



版权所有:UML软件工程组织