第七周作业

发布于: 2020 年 07 月 21 日

  • 性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?

随着并发压力的增加,刚开始系统响应时间应该是稳定的,吞吐量会逐步上升,随之出现排队,锁冲突,这个时候响应时间会上升,吞吐量还是会缓慢提升,直到资源利用率趋于饱和这个时候,因为资源争用,响应时间会进一步提升,吞吐量会呈现下降趋势。

  • 用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。

package benchmark;

import java.util.Properties;

public interface Client {

public boolean setUp(Properties prop);

public void test(SampleResult result) ;

public void tearDown();

}

package benchmark;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.MalformedURLException;

import java.net.URL;

import java.net.URLConnection;

import java.nio.charset.StandardCharsets;

import java.util.List;

import java.util.Map;

import java.util.Properties;

import java.util.Map.Entry;

public class HttpClient implements Client {

private String urlName ;

@Override

public boolean setUp(Properties prop) {

urlName = prop.getProperty( "URLNAME", "http://www.baidu.com" ) ;

return true ;

}

@Override

public void test(SampleResult result) {

result.sampleStart();

try {

URL url = new URL(urlName);

URLConnection connection;

connection = url.openConnection();

connection.connect();

Map<String, List<String>> headers = connection.getHeaderFields();

BufferedReader br;

br = new BufferedReader(new InputStreamReader(

connection.getInputStream(), StandardCharsets.UTF_8));

String line = "";

while ((line = br.readLine()) != null);

br.close();

} catch ( IOException e1 ) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

result.sampleEnd();

}

@Override

public void tearDown() {

// TODO Auto-generated method stub

}

}

package benchmark;

public class SampleResult {

private long startTime = 0;

private long endTime = 0 ;

public void sampleStart() {

if (startTime == 0) {

startTime = System.currentTimeMillis();

}

}

public void sampleEnd() {

if (endTime == 0) {

endTime = System.currentTimeMillis() ;

}

}

public long getLatency() {

return endTime - startTime ;

}

}

package benchmark;

public interface TestControl {

public boolean isStopTest();

}

package benchmark;

import java.util.concurrent.atomic.AtomicInteger;

public class LoopControl implements TestControl {

private AtomicInteger loopCount ;

public LoopControl(int count) {

this.loopCount = new AtomicInteger(count) ;

}

@Override

public boolean isStopTest() {

// TODO Auto-generated method stub

return this.loopCount.getAndDecrement() <= 0;

}

}

package benchmark;

public interface TestReport {

public void out();

public void addTestResult(SampleResult res) ;

}

package benchmark;

import java.util.Set;

import java.util.TreeSet;

import java.util.Vector;

import java.util.concurrent.atomic.AtomicLong;

public class TxtTestReport implements TestReport {

private AtomicLong totalSpentTime = new AtomicLong(0) ;

private AtomicLong totalTimes = new AtomicLong(0) ;

private Set<Long > result = new TreeSet<Long>() ;

@Override

public void out() {

// TODO Auto-generated method stub

System.out.println("***************************test result *****************************") ;

System.out.println("Avg: " + totalSpentTime.get()*1.0 / totalTimes.get() );

int index = ( int ) ( result.size() * 0.95 ) ;

System.out.println("95th: " + result.toArray()[index]);

}

@Override

public void addTestResult( SampleResult res ) {

// TODO Auto-generated method stub

totalSpentTime.addAndGet( res.getLatency() ) ;

totalTimes.incrementAndGet() ;

synchronized(result) {

result.add( res.getLatency() ) ;

}

}

}

package benchmark;

import java.util.Properties;

public class Executor implements Runnable {

private Client testClient ;

private Properties prop ;

private TestControl testCtrl ;

private TestReport report ;

public Executor(Client client, Properties prop ) {

this.testClient = client ;

this.prop = prop ;

}

public void setTestControl(TestControl testCtrl) {

this.testCtrl = testCtrl ;

}

public void setReport( TestReport report) {

this.report = report ;

}

@Override

public void run() {

if ( testClient.setUp( prop )) {

SampleResult result = new SampleResult() ;

while ( ! testCtrl.isStopTest() ) {

testClient.test(result);

this.report.addTestResult( result );

}

testClient.tearDown();

}

}

}

package benchmark;

import java.util.Properties;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Test {

public static void main(String[] args) {

String url ;

int threadCount = 0 ;

int loopCount = 0 ;

for (int i = 0; i < args.length; ++i) {

if ( args[i].equals("--threads") ) {

threadCount = Integer.parseInt( args[++i] );

}else if ( args[i].equals("--url") ) {

url = args[++i];

}else if (args[i].equals("--loopcount")) {

loopCount = Integer.parseInt( args[++i]);

}else {

System.out.println("error input") ;

System.exit( 1 );

}

}

if (threadCount <=0 || loopCount <= 0) {

System.out.println("error input") ;

System.exit( 1 );

}

LoopControl ctrl = new LoopControl(loopCount) ;

TestReport report = new TxtTestReport();

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

for (int i = 0; i <threadCount; ++i) {

Executor executor = new Executor(new HttpClient(), new Properties()) ;

executor.setTestControl( ctrl );

executor.setReport( report );

cachedThreadPool.execute(executor) ;

}

cachedThreadPool.shutdown();

while(!cachedThreadPool.isTerminated()) {

try {

Thread.sleep( 1000 );

} catch ( InterruptedException e ) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

report.out();

}

}

测试结果

***************************test result *****************************

Avg: 176.91

95th: 328

用户头像

Linuxer

关注

还未添加个人签名 2018.06.12 加入

还未添加个人简介

评论

发布
暂无评论
第七周作业