2014-01-08 17 views
6

私は別のサーバーにhttp投稿を送信する必要がある大量のJavaアプリケーションを持っています。 は現在、私はorg.apache.commons.httpclientライブラリを使用しています:java非ブロッキングHTTPクライアント

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 clientxsocketのようなオプションの数を調べていましたが、それを動作させることはできませんでした。

ningをしようとしました:

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); 
} 
} 

私は例外を取得していないが、ポストはに取得していませんターゲットも同様です。 明確にするには、ターゲットはgraphite serverです。投稿が到着すると、それはグラフにはっきりと見えます。同期ポストはうまくいき、結果をグラフで見ることができますが、非同期ポストは目的地のグラフに表示されません。

私には何が欠けていますか?

おかげ

+0

最初の例を 'apache async client'から' HttpGet'の代わりに 'HttpPost'を使うよう変換してください。 –

+0

実例を使って回答を投稿し、クレジットを獲得するのはどうですか? – forhas

答えて

1

はそれを手に入れました。

私が使用しているすべてのライブラリは余分なIOスレッドを使用して実装されているので、私のプロセスは完全なハンドシェイクの前に終了する可能性があります。

httpを呼び出した後にThread.sleep(2000)を追加すると、うまくいきました。 ウェブアプリケーション(私の場合)のために私の提案された実装はちょうど良いですが(Javaプロセスの場合は、NickJの答えを考慮するかもしれません)。

1

あなたはJavaのエグゼキュータのフレームワークを使用できます。あなたのコーラブルを実行するExectutorを取得

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

:、

まず、あなたの仕事をするために呼び出し可能を作成します。 1を取得するための様々な方法がありますが、ここでは一例です:

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 
} 
+0

ニースですが、私はむしろ、私にはこれを行うライブラリを使用しています。 – forhas

+4

これは、真のノンブロッキングI/Oではなく、リクエストごとにスレッドを起動するだけではありませんか? – necromancer

+3

これは、呼び出し元のスレッドでブロックすることと変わりありません。適切な非ブロッキング要求を行うには、NIOクライアントを使用する必要があります。 – HaxElit