Skip to content

Instantly share code, notes, and snippets.

@aviflax
Created January 20, 2011 19:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aviflax/788468 to your computer and use it in GitHub Desktop.
Save aviflax/788468 to your computer and use it in GitHub Desktop.
Benchmarking HTTP client performance using Apache HttpClient 3.1 and 4.0 with and without Restlet 1.1 and 2.0. The server is a constant value (always warmed up) and I tried to make the scripts as identical as possible.
#!/usr/bin/env groovy -cp restlet-1.1.10/httpclient/*
/*** SETTINGS ***/
requestsToSend = args.length >= 1 ? args[0] as Integer : 10000
concurrency = args.length >= 2 ? args[1] as Integer : 10
port = args.length >= 3 ? args[2] as Integer : 3000
/*** /SETTINGS ***/
import java.util.concurrent.atomic.AtomicInteger
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.PostMethod
requestsPerThread = (requestsToSend / concurrency) as Integer
println "Sending $requestsToSend requests across $concurrency threads"
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager())
httpClient.httpConnectionManager.params.defaultMaxConnectionsPerHost = 50
httpClient.httpConnectionManager.params.maxTotalConnections = 50
requestURL = "http://localhost:$port/"
formParams = []
formParams << new NameValuePair('foo', 'bar')
20.times { formParams << new NameValuePair('foo.' + it, 'bar'.multiply(it * 2)) }
entity = formParams as NameValuePair[]
requestCounter = new AtomicInteger(0)
threads = []
concurrency.times {
threads << Thread.start {
def request = new PostMethod(requestURL)
request.requestBody = entity
requestsPerThread.times {
httpClient.executeMethod request
if (request.getStatusCode() != 202) {
println "\n\nThread aborting due to status: $response.statusLine\n\n"
Thread.currentThread().interrupt()
}
request.releaseConnection()
int counterValue = requestCounter.incrementAndGet()
if (counterValue % 1000 == 0) {
print counterValue
print ' requests sent and handled\r'
}
}
}
}
threads.each { it.join() }
println "$requestCounter requests sent and handled"
System.exit(0)
#!/usr/bin/env groovy -cp restlet-2.0.4/restlet/*:restlet-2.0.4/httpclient/*
/*** SETTINGS ***/
requestsToSend = args.length >= 1 ? args[0] as Integer : 10000
concurrency = args.length >= 2 ? args[1] as Integer : 10
port = args.length >= 3 ? args[2] as Integer : 3000
/*** /SETTINGS ***/
requestsPerThread = (requestsToSend / concurrency) as Integer
println "Sending $requestsToSend requests across $concurrency threads"
import javax.net.ssl.SSLContext
import java.util.concurrent.atomic.*
import org.apache.http.*
import org.apache.http.client.*
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.client.methods.HttpPost
import org.apache.http.client.params.*
import org.apache.http.conn.ClientConnectionManager
import org.apache.http.conn.params.*
import org.apache.http.conn.scheme.*
import org.apache.http.conn.ssl.SSLSocketFactory
import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
import org.apache.http.message.BasicNameValuePair
import org.apache.http.params.*
import org.restlet.engine.security.DefaultSslContextFactory
import org.restlet.engine.security.SslContextFactory
params = new BasicHttpParams()
configure(params)
schemeRegistry = new SchemeRegistry()
configure(schemeRegistry)
connManager = new ThreadSafeClientConnManager(params, schemeRegistry)
httpClient = new DefaultHttpClient(connManager, params)
requestURL = "http://localhost:$port/"
formparams = []
formparams << new BasicNameValuePair('foo', 'bar')
20.times { formparams << new BasicNameValuePair('foo.' + it, 'bar'.multiply(it * 2)) }
entity = new UrlEncodedFormEntity(formparams, "UTF-8")
requestCounter = new AtomicInteger(0)
threads = []
concurrency.times {
threads << Thread.start {
def request = new HttpPost(requestURL)
request.entity = entity
requestsPerThread.times {
HttpResponse response = httpClient.execute(request)
if (response.getStatusLine().getStatusCode() != 202) {
println "\n\nThread aborting due to status: $response.statusLine\n\n"
Thread.currentThread().interrupt()
}
response.getEntity().consumeContent()
int counterValue = requestCounter.incrementAndGet()
if (counterValue % 1000 == 0) {
print counterValue
print ' requests sent and handled\r'
}
}
}
}
threads.each { it.join() }
println "$requestCounter requests sent and handled"
System.exit(0)
/*** TAKEN FROM org.restlet.ext.httpclient.HttpClientHelper ***/
def void configure(HttpParams params) {
ConnManagerParams.setMaxTotalConnections(params, 50)
ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(50))
// Configure other parameters
HttpClientParams.setAuthenticating(params, false)
HttpClientParams.setRedirecting(params, false)
HttpClientParams.setCookiePolicy(params, CookiePolicy.BROWSER_COMPATIBILITY)
HttpConnectionParams.setTcpNoDelay(params, false)
HttpConnectionParams.setConnectionTimeout(params, 0)
HttpConnectionParams.setSoTimeout(params, 0)
}
/**
* Configures the scheme registry. By default, it registers the HTTP and the
* HTTPS schemes.
*
* @param schemeRegistry
* The scheme registry to configure.
*/
def void configure(SchemeRegistry schemeRegistry) {
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80))
SSLSocketFactory sslSocketFactory = null
SslContextFactory sslContextFactory = new DefaultSslContextFactory()
if (sslContextFactory != null) {
try {
SSLContext sslContext = sslContextFactory.createSslContext()
sslSocketFactory = new SSLSocketFactory(sslContext)
} catch (Exception e) {
throw new RuntimeException("Unable to create SSLContext.", e)
}
} else {
sslSocketFactory = SSLSocketFactory.getSocketFactory()
}
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443))
}
/*** SETTINGS ***/
requestsToSend = args.length >= 1 ? args[0] as Integer : 10000
concurrency = args.length >= 2 ? args[1] as Integer : 10
port = args.length >= 3 ? args[2] as Integer : 3000
/*** /SETTINGS ***/
requestsPerThread = (requestsToSend / concurrency) as Integer
import java.util.concurrent.atomic.*
import org.restlet.*
import org.restlet.data.*
import org.restlet.representation.*
import org.restlet.resource.*
ref = new Reference("http://localhost:$port/")
def client = new Client(new Context(), Protocol.HTTP)
client.context.parameters.add 'maxConnectionsPerHost', (concurrency * 2) as String
client.context.parameters.add 'maxTotalConnections', (concurrency * 2) as String
// need to pre-start the client because was otherwise having concurrency issues
client.start()
form = new Form()
form.add 'foo', 'bar'
20.times { form.add 'foo.' + it, 'bar'.multiply(it * 2) }
formText = form.webRepresentation.text
requestCounter = new AtomicInteger(0)
threads = []
concurrency.times {
threads << Thread.start {
def request = new Request(Method.POST, ref, new StringRepresentation(formText, MediaType.APPLICATION_WWW_FORM))
requestsPerThread.times {
Response response = client.handle(request)
if (response.getStatus().getCode() != 202) {
println "\n\nThread aborting due to status: ${response.status}\n\n"
Thread.currentThread().interrupt()
}
int counterValue = requestCounter.incrementAndGet()
if (counterValue % 1000 == 0) {
print counterValue
print ' requests sent and handled\r'
}
}
}
}
threads.each { it.join() }
println "$requestCounter requests sent and handled"
System.exit(0)
#!/usr/bin/env java -cp groovy-all-1.7.5.jar:restlet-2.0.4/restlet/*:restlet-2.0.4/jetty/* groovy.lang.GroovyShell
/*** SETTINGS ***/
port = args.length >= 1 ? args[0] as Integer : 3000
/*** /SETTINGS ***/
import java.util.concurrent.atomic.*
import org.restlet.*
import org.restlet.data.*
import org.restlet.representation.*
import org.restlet.resource.*
class RequestHandler extends Restlet {
static requestCounter = new AtomicInteger(0)
void handle(Request request, Response response) {
response.setStatus(Status.SUCCESS_ACCEPTED)
int counterValue = requestCounter.incrementAndGet()
if (counterValue % 1000 == 0) {
print counterValue
print ' requests handled\r'
}
}
}
new Server(Protocol.HTTP, port, new RequestHandler()).start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment