标签:dcm4che2 jmeter dicom服务器 dicom性能测试
目前对于传统WEB网站性能(压力/负载)的测试工具有很多,loadrunner、iperf、siege等,操作都比较简单,这里就不介绍了。然而对于医疗领域内的服务器,通常指的是DICOM服务器,提供满足DICOM3.0标准规定的各项DIMSE服务,诸如DIMSE-C(C-STORE、C-FIND、C-MOVE、C-ECHO)、DIMSE-N(N-CREATE、N-DELETE)等等。倘若使用传统的压力测试工具会有几大局限性:
鉴于以上几点原因,我们需要寻找一款合适的能够监测DICOM服务器性能的工具,初步设想有几种可能的方案:
第一种,利用python等语言手动编写测试脚本,循环调用dcm4che2工具包中的dcmsnd.bat工具模拟多用户并发访问。这种方案的优点是思路简单,直接模拟真实用户操作;缺点是利用python调用dcmsnd.bat批处理指令我们只能获取简单的运行时间,且结果不具有可视化,应付简单的测试(比如内部开发人员自我测试)比较可行,不适用于实际项目发布测试。
第二种,利用JMeter、LoadRunner等工具的TCP请求测试,将DICOM文件以二进制形式放到TCP请求数据体中。该方案的优点是可以利用JMeter、LoadRunner等工具诸多可视化功能,对服务器性能进行全面分析;缺点是需要对DICOM协议进行抓包分析,梳理出具体的完整的数据包,难度较大。
第三种,尝试搜索现有工具或解决方案。通过gfsoso、baidu等搜索引擎,检索与DICOM Server performance相关的资料,发现相关性大的很少。主要有以下几篇有参考价值的资料:
JMeter-wiki中jakarta-jmeter-dev中Germany用户的使用实例。
DICOMetrix与Performance Tools for your PACS systems
利用JMeter测试TCP服务器发送十六进制请求
自定义jar包利用JMeter的“Java请求”模拟测试
整理分析上述资料,确定可以实施的方案有以下几种,各方案按照实施可行性高低进行排列:
1)利用开源JMeter工具,通过扩展自己的jar包(在jar包内部模拟dcmsnd请求)结合JMeter现有的”Java请求“完成DICOM服务端测试。具体实施方案可参考以下资料:
【可行性★★★★☆】
【注】:初步设想可以直接在jar包中调用dcm4che工具包中的dcmsnd.jar,实际情形以具体编码时为准,可能会出现很多问题。
2)利用开源JMeter工具,使用wireshark等抓包工具对现有的dcmsnd与DICOM服务器之间的交互数据包进行提取分析,找出在TCP协议上发送的实际数据包,然后将该数据包手动填充到TCP请求数据体中,利用JMeter的”TCP请求“完成DICOM服务端性能测试。
【可行性★★★☆☆】
【注】:该方法可能的问题是,DICOM整个协议的数据包无法通过一次TCP数据体完成发送,即使顺利完成数据包发送,也很难手动替换每个数据包中的dcm文件体,无法真正模拟多用户并发上传多套数据的应用场景。
3)通过注册DICOMetrix官网账号,申请DICOMetrix60天免费试用版对DICOM服务器进行测试。
【注】:由于该工具使用者较少,目前没找到破解版,即使获得试用版对其测试性能也有所怀疑。
本文基于JMeter+dcm4che2工具的基础上,决定尝试实施第一解决方案。通过“扩展JMeter”方式初步实现了模拟多用户并发调用dcmsnd发送多组数据到PACS影像服务器的测试,具体实现方式如下:
JMeter是Apache下开源测试框架,扩展方式有多种,诸如自定义协议扩展、Java请求扩展等等。此处采用的JMeter扩展方式为“Java请求扩展”,即通过继承AbstractJavaSamplerClient类,重写其中的runTest函数来完成对dcm4chee2影像服务器的存储服务压力测试。
在runTest函数内部直接调用现有的dcmsnd工具包的main函数,通过在runTest中自动构建main函数的命令行参数arg0,来实现模拟多用户并发调用dcmsnd发送dcm文件到dcm4chee2服务器的场景。具体实现代码如下:
public SampleResult runTest(JavaSamplerContext arg0) { String ipAddr=arg0.getParameter("IP","127.0.0.1"); String portString=arg0.getParameter("Port", "11112"); String calledAET=arg0.getParameter("AET", "DCM4CHEE"); String callingAET=arg0.getParameter("CallingAET", "DCM4CHEE"); String filePath=arg0.getParameter("FilePath", ".\\"); int threadnum=arg0.getIntParameter("ThreadNumber"); ++dirIndex; String dirPath=String.valueOf((int)(Thread.currentThread().getId())%threadnum+1); System.out.println("Current Thread id is "+String.valueOf(Thread.currentThread().getId())); String[] args=new String[]{ calledAET+"@"+ipAddr+":"+portString, filePath+"\\"+dirPath }; SampleResult sampleResult=new SampleResult(); sampleResult.sampleStart(); try { DcmSnd.main(args); sampleResult.sampleEnd(); sampleResult.setSuccessful(true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sampleResult.sampleEnd(); sampleResult.setSuccessful(false); } return sampleResult; }
1)将上述备选方案导出为jar包,例如jMeterTestDICOM.jar。
2)拷贝jMeterTestDICOM.jar包到JMeter的lib/ext目录下;
3)将jMeterTestDICOM.jar包依赖的jar包同时拷贝到lib/ext目录下,即dcm4che2-2.0.28/lib下的所有jar包(为了保险起见,拷贝所有jar包)
4)进入JMeter源码的bin目录,运行jMeter.bat脚本,弹出启动界面:
5)在JMeter中新建Java请求测试方案(具体操作参考:http://www.cnblogs.com/yuki-lau/archive/2013/04/20/3033010.html)
6)在Java请求中选中刚才新建的jMeterTestDICOM.jar包的dcmSendSamper类,如下图:
7)如图中输入IP、Port、AET、CallingAEt、FilePath、ThreadNumber参数,即可启动压力测试。
【说明】:上图中的参数最终会传递到dcmSendSampler类中,runTest中会自动构造dcmsnd的命令行参数,即AET@IP:Port。其中需要格外说明的是FilePath参数,为了尽最大可能模拟现实中多用户并发上传,希望JMeter的每个线程传递的数据是不同的,因此在FilePath中是根目录,通过结合ThreadNumber(即总的JMeter线程并发数)来自动构造不同的二级目录,构造方式是:FilePath+”\”+String.valueOf(Thread.CurrentThread().getId()%ThreadNumber+1),即JMeter并发线程数有多少,就需要在FilePath根目录下创建从1到并发线程数对应数量的文件夹,内用任意数量的dcm文件填充。
由于直接使用的是dcm4che2工具包的工具,对于具体的测试结果就不分析了,直接贴几张实测结果图:
作者:zssure@163.com
时间:2015-05-24
DICOM:基于JMeter+dcm4che2测试PACS服务器性能的解决方案(前篇)
标签:dcm4che2 jmeter dicom服务器 dicom性能测试
原文地址:http://blog.csdn.net/zssureqh/article/details/45953291