Клиент CXF JAXRS не использует повторно соединения TCP - PullRequest
3 голосов
/ 11 июля 2011

Я использую поддержку JAX-RS в CXF 2.2.5 для вызова веб-сервисов REST. Я создаю отдельный экземпляр org.apache.cxf.jaxrs.client.WebClient для каждой конечной точки, с которой мне нужно связаться (обычно одна или две конечные точки для любого данного развертывания), и повторно использую этот клиент для каждого вызова веб-службы.

Проблема, с которой я сталкиваюсь, заключается в том, что клиент создает новые TCP-соединения с сервером для каждого запроса, несмотря на использование параметра keep-alive. На высоких уровнях трафика это вызывает проблемы. Ниже приведена выдержка из моего клиентского кода.

Я пытаюсь покопаться в источнике 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) {
    }

    ...
}

Ответы [ 2 ]

4 голосов
/ 05 сентября 2011

В вашем примере кода вы получите ответ JAX-RS, который getEntity () метод вернет InputStream по умолчанию.Следовательно, поскольку CXF не отвечает за использование потока, он, очевидно, остается открытым.

Если вы не закроете это явно, он будет закрыт на этапе сбора мусора.Но даже в этом случае при высоких скоростях трафика эта небольшая задержка предотвращает повторную вставку основного HTTP-соединения во внутренний пул постоянных соединений, используемых HttpURLConnection (который CXF использует под капотом).Поэтому он не может быть повторно использован вовремя.

Если вы позаботитесь о закрытии InputStream, вы больше не должны видеть большое количество сокетов TIME_WAIT.

1 голос
/ 11 июля 2011

Я бы определенно попытался перейти на более новую и поддерживаемую версию CXF.Было много обновлений JAX-RS в более новых версиях CXF, и эта проблема уже может быть исправлена.

...