[英]java Non-blocking HTTP client
I have a high volume java application in which I have to send http posts to another server. 我有一个高容量的Java应用程序,我必须将http帖子发送到另一台服务器。 Currently I'm using org.apache.commons.httpclient library:
目前我正在使用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);
}
}
This means I'm sending my http requests synchronously, which doesn't fit my multithreaded high volume app. 这意味着我正在同步发送我的http请求,这不适合我的多线程高容量应用程序。 So I would like to change those calls to asynchronous non-blocking http calls.
所以我想将这些调用更改为异步非阻塞http调用。
I was going through number of options such as apache async client and xsocket but was not able to make it work. 我经历了一些选项,如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);
}
}
I tried Apache HttpAsyncClient : 我试过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);
}
}
I tried xsocket : 我试过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);
}
}
I get no exceptions but the post doesn't get to the target as well. 我没有例外但是帖子也没有达到目标。 To be clear, the target is a graphite server so once a post arrives it is clearly seen in a graph.
需要说明的是,目标是石墨服务器,所以一旦帖子到达,就会在图表中清楚地看到。 The synchronous posts works well, I can see the result on the graph, but none of the asynchronous posts shows on my destination graph.
同步帖很好用,我可以在图上看到结果,但是我的目标图上没有显示任何异步帖。
What am I missing? 我错过了什么?
Thanks 谢谢
Got it. 得到它了。
All the libraries I'n using are implemented using an extra IO thread, so my process probably ends before a full handshake. 我使用的所有库都是使用额外的IO线程实现的,所以我的进程可能在完全握手之前结束。
Once I added Thread.sleep(2000) after the http calls things worked just fine. 一旦我在http调用之后添加了Thread.sleep(2000)就可以了。 So for a web app (which is my case) my suggested implementations are just fine (but for a java process you might consider NickJ's answer).
所以对于一个Web应用程序(这是我的情况)我建议的实现很好(但对于java进程,你可能会考虑NickJ的答案)。
You could use the Java Executor framework: 您可以使用Java Executor框架:
First, create a Callable to do your work: 首先,创建一个Callable来完成你的工作:
public class MyCallable implements Callable<MyResult> {
@Override
public MyResult call() throws Exception {
//do stuff
return result;
}
}
Get an Exectutor which will run your Callable. 获取将运行Callable的Exectutor。 There are various way to get one, here's one example:
有一种方法可以得到一个,这是一个例子:
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
Finally, run it: 最后,运行它:
MyCallable callable = new MyCallable();
Future<MyResult> futureResult = executor.submit(callable);
Getting the result: 得到结果:
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.