Subversion Repositories general

Rev

Rev 1127 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1127 dev 1
package ak.httpbench;
2
 
1128 dev 3
import java.util.List;
4
import java.util.ArrayList;
5
 
1127 dev 6
import org.apache.commons.logging.Log;
7
import org.apache.commons.logging.LogFactory;
8
 
9
import org.apache.commons.httpclient.HttpClient;
10
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
11
import org.apache.commons.httpclient.methods.GetMethod;
12
 
13
public class HttpBench
14
{
1128 dev 15
	private static Log log = LogFactory.getLog(HttpBench.class);
16
 
1127 dev 17
	public static void main(String[] args)
18
		throws Exception
19
	{
1128 dev 20
		HttpBench hb = new HttpBench();
21
 
22
		if(hb.parseParams(args))
23
			hb.run();
1127 dev 24
	}
1128 dev 25
 
26
	// config
27
	private int    threadNumber         = 10;
28
	private int    requestNumber        = 50;
29
	private int    requestPerConnection = 0;
30
	private int    sleepMin             = 0;
31
	private int    sleepMax             = 1000; // 1s
32
	private int    timeout              = 60000; // 1min
33
	private String firstUrl             = null;
34
	private List   urls                 = new ArrayList();
35
 
36
	private int parseInt(String s, String prefix, String errorMsg)
37
		throws Exception
38
	{
39
		try {
40
			return Integer.parseInt(s.substring(prefix.length()));
41
		}
42
		catch(Exception ex) {
43
			log.error(errorMsg);
44
			throw ex;
45
		}
46
	}
47
 
48
	private boolean parseParams(String[] args)
49
		throws Exception
50
	{
51
		try {
52
			for(int i = 0; i< args.length; i++) {
53
				String s = args[i];
54
				if(s.startsWith("thr=")) {
55
					threadNumber = parseInt(s, "thr=",
56
						"Cannot get number of threads from " + s);
57
				}
58
				else if(s.startsWith("req=")) {
59
					requestNumber = parseInt(s, "req=",
60
						"Cannot get number of requests from " + s);
61
				}
62
				else if(s.startsWith("rpc=")) {
63
					requestPerConnection = parseInt(s, "rpc=",
64
						"Cannot get number of requests per connection from " + s);
65
				}
66
				else if(s.startsWith("sleepMin=")) {
67
					sleepMin = parseInt(s, "sleepMin=",
68
						"Cannot get min sleep from " + s);
69
				}
70
				else if(s.startsWith("timeout=")) {
71
					timeout = parseInt(s, "timeout=",
72
						"Cannot get timeout from " + s);
73
				}
74
				else if(s.startsWith("sleepMax=")) {
75
					sleepMax = parseInt(s, "sleepMax=",
76
						"Cannot get max sleep from " + s);
77
				}
78
				else if(s.startsWith("firstUrl=")) {
79
					firstUrl = s.substring("firstUrl=".length());
80
					if(firstUrl.equals("")) firstUrl = null;
81
				}
82
				else {
83
					urls.add(s);
84
				}
85
			}
86
 
87
			if(urls.isEmpty()) {
88
				log.error("Need at least one URL to work");
89
				return false;
90
			}
91
 
92
			return true;
93
		}
94
		catch(Exception ex) {
95
			return false;
96
		}
97
	}
98
 
99
	private void run()
100
		throws Exception
101
	{
102
		log.info("start " + threadNumber + "/" + requestNumber + "/" + requestPerConnection
103
			+ " " + sleepMin + "/" + sleepMax);
104
		log.info("  firstUrl: " + (firstUrl == null ? "<null>" : firstUrl));
105
		for(int i = 0; i < urls.size(); i++)
106
			log.info("  url: " + urls.get(i));
107
 
108
		List     threads  = new ArrayList();
109
		List     workers  = new ArrayList();
110
		String[] urlArray = (String[])urls.toArray(new String[] {});
111
 
112
		for(int i = 0; i < threadNumber; i++) {
113
			log.debug("create thread " + i);
114
 
115
			HttpThread ht = new HttpThread(firstUrl, urlArray);
116
			workers.add(ht);
117
			ht.setRequestNumber(requestNumber);
118
			ht.setRequestPerConnection(requestPerConnection);
119
			ht.setSleepMin(sleepMin);
120
			ht.setSleepMax(sleepMax);
121
			ht.setTimeout(timeout);
122
 
123
			Thread t = new Thread(ht);
124
			threads.add(t);
125
			t.start();
126
		}
127
 
128
		// wait for all
129
		for(int i = 0; i < threads.size(); i++) {
130
			log.debug("wait for thread " + i);
131
 
132
			Thread t = (Thread)threads.get(i);
133
			try {
134
				t.join();
135
			}
136
			catch(InterruptedException ex) {
137
			}
138
		}
139
 
140
		// statistics
141
		long totalTime      = 0;
142
		long reqTime        = 0;
143
		long minTime        = Long.MAX_VALUE;
144
		long maxTime        = -1;
145
		int  successRequest = 0;
146
		int  failRequest    = 0;
147
		for(int i = 0; i < workers.size(); i++) {
148
			HttpThread ht = (HttpThread)workers.get(i);
149
			if(ht.getSuccess()) {
150
				totalTime += ht.getRunTime();
151
 
152
				List results = ht.getResults();
153
				for(int j = 0; j < results.size(); j++) {
154
					RequestResult r = (RequestResult)results.get(j);
155
					totalTime -= r.sleepBefore;
156
					if(r.success) {
157
						successRequest++;
158
 
159
						long t = r.stopTime - r.startTime;
160
						reqTime += t;
161
						if(minTime > t) minTime = t;
162
						if(maxTime < t) maxTime = t;
163
					}
164
					else {
165
						failRequest++;
166
					}
167
				}
168
			}
169
		}
170
 
171
		log.info("done " + totalTime + "ms / " + successRequest + " = "
172
			+ (totalTime / successRequest) + "ms "
173
			+ minTime + "/" + (reqTime / successRequest) + "/" + maxTime
174
			+ " ms, " + failRequest + " failed");
175
	}
1127 dev 176
}
177
 
