HttpClient性能对比

通过并发测试比较了Apache HttpClient与AsyncHttpClient的性能表现,结果显示两者在30线程并发请求下性能差异不大。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中用到HttpClient比较多,公司使用的框架是Apache HttpClient,它是用BIO实现的,我想使用了NIO的Netty效率会不会好些。

在网上没有查到这两个性能对比,自己写了例子测试的。

Netty的原生HttpClient需要自己写连接池管理,我使用的是AsyncHttpClient


测试的基类,30个线程并发发起请求,每个线程连续请求200次:

package com.weishubin.test.httpclient;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class AbstractHttpClientTester {
	public static final int THREAD_COUNT = 30;//并行线程数量
	
	public static final int TIMES = 200;//一个线程内执行的次数
	
	public long mainStart;
	
	public long[][] RECORD = new long[THREAD_COUNT][TIMES];//记录耗时
	
	public AtomicInteger counter;

	public ExecutorService executor = Executors.newCachedThreadPool();
	
	public void run() {
		createHttpClient();
		
		counter = new AtomicInteger(0);
		mainStart = System.currentTimeMillis();
		
		for (int i = 0; i < THREAD_COUNT; i++) {
			executor.submit(new Http(i));;
		}
	}
	
	protected  abstract void createHttpClient();
	
	protected abstract String request() throws Exception;
	
	protected void close() {
		executor.shutdown();
	}
	
	public class Http extends Thread {
		int index;
		Http(int i) {
			this.index = i;
		}
		public void run() {
			test();
			
			int r = counter.incrementAndGet();
			
			if (r == THREAD_COUNT) {
				printResult();
				
				close();
			}
		}
		
		private void test() {
			for (int i = 0; i < TIMES; i++) {
				long start = System.currentTimeMillis();
				try {
					
					String data = request();
					
					//System.out.println(data);
					RECORD[index][i] = System.currentTimeMillis() - start;
				} catch (Exception e) {
					e.printStackTrace();
					RECORD[index][i] = 0;
				}
			}
		}
		
		private void printResult() {
			long sum = 0;
			long count = 0;
			for (int i = 0; i < THREAD_COUNT; i++) {
				for (int j = 0; j < TIMES; j++) {
					if (RECORD[i][j] > 0) {
						sum += RECORD[i][j];
						count++;
					}
					
				}
			}
			
			System.out.println("TOTAL COST:" + (System.currentTimeMillis() - mainStart));
			System.out.println("TIMES:" + TIMES);
			System.out.println("SUCCESS COUNT:" + count);
			System.out.println("AVG COST:" + sum / count);
		}
	}
}


Apache HttpClient测试类:

package com.weishubin.test.httpclient;


import java.io.IOException;

import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.params.SyncBasicHttpParams;

public class ApacheHttpClientTester extends AbstractHttpClientTester {
	
	public HttpClient httpClient;
	public BasicResponseHandler handler;
	
	public static void main(String[] args) {
		new ApacheHttpClientTester().run();
	}
	
	@Override
	protected void createHttpClient() {
		PoolingClientConnectionManager cm = new PoolingClientConnectionManager();
		cm.setMaxTotal(40);
		cm.setDefaultMaxPerRoute(40);
		
		HttpParams param = new SyncBasicHttpParams();
		HttpProtocolParams.setVersion(param, HttpVersion.HTTP_1_1);
		HttpConnectionParams.setTcpNoDelay(param, true);
		HttpConnectionParams.setConnectionTimeout(param, 30000);
		HttpConnectionParams.setSoTimeout(param, 30000);
		
		httpClient = new DefaultHttpClient(cm);
		httpClient.getParams().setParameter(ClientPNames.DEFAULT_HOST, new HttpHost("192.168.1.105", 8090));
		
		handler = new BasicResponseHandler();
	}

	@Override
	protected String request() throws ClientProtocolException, IOException {
		HttpGet request = new HttpGet("/httpclient/get.json");
		String r = httpClient.execute(request, handler);
		//System.out.println(r);
		return r;
	}
}


AsyncHttpClent测试类:
package com.weishubin.test.httpclient;

import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncHttpClientConfig;
import com.ning.http.client.ListenableFuture;
import com.ning.http.client.providers.netty.response.NettyResponse;

public class AsyncHttpClientTester extends AbstractHttpClientTester {
	
	public static void main(String[] args) {
		new AsyncHttpClientTester().run();
	}
	
	private AsyncHttpClient httpClient;
	@Override
	protected void createHttpClient() {
		AsyncHttpClientConfig.Builder cf = new AsyncHttpClientConfig.Builder();
		cf.setConnectTimeout(3000);
		cf.setConnectionTTL(3000);
		cf.setPooledConnectionIdleTimeout(3000);
		cf.setReadTimeout(3000);
		
		
		AsyncHttpClientConfig config = cf.build();
		
		httpClient = new AsyncHttpClient(config);
	}

	@Override
	protected String request() throws Exception {
		String url = "http://192.168.1.105:8090/httpclient/get.json";
		ListenableFuture data =  httpClient
				.prepareGet(url).execute();
		NettyResponse s = (NettyResponse) data.get();
		return s.getResponseBody();
	}
	
	@Override
	protected void close() {
		super.close();
		httpClient.closeAsynchronously();
	}

}


服务是我自己写的一个Netty服务,简单的返回一个Json字符串。

多次测试发现两个性能没有明显差别。

又考虑到我们的并发量远没有达到30个,AsyncHttpClient也没有Apache实现得成熟,没有使用,继续使用了Apahce。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值