簡體   English   中英

java非阻塞HTTP客戶端

[英]java Non-blocking HTTP client

我有一個高容量的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);

}
}

這意味着我正在同步發送我的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);
}
}

我試過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);
}
}

我試過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);
}
}

我沒有例外但是帖子也沒有達到目標。 需要說明的是,目標是石墨服務器,所以一旦帖子到達,就會在圖表中清楚地看到。 同步帖很好用,我可以在圖上看到結果,但是我的目標圖上沒有顯示任何異步帖。

我錯過了什么?

謝謝

得到它了。

我使用的所有庫都是使用額外的IO線程實現的,所以我的進程可能在完全握手之前結束。

一旦我在http調用之后添加了Thread.sleep(2000)就可以了。 所以對於一個Web應用程序(這是我的情況)我建議的實現很好(但對於java進程,你可能會考慮NickJ的答案)。

您可以使用Java Executor框架:

首先,創建一個Callable來完成你的工作:

public class MyCallable implements Callable<MyResult> {
  @Override
  public MyResult call() throws Exception {
    //do stuff
    return result;
  }
} 

獲取將運行Callable的Exectutor。 有一種方法可以得到一個,這是一個例子:

ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);

最后,運行它:

MyCallable callable = new MyCallable();
Future<MyResult> futureResult = executor.submit(callable);

得到結果:

boolean resultReady = futureResult.isDone(); //is the result ready yet?
Result r = futureResult.get(); //wait for result and return it

try {
  Result r = futureResult.get(10, TimeUnit.SECONDS); //wait max. 10 seconds for result
} catch (TimeOutException e) {
  //result still not ready after waiting 10 seconds
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM