于吉吉的技術博客

          建造高性能門戶網

            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 陳于喆 閱讀(12039) 評論(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啊  回復  更多評論
            

          主站蜘蛛池模板: 尚义县| 嘉祥县| 全州县| 土默特右旗| 连平县| 长丰县| 漠河县| 庆云县| 长沙县| 苗栗市| 宜州市| 昭觉县| 夏津县| 方山县| 彭州市| 云安县| 嘉禾县| 积石山| 兴业县| 浮山县| 从江县| 昔阳县| 金阳县| 忻州市| 德安县| 黔南| 安泽县| 德庆县| 凭祥市| 积石山| 赤城县| 汉中市| 克什克腾旗| 四川省| 嘉禾县| 蒙阴县| 庄河市| 阿克| 华容县| 二连浩特市| 朝阳区|