1128 dev 178
class RequestResult
1127 dev 179
{
1128 dev 180
	public boolean   success = false;
181
	public String    url;
182
	public long      sleepBefore;
183
	public long      startTime;
184
	public long      stopTime;
185
	public int       code;
186
	public Exception exception;
187
}
188
 
189
class HttpThread implements Runnable
190
{
1127 dev 191
	private static int threadCount = 0;
192
	private static Log log         = LogFactory.getLog(HttpThread.class);
193
 
194
	private int      id;
195
	private String   firstUrl; // is used one time only, may be null
196
	private String[] urls;
197
	private int      requestNumber = 1;
198
	private int      requestPerConnection = 0; // 0 == all
199
	private int      sleepMin = 0;
200
	private int      sleepMax = 0;
1128 dev 201
	private int      timeout  = 0;
1127 dev 202
 
1128 dev 203
	private boolean  success;
204
	private long     runTime;
205
	private List     results;
206
 
1127 dev 207
	public HttpThread(String firstUrl, String[] urls)
208
	{
209
		id = threadCount++;
210
		this.firstUrl = firstUrl;
211
		this.urls     = urls;
212
	}
213
 
214
	public int getId()
215
	{
216
		return id;
217
	}
218
 
219
	public int getRequestNumber()
220
	{
221
		return requestNumber;
222
	}
223
 
224
	public void setRequestNumber(int requestNumber)
225
	{
226
		this.requestNumber = requestNumber;
227
	}
228
 
229
	public int getRequestPerConnection()
230
	{
231
		return requestPerConnection;
232
	}
233
 
234
	public void setRequestPerConnection(int requestPerConnection)
235
	{
236
		this.requestPerConnection = requestPerConnection;
237
	}
238
 
239
	public void setSleepMin(int sleepMin)
240
	{
241
		this.sleepMin = sleepMin;
242
	}
243
 
244
	public int getSleepMax()
245
	{
246
		return sleepMax;
247
	}
248
 
249
	public void setSleepMax(int sleepMax)
250
	{
251
		this.sleepMax = sleepMax;
252
	}
253
 
1128 dev 254
	public int getTimeout()
255
	{
256
		return timeout;
257
	}
258
 
259
	public void setTimeout(int timeout)
260
	{
261
		this.timeout = timeout;
262
	}
263
 
264
	public boolean getSuccess()
265
	{
266
		return success;
267
	}
268
 
269
	public long getRunTime()
270
	{
271
		return runTime;
272
	}
273
 
274
	public List getResults()
275
	{
276
		return results;
277
	}
278
 
1127 dev 279
	public void run()
280
	{
1128 dev 281
		long sumSleep = 0;
1127 dev 282
		log.info(Integer.toString(id) + ": start");
283
 
284
		try {
285
			HttpClient client = new HttpClient();
286
 
1128 dev 287
			results = new ArrayList();
1127 dev 288
			for(int i = 0; i < requestNumber; i++) {
1128 dev 289
				results.add(new RequestResult());
290
			}
291
 
292
			long startTime = System.currentTimeMillis();
293
			for(int i = 0; i < requestNumber; i++) {
294
				RequestResult result = (RequestResult)results.get(i);
295
 
296
				if(sleepMax > 0) {
297
					long sleep = (long)(Math.random() * (sleepMax - sleepMin)) + sleepMin;
298
					sumSleep += sleep;
299
					result.sleepBefore = sleep;
300
					log.trace(Integer.toString(id) + ": sleep for " + sleep + "ms");
301
					Thread.sleep(sleep);
302
				}
303
 
1127 dev 304
				if(i == 0 && firstUrl != null)
1128 dev 305
					result.url = firstUrl;
1127 dev 306
				else
1128 dev 307
					result.url = urls[(firstUrl == null ? i : i-1) % urls.length];
1127 dev 308
 
1128 dev 309
				GetMethod get = new GetMethod(result.url);
310
				get.getParams().setSoTimeout(timeout);
1127 dev 311
 
312
				try {
1128 dev 313
					result.startTime = System.currentTimeMillis();
314
					result.code      = client.executeMethod(get);
315
					result.stopTime  = System.currentTimeMillis();
316
					result.success   = true;
317
 
1127 dev 318
					if(log.isTraceEnabled()) {
319
						String response = get.getResponseBodyAsString();
1128 dev 320
						log.trace(Integer.toString(id) + ": got " + result
321
							+ " in " + (result.stopTime - result.startTime)
322
							+ "ms \n'" + response.substring(0, 100) + "'");
1127 dev 323
					}
324
					else if(log.isDebugEnabled()) {
1128 dev 325
						log.debug(Integer.toString(id) + ": got " + result
326
							+ " in " + (result.stopTime - result.startTime) + "ms");
1127 dev 327
					}
328
				}
1128 dev 329
				catch(Exception ex) {
330
					result.stopTime  = System.currentTimeMillis();
331
					result.exception = ex;
332
				}
1127 dev 333
				finally {
334
					get.releaseConnection();
335
				}
336
 
337
				if(requestPerConnection > 0 && (i+1) % requestPerConnection == 0
338
					&& i < requestNumber-1)
339
				{
340
					log.debug(Integer.toString(id)
341
						+ ": request per connection limit reached at " + i);
342
					client.getHttpConnectionManager().closeIdleConnections(0);
343
				}
344
			}
345
 
346
			client.getHttpConnectionManager().closeIdleConnections(0);
1128 dev 347
			success = true;
348
			runTime = System.currentTimeMillis() - startTime;
1127 dev 349
		}
350
		catch(Exception ex) {
1128 dev 351
			success = false;
1127 dev 352
			log.warn(Integer.toString(id), ex);
353
		}
354
 
1128 dev 355
		log.info(Integer.toString(id) + ": done" + (success ? " " + runTime
356
			+ "/" + sumSleep + "/" + (runTime - sumSleep) + " ms": " with error"));
1127 dev 357
	}
358
}
359