最近项目中需要在微服务中调用rest接口,而且需要调用得次数很多,所以同步得http客户端已经不满足要求,在网上查阅资料后发现了async-http-client这个包得性能不错,所以写了个demo测试性能。
由于在线得网站一般都会限制流量,也有反爬虫,所以为了排除服务端得影响,自己搭建一个简单http服务。代码如下:
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; public class HttpServer1 { private static int index = 0; public static void main(String[] args) { HttpServer server = null; try { server = HttpServer.create(new InetSocketAddress(8001), 0); } catch (IOException e) { e.printStackTrace(); } assert server != null; server.createContext("/test", new TestHandler()); server.start(); } static class TestHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { index += 1; System.out.println(index); String response = "hello world"; exchange.sendResponseHeaders(200, 0); OutputStream os = exchange.getResponseBody(); os.write(response.getBytes()); os.close(); } } }
这是一个简单得http服务,不会拒绝连接,也不会进行限流。我之前遇到问题就是因为没有在自建得服务上进行测试,而是在其他的微服务上进行测试,而由于微服务往往存在流量限制,所以导致测试得性能不好,我还一直以为是客户端得问题,md。
现在看看客户端代码:
import io.netty.channel.nio.NioEventLoopGroup; import org.asynchttpclient.*; import java.io.IOException; import java.util.Date; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; public class AsyncHttp { public static void main(String[] args) { DefaultAsyncHttpClientConfig.Builder clientBuilder = Dsl.config() .setConnectTimeout(5000) .setRequestTimeout(30000); AsyncHttpClient client = Dsl.asyncHttpClient(clientBuilder); NioEventLoopGroup p = new NioEventLoopGroup(8); System.out.println(new Date().toString()); for (int i = 0; i < 10000; i++) { BoundRequestBuilder getRequest = client.prepareGet("http://localhost:8001/test"); final ListenableFuture<Response> responseFuture = getRequest.execute(); final int index = i; Runnable callback = () -> { try { Response response = responseFuture.get(); // System.out.println(response); System.out.println(index); System.out.println(new Date().toString()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } }; responseFuture.addListener(callback, p); } // try { // client.close(); // } catch (IOException e) { // e.printStackTrace(); // } } }
很简单地使用asynchttpclient包进行异步的http请求,这里循环异步发送1w条请求,打印时间一共只用了5秒钟,相当于2000条/s,这个效率相比同步http已经高了两个数量级。
这里是我封装的http批量异步请求管理器:
https://github.com/Yves-yuan/batch-async-http-request
欢迎start fork 之类的。