最近在做需求的时候,遇到一个问题,就是调用三方的服务,没有设置超时链接,影响了消息队列中消息的消费速度,进而导致消息队列消息有挤压。对此找到了一种设置连接超时的方法,适用于基于Xfire实现webservice的调用,具体如下:
1、新建HttpMessageSender
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.exchange.OutMessage;
import org.codehaus.xfire.transport.http.CommonsHttpMessageSender;
/**
* @description resolve the connection timeout
* @author jerry
* @date 20170814
*
*/
public class HttpMessageSender extends CommonsHttpMessageSender{
public HttpMessageSender(OutMessage message, MessageContext context) {
super(message, context);
}
protected synchronized void createClient(){
super.createClient();
HttpClientParams params = (HttpClientParams) getMessageContext().getContextualProperty(HTTP_CLIENT_PARAMS);
if (params != null){
HttpConnectionManagerParams connParams = getClient().getHttpConnectionManager().getParams();
connParams.setDefaults(params);
}
}
}
2、在调用端设置httpclient的属性
AddServiceClient addEmailServiceclient = new AddServiceClient();
final AddServicePortType service = addServiceclient.getAddEmailServiceHttpPort();
Client client = Client.getInstance(service);
HttpClientParams params = new HttpClientParams();
// 如果服务不需要传输大量的数据,保持长连接,还是建议关闭掉此功能,设置为false。否则,在业务量很大的情况下,很容易将服务端和自己都搞的很慢甚至拖死。
params.setParameter(HttpClientParams.USE_EXPECT_CONTINUE, Boolean.FALSE);
// 设置从连接池中取连接超时时间(单位:毫秒)
params.setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, 10000L);
//socket超时时间(单位:毫秒)
params.setIntParameter(HttpClientParams.SO_TIMEOUT, 30000);
//连接超时时间(单位:毫秒)
params.setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 30000);
// params.setParameter(HttpClientParams.MAX_REDIRECTS, 2);
client.setProperty(CommonsHttpMessageSender.HTTP_CLIENT_PARAMS, params);
//http 单个host连接池最大连接数(host只有一个,值同MAX_TOTAL_CONNECTIONS)
client.setProperty(CommonsHttpMessageSender.MAX_CONN_PER_HOST, "100");
//http 连接池最大连接数
client.setProperty(CommonsHttpMessageSender.MAX_TOTAL_CONNECTIONS, "100");
client.setProperty(AbstractMessageSender.MESSAGE_SENDER_CLASS_NAME, "xxxxx.xxxx.xxxx.util.HttpMessageSender");//第1步中HttpMessageSender在项目中的路径