我正在尝试使用JDBC从oracle下载BLOB数据。 为了知道获取blob数据的平均响应时间, 我正在使用JMeter来调用Getting blob数据Java程序 一个或多个线程。但我得到了奇怪的响应时间,我不能 理解。
我在下面尝试了一些测试。(blob数据大小是1M)
1.在一个线程中使用Jmeter获取blob数据
2.用两个线程中的Jmeter获取blob数据
3.使用两个线程中的JMeter在同一个表中获取不同的blob数据
4.使用Jmeter在两个线程中获取不同表中的不同blob数据。
从测试1和测试2中,我发现测试2的响应时间几乎是测试1的两倍 我无法理解这一点(我的服务器有四个内核,没有人使用它)。 当我得到相同的blob数据时,我怀疑是否有锁,所以我尝试了测试3。 但响应时间几乎与test2相同。然后我尝试了测试4 当我访问同一个表时确保是否有锁,但响应时间 测试4的测试也与测试3相同。
我认为oracle可以同时处理很多用户的请求,所以我不能 了解我从测试中得到的结果。 oracle在同时获取blob数据时是否有一些限制?
这是获取blob数据的代码
public SampleResult runTest(JavaSamplerContext arg0) {
////
try {
Class.forName(JDBC_CLASS_NAME);
conn=DriverManager.getConnection(JDBC_THIN+dbserverIp+":"+port+":"+sid,dbuser,userPwd);
statement=conn.createStatement();
rs=statement.executeQuery(sqlText);
responseStr=RESPONSE_DATA_OK_HEAD+KAIGYOU_CODE;
if(rs.next()){
String fileId=rs.getString(FILE_ID_COLUMN_NAME);
oracle.sql.BLOB blob=((OracleResultSet)rs).getBLOB(BLOB_COLUMN_NAME);
in=blob.getBinaryStream();
int size=blob.getBufferSize();
byte[] buffer=new byte[size];
int len=-1;
bos=new ByteArrayOutputStream();
while((len=in.read(buffer))!=-1){
readCount=readCount+1;
bos.write(buffer,0,len);
}
byte[] blobValues=bos.toByteArray();
responseStr=responseStr+fileId+","+blobValues.length+","+readCount+KAIGYOU_CODE;
}else{
responseStr=RESPONSE_DATA_ZERO;
}
} catch (Exception e) {
e.printStackTrace();
getNGSampleResult(e,sr);
return sr;
}finally{
try {
if(rs!=null){
rs.close();
rs=null;
}
if(statement!=null){
statement.close();
statement=null;
}
if(conn!=null){
conn.close();
conn=null;
}
if(in!=null){
in.close();
in=null;
}
if(bos!=null){
bos.close();
bos=null;
}
} catch (Exception e) {
e.printStackTrace();
getNGSampleResult(e,sr);
return sr;
}
}
sr.sampleEnd();
sr.setSuccessful(true);
sr.setResponseCodeOK();
sr.setResponseMessageOK();
sr.setResponseData(responseStr,"UTF-8");
sr.setDataType(SampleResult.TEXT);
return sr;
}
这是测试计划
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.1">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Parameter" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="env_test_date" elementType="Argument">
<stringProp name="Argument.name">env_test_date</stringProp>
<stringProp name="Argument.value">20130202</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="env_test_case" elementType="Argument">
<stringProp name="Argument.name">env_test_case</stringProp>
<stringProp name="Argument.value">Run at the same time</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="env_test_filesize" elementType="Argument">
<stringProp name="Argument.name">env_test_filesize</stringProp>
<stringProp name="Argument.value">1M</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="env_test_thread" elementType="Argument">
<stringProp name="Argument.name">env_test_thread</stringProp>
<stringProp name="Argument.value">2users</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="ULDLtest" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="loop controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<intProp name="LoopController.loops">-1</intProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">2</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<longProp name="ThreadGroup.start_time">1358319600000</longProp>
<longProp name="ThreadGroup.end_time">1358328499000</longProp>
<boolProp name="ThreadGroup.scheduler">true</boolProp>
<stringProp name="ThreadGroup.duration">300</stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<hashTree>
<JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Java DL BLOB Request" enabled="true">
<elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="SQL_TEXT" elementType="Argument">
<stringProp name="Argument.name">SQL_TEXT</stringProp>
<stringProp name="Argument.value">select * from t_download_file_data t where t.file_id='testdata1M.csv'</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="DB_USER" elementType="Argument">
<stringProp name="Argument.name">DB_USER</stringProp>
<stringProp name="Argument.value">xxxx</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="USER_PWD" elementType="Argument">
<stringProp name="Argument.name">USER_PWD</stringProp>
<stringProp name="Argument.value">xxxx</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="SID" elementType="Argument">
<stringProp name="Argument.name">SID</stringProp>
<stringProp name="Argument.value">xxxxx</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="DBSERVER_IP" elementType="Argument">
<stringProp name="Argument.name">DBSERVER_IP</stringProp>
<stringProp name="Argument.value">xxx.xx.xx.xx</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="PORT" elementType="Argument">
<stringProp name="Argument.name">PORT</stringProp>
<stringProp name="Argument.value">1521</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="classname">sample.TestSamplerClient</stringProp>
</JavaSampler>
<hashTree/>
<ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="Reust for table" enabled="false">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>true</xml>
<fieldNames>false</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="Result for graph" enabled="false">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>true</xml>
<fieldNames>false</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
<ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="Report" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>true</xml>
<fieldNames>false</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
</value>
</objProp>
<stringProp name="filename">log\ULDLPerformance_${env_test_case}_${env_test_thread}_${env_test_filesize}_${env_test_date}.jtl</stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
答案 0 :(得分:1)
如果有足够的硬件,Oracle数据库可以扩展到数十万个并发用户。因此,您所看到的结果要么是由于硬件的限制,要么是您编写程序时的缺陷。
例如,如果您的服务器只有一个核心,那么它一次只能做一件事。因此,针对它运行的两个用户需要两倍的时间。不是说这就是实际发生的事情,只是说明它可能是什么样的事情。
答案 1 :(得分:1)
编码时你正在测量: - 与db的连接 - blob阅读 - 连接关闭
您可以使用JDBC Configuration元素:
http://jmeter.apache.org/usermanual/component_reference.html#JDBC_Connection_Configuration
以便在您采样之前建立连接。
然后通过查看jdbc请求如何访问数据库连接来修改代码:
conn = DataSourceElement.getConnection("Variable Name used in JDBC_Connection_Configuration");