1

我正在尝试使用 JDBC 从 oracle 下载 BLOB 数据。为了知道获取blob数据的平均响应时间,我正在使用JMeter调用一个或多个线程的Getting blob data 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=&apos;testdata1M.csv&apos;</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>
4

2 回答 2

1

如果有足够的硬件,Oracle 数据库可以扩展到数十万同时用户。因此,您看到的结果要么是由于硬件的限制,要么是由于您编写程序的方式存在缺陷。

例如,如果您的服务器只有一个核心,那么它一次只能做一件事。因此,两个用户运行它需要两倍的时间。并不是说那是实际发生的事情,只是说明它可能是什么。

于 2013-02-06T13:06:28.657 回答
1

正如你编码它你正在测量: - 连接到 db - blob 读取 - 连接关闭

您也许可以使用 JDBC 配置元素:

http://jmeter.apache.org/usermanual/component_reference.html#JDBC_Connection_Configuration

因此,在您采样之前建立了连接。

然后通过查看 jdbc 请求如何工作以访问数据库连接来修改您的代码:

 conn = DataSourceElement.getConnection("Variable Name used in JDBC_Connection_Configuration");
于 2013-02-10T10:09:45.140 回答