java非阻塞HTTP客户端

for*_*has 9 java asynchronous http-post nonblocking

我有一个高容量的Java应用程序,我必须将http帖子发送到另一台服务器.目前我正在使用org.apache.commons.httpclient库:

private static void sendData(String data) {
HttpClient httpclient = new HttpClient();
StringRequestEntity requestEntity;
try {
    requestEntity = new StringRequestEntity(data, "application/json", "UTF-8");
    String address = "http://<my host>/events/"
    PostMethod postMethod = new PostMethod(address);
    postMethod.setRequestEntity(requestEntity);

    httpclient.executeMethod(postMethod);

} catch (Exception e) {
    LOG.error("Failed to send data ", e);

}
}
Run Code Online (Sandbox Code Playgroud)

这意味着我正在同步发送我的http请求,这不适合我的多线程高容量应用程序.所以我想将这些调用更改为异步非阻塞http调用.

我经历了一些选项,如apache异步客户端xsocket,但无法使其工作.

试图:

private static void sendEventToGrpahiteAsync(String event) {
LOG.info("\n" + "sendEventToGrpahiteAsync");
try (AsyncHttpClient asyncHttpClient = new AsyncHttpClient()) {
    BoundRequestBuilder post = asyncHttpClient.preparePost();
    post.addHeader("Content-Type", "application/json");
    post.setBodyEncoding("UTF-8");
    post.setBody(event);
    post.execute(new HttpRequestCompletionHandler());
} catch (Exception e) {
    LOG.error("Failed to sending event", e);
}
}
Run Code Online (Sandbox Code Playgroud)

我试过Apache HttpAsyncClient:

private static void sendEventToGrpahiteAsync(String event) {
LOG.info("\n" + "sendEventToGrpahiteAsync");
try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) {
    httpclient.start();
    HttpPost request = new HttpPost(addr);
    StringEntity entity = new StringEntity(event, ContentType.create("application/json", Consts.UTF_8));
    request.setEntity(entity);
    httpclient.execute(request, null);
} catch (Exception e) {
    LOG.error("Failed to sending event", e);
}
}
Run Code Online (Sandbox Code Playgroud)

我试过xsocket:

private static void sendEventToGrpahiteAsync2(String event) {
LOG.info("\n" + "sendEventToGrpahiteAsync");
try (INonBlockingConnection con = new NonBlockingConnection(<SERVER_IP>, 80);
    IHttpClientEndpoint httpClientConnection = new HttpClientConnection(con)) {
    IHttpResponseHandler responseHandler = new MyResponseHandler();
    IHttpRequest request = new PostRequest(url_address, "application/json", Consts.UTF_8.toString(), event);
    request.setTransferEncoding(Consts.UTF_8.toString());
    httpClientConnection.send(request, responseHandler);
} catch (Exception e) {
    LOG.error("Failed to sending event", e);
}
}
Run Code Online (Sandbox Code Playgroud)

我没有例外但是帖子也没有达到目标.需要说明的是,目标是石墨服务器,所以一旦帖子到达,就会在图表中清楚地看到.同步帖很好用,我可以在图上看到结果,但是我的目标图上没有显示任何异步帖.

我错过了什么?

谢谢

for*_*has 4

知道了。

我使用的所有库都是使用额外的 IO 线程实现的,因此我的进程可能在完全握手之前结束。

一旦我在 http 调用之后添加 Thread.sleep(2000) ,一切就正常了。因此,对于网络应用程序(这是我的情况),我建议的实现就很好(但对于 java 进程,您可能会考虑 NickJ 的答案)。

  • 如果您使用额外的 IO 线程,您仍然会损害整个线程池,对吗?一天结束时,您将多使用 1 个线程来处理回调,不是吗? (2认同)