2011-07-11 20 views
3

CXF 2.2.5でJAX-RSサポートを使用してREST Webサービスを呼び出しています。私は通信する必要のある各エンドポイント(通常は任意のデプロイメントに対して1つまたは2つのエンドポイント)に対して1つのorg.apache.cxf.jaxrs.client.WebClientインスタンスを作成し、各Webサービス呼び出しでこのクライアントを再利用します。CXF JAXRSクライアントがTCP接続を再利用しない

私が直面する問題は、キープアライブ設定を使用しているにもかかわらず、クライアントが要求ごとにサーバーに新しいTCP接続を作成していることです。高いトラフィックレベルでは、これが問題を引き起こしています。私のクライアントコードからの抜粋は以下の通りです。

私は問題を特定するためにCXFソースを掘り下げようとしていますが、現在は絶望的に失われています。どのような考えが大いに感謝します。

おかげで、 FB

ConcurrentMap<String, WebClient> webclients = new ConcurrentHashMap<String, WebClient>(); 

public void dispatchRequest(MyRequestClass request, String hostAddress) { 

    // Fetch or create the web client if we don't already have one for this hostAddress 
    // NOTE: WebClient is only thread-safe if not changing the URI or headers between calls! 
    // http://cxf.apache.org/docs/jax-rs-client-api.html#JAX-RSClientAPI-ThreadSafety 
    WebClient client = webclients.get(hostAddress); 
    if (client == null) { 
     String serviceUrl = APP_HTTP_PROTOCOL + "://" + hostAddress + ":" + APP_PORT + "/" + APP_REQUEST_PATH; 
     WebClient newClient = WebClient.create(serviceUrl).accept(MediaType.TEXT_PLAIN); 
     client = webclients.putIfAbsent(hostAddress, newClient); 
     if (client == null) { 
      client = newClient; 
     } // Else, another thread must have added the client in the meantime - that's fine if so. 
    } 

    XStream marshaller = MyCollection.getMarshaller(); 
    String requestXML = marshaller.toXML(request); 

    Response response = null; 
    try { 
     // Send it! 
     response = client.post(requestXML); 
    } 
    catch (Exception e) { 
    } 

    ... 
} 

答えて

4

。したがって、CXFはストリームの消費に責任を負いませんが、これは明らかに開かれたままです。

明示的に閉じないと、ガベージコレクションフェーズ中に閉じられます。 しかし、高いトラフィック速度では、このわずかな遅延によって、HttpURLConnection(ボンネットの下でCXFが使用している)によって悪用されている内部接続の内部プールに、元のHTTP接続を再挿入することができなくなります。だから、時間通りに再利用することはできません。

InputStreamを閉じるときには、TIME_WAITソケットが多数表示されないようにしてください。

+1

私は基本的なコモンズHttp接続ベースのアプローチに落ち着きましたが、私の要求は定式化が簡単だったので、実際には何もする必要はほとんどありませんでしたが、CXFをもう一度使っても、これは間違いなく便利です! –

1

私は間違いなく、CXFの新しいおよびサポートされているバージョンに更新しようとするだろう。新しいバージョンのCXFではJAX-RSのアップデートがたくさんありましたが、この問題はすでに修正されている可能性があります。

あなたは方法は、デフォルトで のInputStreamを返します getEntity()JAX-RSレスポンスを取得あなたのサンプルコードで
+0

私は大好きですが、私のコントロール外のいくつかのプロジェクトの依存関係のため、現在このバージョンに固執しています。 : –

+0

Dan、開発マシンで2.4.1へのアップグレードを試みましたが、残念なことに同じ問題が発生しました –

関連する問題