杰瑞科技汇

Java webservice超时如何正确设置?

下面我将详细讲解如何在这两种场景下设置超时,并以主流的 JAX-WS (Java API for XML Web Services)Apache CXF 为例进行说明。

Java webservice超时如何正确设置?-图1
(图片来源网络,侵删)

客户端超时设置 (Client-side Timeout)

客户端超时指的是,当客户端调用一个 WebService 时,如果在指定的时间内没有收到服务器的响应,就认为请求失败并抛出超时异常。

JAX-WS 客户端超时设置

JAX-WS 客户端通常通过 BindingProvider 接口来配置连接和读取超时。

核心概念:

  • javax.xml.ws.BindingProvider: 所有 JAX-WS 客户端端口(Port)都实现了这个接口。
  • javax.xml.ws.WebServiceFeature: 用于配置 WebService 的特性,HTTPClientPolicy 就是一个用于配置 HTTP 客户端行为的特性,它包含了超时设置。

示例代码:

Java webservice超时如何正确设置?-图2
(图片来源网络,侵删)

假设我们有一个客户端生成的 MyService 类。

import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.soap.SOAPBinding;
import com.sun.xml.ws.client.BindingProviderProperties; // 注意:这是 Sun/Oracle 的特定 API
import com.sun.xml.ws.developer.JAXWSProperties; // 更通用的 API
public class JaxwsClientTimeoutExample {
    public static void main(String[] args) {
        // 1. 创建 WebService 客户端
        MyService service = new MyService();
        MyServicePortType port = service.getMyServicePort();
        // 2. 获取 BindingProvider 实例
        BindingProvider bindingProvider = (BindingProvider) port;
        // 3. 设置超时 (两种方式,推荐使用第二种更标准的方式)
        // 方式一:使用 Sun/Oracle 特定的属性 (简单直接,但可移植性稍差)
        bindingProvider.getRequestContext().put(
            BindingProviderProperties.CONNECT_TIMEOUT, 5000); // 5秒连接超时
        bindingProvider.getRequestContext().put(
            BindingProviderProperties.REQUEST_TIMEOUT, 10000); // 10秒读取超时
        // 方式二:使用标准的 HTTPClientPolicy (更推荐,可移植性好)
        // 首先获取或创建 SOAPBinding
        SOAPBinding binding = (SOAPBinding) bindingProvider.getBinding();
        // 创建 HTTPClientPolicy
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setConnectionTimeout(5000); // 5秒连接超时
        httpClientPolicy.setReceiveTimeout(10000);  // 10秒读取超时
        // 将 policy 应用到 binding
        binding.setOutboundAttachments(null); // 清除旧的附件策略
        binding.setHandlerChain(null); // 清除旧的处理器链
        binding.setFeature(new HTTPClientFeature(httpClientPolicy)); // 设置新的特性
        // 4. 调用 WebService
        try {
            String result = port.someMethod("some data");
            System.out.println("调用成功: " + result);
        } catch (Exception e) {
            System.err.println("调用失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

参数解释:

  • CONNECT_TIMEOUT / setConnectionTimeout(): 客户端与服务器建立 TCP 连接的超时时间(单位:毫秒),如果在这段时间内无法建立连接,则会抛出 java.net.SocketTimeoutException
  • REQUEST_TIMEOUT / setReceiveTimeout(): 客户端从服务器接收响应数据的超时时间(单位:毫秒),如果在这段时间内没有完整地接收到响应数据,则会抛出 java.net.SocketTimeoutException

Apache CXF 客户端超时设置

Apache CXF 是一个功能强大的开源框架,它对超时的控制更加灵活和细致。

核心概念:

Java webservice超时如何正确设置?-图3
(图片来源网络,侵删)
  • org.apache.cxf.configuration.jsse.TLSClientParameters: 用于配置 SSL/TLS 相关的超时。
  • org.apache.cxf.frontend.ClientProxy: 用于获取客户端的底层配置对象。
  • org.apache.cxf.transports.http.configuration.HTTPClientPolicy: CXF 中用于配置 HTTP 客户端的核心策略类。

示例代码:

import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy.ConnectionTimeout;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy.ReceiveTimeout;
public class CxfClientTimeoutExample {
    public static void main(String[] args) {
        // 1. 创建 WebService 客户端 (假设使用 CXF 生成的客户端)
        MyService service = new MyService();
        MyServicePortType port = service.getMyServicePort();
        // 2. 获取 HTTPClientPolicy
        HTTPClientPolicy httpClientPolicy = ClientProxy.getClient(port).getHTTPClientPolicy();
        // 3. 设置超时
        httpClientPolicy.setConnectionTimeout(5000); // 5秒连接超时
        httpClientPolicy.setReceiveTimeout(10000);  // 10秒读取超时
        // CXF 还支持更细粒度的超时控制
        // httpClientPolicy.setConnectionRequestTimeout(3000); // 从连接池获取连接的超时
        // 4. (可选) 设置重试策略
        // httpClientPolicy.setAllowChunking(false); // 禁用分块传输,有时有助于解决超时问题
        // 5. 调用 WebService
        try {
            String result = port.someMethod("some data");
            System.out.println("调用成功: " + result);
        } catch (Exception e) {
            System.err.println("调用失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

服务端超时设置 (Server-side Timeout)

服务端超时指的是,当服务器接收到一个请求后,如果在指定的时间内无法处理完毕,就主动中断请求,并向客户端返回一个超时错误,这可以防止服务器线程长时间被一个慢请求占用,从而影响其他请求的处理。

JAX-WS 服务端超时设置 (在 Tomcat/JBoss 等 Servlet 容器中)

在标准的 JAX-WS 实现中,服务端超时通常不是直接通过 JAX-WS API 设置的,而是依赖于底层的 Servlet 容器(如 Tomcat)的配置。

在 Tomcat 中配置:

Tomcat 的 web.xml 文件中可以配置 Servlet 的超时。

<web-app ...>
    <servlet>
        <servlet-name>MyService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <!-- 设置 Servlet 超时为 30 秒 -->
        <async-timeout>30000</async-timeout> 
    </servlet>
    <servlet-mapping>
        <servlet-name>MyService</servlet-name>
        <url-pattern>/myservice</url-pattern>
    </servlet-mapping>
</web-app>

<async-timeout>:

  • 这个标签用于配置异步 Servlet 的超时时间(单位:毫秒)。
  • 当一个请求被异步处理后,如果超过这个时间还没有完成,容器会调用 AsyncContext.complete()AsyncContext.dispatch() 来结束异步处理。
  • 这对于处理长时间运行的任务非常有用。

对于同步请求,超时主要由 Servlet 容器的连接超时 控制,这通常在 server.xml 中配置:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"  <!-- 连接建立后,等待请求的超时 -->
           redirectPort="8443" />

Apache CXF 服务端超时设置

CXF 提供了更精细的控制,可以通过配置文件或编程方式来设置。

通过 cxf.xml 配置文件:

WEB-INF/cxf.xml 中配置 HTTP 传输器的超时。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://cxf.apache.org/transports/http/configuration
           http://cxf.apache.org/schemas/configuration/http.xsd">
    <!-- 配置 HTTP 传输器 -->
    <http:destination name="{http://your.namespace/}MyServicePort.http-destination">
        <http:server ConnectionTimeout="10000" ReceiveTimeout="30000"/>
    </http:destination>
</beans>
  • ConnectionTimeout: 服务器端等待客户端连接建立的超时。
  • **`
分享:
扫描分享到社交APP
上一篇
下一篇