1,8 → 1,5 |
package ak.httpbench; |
|
import java.util.List; |
import java.util.ArrayList; |
|
import org.apache.commons.logging.Log; |
import org.apache.commons.logging.LogFactory; |
|
12,182 → 9,15 |
|
public class HttpBench |
{ |
private static Log log = LogFactory.getLog(HttpBench.class); |
|
public static void main(String[] args) |
throws Exception |
{ |
HttpBench hb = new HttpBench(); |
|
if(hb.parseParams(args)) |
hb.run(); |
(new HttpThread(null, new String[] { "http://sun/" } )).run(); |
} |
|
// config |
private int threadNumber = 10; |
private int requestNumber = 50; |
private int requestPerConnection = 0; |
private int sleepMin = 0; |
private int sleepMax = 1000; // 1s |
private int timeout = 60000; // 1min |
private String firstUrl = null; |
private List urls = new ArrayList(); |
|
private int parseInt(String s, String prefix, String errorMsg) |
throws Exception |
{ |
try { |
return Integer.parseInt(s.substring(prefix.length())); |
} |
catch(Exception ex) { |
log.error(errorMsg); |
throw ex; |
} |
} |
|
private boolean parseParams(String[] args) |
throws Exception |
{ |
try { |
for(int i = 0; i< args.length; i++) { |
String s = args[i]; |
if(s.startsWith("thr=")) { |
threadNumber = parseInt(s, "thr=", |
"Cannot get number of threads from " + s); |
} |
else if(s.startsWith("req=")) { |
requestNumber = parseInt(s, "req=", |
"Cannot get number of requests from " + s); |
} |
else if(s.startsWith("rpc=")) { |
requestPerConnection = parseInt(s, "rpc=", |
"Cannot get number of requests per connection from " + s); |
} |
else if(s.startsWith("sleepMin=")) { |
sleepMin = parseInt(s, "sleepMin=", |
"Cannot get min sleep from " + s); |
} |
else if(s.startsWith("timeout=")) { |
timeout = parseInt(s, "timeout=", |
"Cannot get timeout from " + s); |
} |
else if(s.startsWith("sleepMax=")) { |
sleepMax = parseInt(s, "sleepMax=", |
"Cannot get max sleep from " + s); |
} |
else if(s.startsWith("firstUrl=")) { |
firstUrl = s.substring("firstUrl=".length()); |
if(firstUrl.equals("")) firstUrl = null; |
} |
else { |
urls.add(s); |
} |
} |
|
if(urls.isEmpty()) { |
log.error("Need at least one URL to work"); |
return false; |
} |
|
return true; |
} |
catch(Exception ex) { |
return false; |
} |
} |
|
private void run() |
throws Exception |
{ |
log.info("start " + threadNumber + "/" + requestNumber + "/" + requestPerConnection |
+ " " + sleepMin + "/" + sleepMax); |
log.info(" firstUrl: " + (firstUrl == null ? "<null>" : firstUrl)); |
for(int i = 0; i < urls.size(); i++) |
log.info(" url: " + urls.get(i)); |
|
List threads = new ArrayList(); |
List workers = new ArrayList(); |
String[] urlArray = (String[])urls.toArray(new String[] {}); |
|
for(int i = 0; i < threadNumber; i++) { |
log.debug("create thread " + i); |
|
HttpThread ht = new HttpThread(firstUrl, urlArray); |
workers.add(ht); |
ht.setRequestNumber(requestNumber); |
ht.setRequestPerConnection(requestPerConnection); |
ht.setSleepMin(sleepMin); |
ht.setSleepMax(sleepMax); |
ht.setTimeout(timeout); |
|
Thread t = new Thread(ht); |
threads.add(t); |
t.start(); |
} |
|
// wait for all |
for(int i = 0; i < threads.size(); i++) { |
log.debug("wait for thread " + i); |
|
Thread t = (Thread)threads.get(i); |
try { |
t.join(); |
} |
catch(InterruptedException ex) { |
} |
} |
|
// statistics |
long totalTime = 0; |
long reqTime = 0; |
long minTime = Long.MAX_VALUE; |
long maxTime = -1; |
int successRequest = 0; |
int failRequest = 0; |
for(int i = 0; i < workers.size(); i++) { |
HttpThread ht = (HttpThread)workers.get(i); |
if(ht.getSuccess()) { |
totalTime += ht.getRunTime(); |
|
List results = ht.getResults(); |
for(int j = 0; j < results.size(); j++) { |
RequestResult r = (RequestResult)results.get(j); |
totalTime -= r.sleepBefore; |
if(r.success) { |
successRequest++; |
|
long t = r.stopTime - r.startTime; |
reqTime += t; |
if(minTime > t) minTime = t; |
if(maxTime < t) maxTime = t; |
} |
else { |
failRequest++; |
} |
} |
} |
} |
|
log.info("done " + totalTime + "ms / " + successRequest + " = " |
+ (totalTime / successRequest) + "ms " |
+ minTime + "/" + (reqTime / successRequest) + "/" + maxTime |
+ " ms, " + failRequest + " failed"); |
} |
} |
|
class RequestResult |
class HttpThread |
{ |
public boolean success = false; |
public String url; |
public long sleepBefore; |
public long startTime; |
public long stopTime; |
public int code; |
public Exception exception; |
} |
|
class HttpThread implements Runnable |
{ |
private static int threadCount = 0; |
private static Log log = LogFactory.getLog(HttpThread.class); |
|
198,12 → 28,7 |
private int requestPerConnection = 0; // 0 == all |
private int sleepMin = 0; |
private int sleepMax = 0; |
private int timeout = 0; |
|
private boolean success; |
private long runTime; |
private List results; |
|
public HttpThread(String firstUrl, String[] urls) |
{ |
id = threadCount++; |
236,6 → 61,11 |
this.requestPerConnection = requestPerConnection; |
} |
|
public int getSleepMin() |
{ |
return sleepMin; |
} |
|
public void setSleepMin(int sleepMin) |
{ |
this.sleepMin = sleepMin; |
251,85 → 81,38 |
this.sleepMax = sleepMax; |
} |
|
public int getTimeout() |
public void run() |
{ |
return timeout; |
} |
long startTime = 0; |
long stopTime = 0; |
long sumSleep = 0; |
|
public void setTimeout(int timeout) |
{ |
this.timeout = timeout; |
} |
|
public boolean getSuccess() |
{ |
return success; |
} |
|
public long getRunTime() |
{ |
return runTime; |
} |
|
public List getResults() |
{ |
return results; |
} |
|
public void run() |
{ |
long sumSleep = 0; |
log.info(Integer.toString(id) + ": start"); |
|
try { |
HttpClient client = new HttpClient(); |
|
results = new ArrayList(); |
startTime = System.currentTimeMillis(); |
for(int i = 0; i < requestNumber; i++) { |
results.add(new RequestResult()); |
} |
|
long startTime = System.currentTimeMillis(); |
for(int i = 0; i < requestNumber; i++) { |
RequestResult result = (RequestResult)results.get(i); |
|
if(sleepMax > 0) { |
long sleep = (long)(Math.random() * (sleepMax - sleepMin)) + sleepMin; |
sumSleep += sleep; |
result.sleepBefore = sleep; |
log.trace(Integer.toString(id) + ": sleep for " + sleep + "ms"); |
Thread.sleep(sleep); |
} |
|
String url; |
if(i == 0 && firstUrl != null) |
result.url = firstUrl; |
url = firstUrl; |
else |
result.url = urls[(firstUrl == null ? i : i-1) % urls.length]; |
url = urls[(firstUrl == null ? i : i-1) % urls.length]; |
|
GetMethod get = new GetMethod(result.url); |
get.getParams().setSoTimeout(timeout); |
GetMethod get = new GetMethod(url); |
|
try { |
result.startTime = System.currentTimeMillis(); |
result.code = client.executeMethod(get); |
result.stopTime = System.currentTimeMillis(); |
result.success = true; |
|
int result = client.executeMethod(get); |
if(log.isTraceEnabled()) { |
String response = get.getResponseBodyAsString(); |
log.trace(Integer.toString(id) + ": got " + result |
+ " in " + (result.stopTime - result.startTime) |
+ "ms \n'" + response.substring(0, 100) + "'"); |
log.trace(Integer.toString(id) + ": got " + result + "\n'" |
+ response.substring(0, 100) + "'"); |
} |
else if(log.isDebugEnabled()) { |
log.debug(Integer.toString(id) + ": got " + result |
+ " in " + (result.stopTime - result.startTime) + "ms"); |
log.debug(Integer.toString(id) + ": got " + result); |
} |
} |
catch(Exception ex) { |
result.stopTime = System.currentTimeMillis(); |
result.exception = ex; |
} |
finally { |
get.releaseConnection(); |
} |
341,19 → 124,24 |
+ ": request per connection limit reached at " + i); |
client.getHttpConnectionManager().closeIdleConnections(0); |
} |
|
if(sleepMax > 0 && i < requestNumber-1) { |
long sleep = (long)(Math.random() * (sleepMax - sleepMin)) + sleepMin; |
log.debug(Integer.toString(id) + ": sleep for " + sleep + "ms"); |
Thread.currentThread().sleep(sleep); |
sumSleep += sleep; |
} |
} |
|
client.getHttpConnectionManager().closeIdleConnections(0); |
success = true; |
runTime = System.currentTimeMillis() - startTime; |
stopTime = System.currentTimeMillis(); |
} |
catch(Exception ex) { |
success = false; |
log.warn(Integer.toString(id), ex); |
} |
|
log.info(Integer.toString(id) + ": done" + (success ? " " + runTime |
+ "/" + sumSleep + "/" + (runTime - sumSleep) + " ms": " with error")); |
log.info(Integer.toString(id) + ": done" + (stopTime > 0 ? " in " + (stopTime - startTime) |
+ "ms, sleeped for " + sumSleep + " ms" : "")); |
} |
} |
|