于吉吉的技术博客

建造高性能门户网

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  65 随笔 :: 6 文章 :: 149 评论 :: 0 Trackbacks
目前几套系统中主要使用的hessian进行远程调用webservice服务的有hessian的HessianProxyFactory(com.caucho.hessian.client.HessianProxyFactory)和spring的HessianProxyFactoryBean(org.springframework.remoting.caucho.HessianProxyFactoryBean).

1.HessianProxyFactory
查看HessianProxyFactory源码后发现,hessian在创建http请求连接webservice服务并没有对连接超时进行相关的参数设置,所以当网络出现问题就会造成整个hessian处理的阻塞,进而阻塞整个线程后续的处理
以下是HessianProxyFactory对连接处理的源码

protected URLConnection openConnection(URL url)
    
throws IOException
  {
    URLConnection conn 
= url.openConnection();

    conn.setDoOutput(
true);

    
if (_readTimeout > 0) {
      
try {
    conn.setReadTimeout((
int) _readTimeout);
      } 
catch (Throwable e) {
      }
    }

    conn.setRequestProperty(
"Content-Type""x-application/hessian");

    
if (_basicAuth != null)
      conn.setRequestProperty(
"Authorization", _basicAuth);
    
else if (_user != null && _password != null) {
      _basicAuth 
= "Basic " + base64(_user + ":" + _password);
      conn.setRequestProperty(
"Authorization", _basicAuth);
    }

    
return conn;
  }

所以我们针对此逻辑继承并重写该openConnection方法,在创建http连接的时候通过设置连接超时时间来解决因网络问题阻塞程序继续的问题

public class MyHessianProxyFactory extends HessianProxyFactory {

    
private int connectTimeOut = 10000;

    
private int readTimeOut = 10000;

    
public int getConnectTimeOut() {
        
return connectTimeOut;
    }

    
public void setConnectTimeOut(int connectTimeOut) {
        
this.connectTimeOut = connectTimeOut;
    }

    
public int getReadTimeOut() {
        
return readTimeOut;
    }

    
public void setReadTimeOut(int readTimeOut) {
        
this.readTimeOut = readTimeOut;
    }

    
protected URLConnection openConnection(URL url) throws IOException {
        URLConnection conn 
= url.openConnection();
        conn.setDoOutput(
true);
        
if (this.connectTimeOut > 0) {
            conn.setConnectTimeout(
this.connectTimeOut);
        }
        
if (this.readTimeOut > 0) {
            conn.setReadTimeout(
this.readTimeOut);
        }
        conn.setRequestProperty(
"Content-Type""x-application/hessian");
            
if (_basicAuth != null)
                  conn.setRequestProperty(
"Authorization", _basicAuth);
            
else if (_user != null && _password != null) {
                  _basicAuth 
= "Basic " + base64(_user + ":" + _password);
                  conn.setRequestProperty(
"Authorization", _basicAuth);
            }
        
return conn;
    }
}

2.HessianProxyFactoryBean
查看spring的HessianProxyFactoryBean源码发现,它在封装hessian是直接创建一个HessianProxyFactory实例,然后利用该实例完成创建远程服务

public class HessianProxyFactoryBean extends HessianClientInterceptor implements FactoryBean {

    
private Object serviceProxy;


    
public void afterPropertiesSet() {
        
super.afterPropertiesSet();
        
this.serviceProxy = ProxyFactory.getProxy(getServiceInterface(), this);
    }
    

    
public Object getObject() {
        
return this.serviceProxy;
    }

    
public Class getObjectType() {
        
return getServiceInterface();
    }
    
    
public boolean isSingleton() {
        
return true;
    }

}

所以对此的解决方法与上面差不多,继承HessianProxyFactoryBean然后加入相应的连接超时和读取超时的变量,重写afterPropertiesSet方法,并且同时完成上面第一步对HessianProxyFactory的改造,这样就能保证连接远程webserver服务器时不会因为网络原因阻塞程序的执行

public class MyHessianProxyFactoryBean extends HessianProxyFactoryBean {

    
private MyHessianProxyFactory proxyFactory = new MyHessianProxyFactory();

    
private int readTimeOut = 10000;

    
private int connectTimeOut = 10000;

    
public int getReadTimeOut() {
        
return readTimeOut;
    }

    
public void setReadTimeOut(int readTimeOut) {
        
this.readTimeOut = readTimeOut;
    }

    
public int getConnectTimeOut() {
        
return connectTimeOut;
    }

    
public void setConnectTimeOut(int connectTimeOut) {
        
this.connectTimeOut = connectTimeOut;
    }

    
public void afterPropertiesSet() {
        proxyFactory.setReadTimeout(readTimeOut);
        proxyFactory.setConnectTimeOut(connectTimeOut);
        setProxyFactory(proxyFactory);
        
super.afterPropertiesSet();
    }
}


posted on 2010-12-16 14:46 陈于喆 阅读(11997) 评论(11)  编辑  收藏 所属分类: web开发javaweb service

评论

# re: 解决hessian远程调用连接超时的问题 2010-12-16 15:25 Xuzhengsong
我觉得可以这样重写openConnection方法
protected URLConnection openConnection(URL url) throws IOException {

URLConnection conn = super.openConnection(url);
if (this.connectTimeOut > 0) {
conn.setConnectTimeout(this.connectTimeOut);
}
retrun conn;
}  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2010-12-16 15:33 陈于喆
@Xuzhengsong
非常感谢,这样更简洁  回复  更多评论
  

# ugg boots womens 2010-12-16 15:47 ugg boots womens
谢谢 这样以后方便了许多  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2010-12-28 18:53 mrt_soul
HessianProxyFactory 有_readTimeout设置项啊!
只是没有connectTimeOut  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2011-10-17 13:05 郭蕾
楼主,在hessian中相关设置的!  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2012-07-23 12:25 Eddy.he
请问你用的是哪个版本的hessian包?父类HessianProxyFactory 里面的变量_basicAuth 、_user ,子类能引用到吗?不知道你自己有没有测试过哦。  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2012-07-23 12:30 Eddy.he
@郭蕾
你设置给我看看,怎么设置connectTimeout?麻烦分享一下。  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2012-11-05 17:24 郭蕾
factory.setReadTimeout  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2012-11-05 17:25 郭蕾
请看看这个软件:http://www.oschina.net/news/34462/hetty-1-3-rpc-framework  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题 2012-11-15 15:17 gahd
你敢把代码写完么?帖一部分跟没帖没什么区别吧  回复  更多评论
  

# re: 解决hessian远程调用连接超时的问题[未登录] 2016-01-22 11:11 aa
楼主用的是哪个版本的hessian啊  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: