xfire在高并发下的问题
在高并发的情况下,我同事测试出来有个问题,说是client里面有并发限制,而且是写死在代码里面的default配置
private static final int DEFAULT_MAX_CONN_PER_HOST = 6;
我也查找了一下,在类org.codehaus.xfire.transport.http.CommonsHttpMessageSender.java里面。
那么怎么修改呢,我参考了如下一些BLOG:
http://hi.baidu.com/hao_holly/blog/item/5377ba244f925820d407429c.html
http://xtjjj.blog.sohu.com/149111514.html
http://xfire.codehaus.org/Client+API
由于我以前为了写client方便,自己写了一个FactoryBean
com.sillycat.core.commons.plugins.webservice.xfire.XFireClientFactory
所以,目前我的思路就是参考org.codehaus.xfire.spring.remoting.XFireClientFactoryBean,将这些属性配置扩展上去。
查看xfire源码,找到了org.codehaus.xfire.service.binding.ObjectServiceFactory.java程序里面的436行:
setProperties(endpoint, properties);
这里就是读入配置,向Service里面写的地方了,参考这里的实现,修改了XFireClientFactory.java如下:
package com.sillycat.core.commons.plugins.webservice.xfire;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.Assert;
public class XFireClientFactory implements FactoryBean {
private static XFireProxyFactory serviceFactory = new XFireProxyFactory();
private static final Log log = LogFactory.getLog(XFireClientFactory.class);
private String serviceURL;
private String serviceClassName;
// hold the properties
private Map<String, String> _properties;
public Map<String, String> getProperties() {
return _properties;
}
/**
* Set the properties for the Client.
*/
public void setProperties(Map<String, String> properties) {
this._properties = properties;
}
private XFireClientFactory() {
}
public Object getObject() throws Exception {
String url = this.getServiceURL();
Class<?> sClass = null;
try {
sClass = Class.forName(this.getServiceClassName());
} catch (ClassNotFoundException e) {
log.error(e.getMessage(), e);
return null;
}
Assert.notNull(url);
Assert.notNull(sClass);
Service serviceModel = new ObjectServiceFactory().create(sClass);
setProperties(serviceModel, this.getProperties());
try {
return serviceFactory.create(serviceModel, url);
} catch (MalformedURLException e) {
log.error(e.getMessage(), e);
return null;
}
}
@SuppressWarnings("unchecked")
private void setProperties(Service service, Map<String, String> properties) {
if (properties == null) {
return;
}
for (Iterator<?> itr = properties.entrySet().iterator(); itr.hasNext();) {
Map.Entry entry = (Map.Entry) itr.next();
service.setProperty((String) entry.getKey(), entry.getValue());
}
}
public Class<?> getObjectType() {
Class<?> sClass = null;
try {
sClass = Class.forName(this.getServiceClassName());
} catch (ClassNotFoundException e) {
log.error(e.getMessage(), e);
return null;
}
return sClass;
}
public boolean isSingleton() {
return true;
}
public String getServiceURL() {
return serviceURL;
}
public void setServiceURL(String serviceURL) {
this.serviceURL = serviceURL;
}
public String getServiceClassName() {
return serviceClassName;
}
public void setServiceClassName(String serviceClassName) {
this.serviceClassName = serviceClassName;
}
}
spring的配置文件,修改成为如下:
<bean name="userService"
class="com.sillycat.core.commons.plugins.webservice.xfire.XFireClientFactory">
<property name="serviceURL" value="${user.serviceURL}" />
<property name="serviceClassName" value="${user.serviceClassName}" />
<property name="properties">
<props>
<!-- 等待HttpConnectionManager从连接池中返回空闲连接的超时时间 -->
<prop key="http.connection.manager.timeout">1000</prop>
<!-- 等待建立连接的超时时间 -->
<prop key="http.connection.timeout">2000</prop>
<!-- 等待服务器返回数据超时时间 -->
<prop key="http.timeout">5000</prop>
<!-- 连接到单个服务器的连接数上限 -->
<prop key="max.connections.per.host">10</prop>
<!-- 连接到所有服务器的连接个数上限 -->
<prop key="max.total.connections">80</prop>
</props>
</property>
</bean>
测试一下,调用是没有问题的,至于这个properties生效没有,就需要多测试一下高并发的情况了。既然xfire有Factorybean,为啥当初我还要重复发明轮子,参考springside重新写一个呢。可能也是为了某个地方简单吧。记录一下,留着以后备用。另外每个service都配置一个,还显得比较繁琐,以后看能不能略微改改。
在高并发的情况下,我同事测试出来有个问题,说是client里面有并发限制,而且是写死在代码里面的default配置
private static final int DEFAULT_MAX_CONN_PER_HOST = 6;
我也查找了一下,在类org.codehaus.xfire.transport.http.CommonsHttpMessageSender.java里面。
那么怎么修改呢,我参考了如下一些BLOG:
http://hi.baidu.com/hao_holly/blog/item/5377ba244f925820d407429c.html
http://xtjjj.blog.sohu.com/149111514.html
http://xfire.codehaus.org/Client+API
由于我以前为了写client方便,自己写了一个FactoryBean
com.sillycat.core.commons.plugins.webservice.xfire.XFireClientFactory
所以,目前我的思路就是参考org.codehaus.xfire.spring.remoting.XFireClientFactoryBean,将这些属性配置扩展上去。
查看xfire源码,找到了org.codehaus.xfire.service.binding.ObjectServiceFactory.java程序里面的436行:
setProperties(endpoint, properties);
这里就是读入配置,向Service里面写的地方了,参考这里的实现,修改了XFireClientFactory.java如下:
package com.sillycat.core.commons.plugins.webservice.xfire;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.Assert;
public class XFireClientFactory implements FactoryBean {
private static XFireProxyFactory serviceFactory = new XFireProxyFactory();
private static final Log log = LogFactory.getLog(XFireClientFactory.class);
private String serviceURL;
private String serviceClassName;
// hold the properties
private Map<String, String> _properties;
public Map<String, String> getProperties() {
return _properties;
}
/**
* Set the properties for the Client.
*/
public void setProperties(Map<String, String> properties) {
this._properties = properties;
}
private XFireClientFactory() {
}
public Object getObject() throws Exception {
String url = this.getServiceURL();
Class<?> sClass = null;
try {
sClass = Class.forName(this.getServiceClassName());
} catch (ClassNotFoundException e) {
log.error(e.getMessage(), e);
return null;
}
Assert.notNull(url);
Assert.notNull(sClass);
Service serviceModel = new ObjectServiceFactory().create(sClass);
setProperties(serviceModel, this.getProperties());
try {
return serviceFactory.create(serviceModel, url);
} catch (MalformedURLException e) {
log.error(e.getMessage(), e);
return null;
}
}
@SuppressWarnings("unchecked")
private void setProperties(Service service, Map<String, String> properties) {
if (properties == null) {
return;
}
for (Iterator<?> itr = properties.entrySet().iterator(); itr.hasNext();) {
Map.Entry entry = (Map.Entry) itr.next();
service.setProperty((String) entry.getKey(), entry.getValue());
}
}
public Class<?> getObjectType() {
Class<?> sClass = null;
try {
sClass = Class.forName(this.getServiceClassName());
} catch (ClassNotFoundException e) {
log.error(e.getMessage(), e);
return null;
}
return sClass;
}
public boolean isSingleton() {
return true;
}
public String getServiceURL() {
return serviceURL;
}
public void setServiceURL(String serviceURL) {
this.serviceURL = serviceURL;
}
public String getServiceClassName() {
return serviceClassName;
}
public void setServiceClassName(String serviceClassName) {
this.serviceClassName = serviceClassName;
}
}
spring的配置文件,修改成为如下:
<bean name="userService"
class="com.sillycat.core.commons.plugins.webservice.xfire.XFireClientFactory">
<property name="serviceURL" value="${user.serviceURL}" />
<property name="serviceClassName" value="${user.serviceClassName}" />
<property name="properties">
<props>
<!-- 等待HttpConnectionManager从连接池中返回空闲连接的超时时间 -->
<prop key="http.connection.manager.timeout">1000</prop>
<!-- 等待建立连接的超时时间 -->
<prop key="http.connection.timeout">2000</prop>
<!-- 等待服务器返回数据超时时间 -->
<prop key="http.timeout">5000</prop>
<!-- 连接到单个服务器的连接数上限 -->
<prop key="max.connections.per.host">10</prop>
<!-- 连接到所有服务器的连接个数上限 -->
<prop key="max.total.connections">80</prop>
</props>
</property>
</bean>
测试一下,调用是没有问题的,至于这个properties生效没有,就需要多测试一下高并发的情况了。既然xfire有Factorybean,为啥当初我还要重复发明轮子,参考springside重新写一个呢。可能也是为了某个地方简单吧。记录一下,留着以后备用。另外每个service都配置一个,还显得比较繁琐,以后看能不能略微改改。