CXF JAXRS客户端不重用TCP连接

Joh*_*Rix 3 rest tcp cxf jax-rs keep-alive

我正在使用CXF 2.2.5中的JAX-RS支持来调用REST Web服务。我为需要与之通信的每个终结点(通常是一个或两个终结点,对于任何给定的部署)创建一个org.apache.cxf.jaxrs.client.WebClient实例,并为每个Web服务调用重用此客户端。

我面临的问题是,尽管使用了保持活动设置,客户端仍在为每个请求创建与服务器的新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) {
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

小智 5

在示例代码中,您将获得JAX-RS响应,默认情况下,该getEntity()方法将返回InputStream。因此,由于CXF不负责使用流,因此显然这是开放的。

如果您没有明确关闭它,它将在垃圾回收阶段关闭。但是即使如此,在高通信量的情况下,这种很小的延迟也可以防止将基础HTTP连接重新插入到HttpURLConnection利用的持久连接的内部池中(该CXF在引擎盖下使用)。因此,它不能按时重用。

如果您要关闭InputStream,则应该不再看到大量的TIME_WAIT套接字。