java неблокирующий HTTP-клиент
у меня есть приложение java большого объема, в котором я должен отправлять сообщения http на другой сервер. В настоящее время я использую org.апаш.палата общин.с помощью 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 async и 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);
}
}
Я не получаю никаких исключений, но сообщение не попадает в цель. Чтобы быть ясным, цель -графит сервера поэтому, как только сообщение прибывает, оно ясно видно на графике. Синхронные сообщения работают хорошо, я могу см. результат на графике, но ни один из асинхронных сообщений не отображается на графике назначения.
что я упустил?
спасибо
2 ответов
получил его.
все библиотеки, которые я использую, реализованы с использованием дополнительного потока ввода-вывода, поэтому мой процесс, вероятно, заканчивается до полного рукопожатия.
Как только я добавил поток.sleep (2000) после http-вызовов все работало нормально. Поэтому для веб-приложения (что является моим случаем) мои предлагаемые реализации просто прекрасны (но для процесса java вы можете рассмотреть ответ NickJ).
вы можете использовать Java executor framework:
во-первых, создайте вызываемый для выполнения вашей работы:
public class MyCallable implements Callable<MyResult> {
@Override
public MyResult call() throws Exception {
//do stuff
return result;
}
}
получить 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
}