• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            twzheng's cppblog

            『站在風口浪尖緊握住鼠標旋轉!』 http://www.cnblogs.com/twzheng

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              136 隨筆 :: 78 文章 :: 353 評論 :: 0 Trackbacks
            [源] http://zhuweisky.cnblogs.com/archive/2006/03/16/351301.html

            凡是帶有“池”的,比如數據庫連接池、對象池、緩沖區池(后面可以看到IBuffPool)等等,都是為了避免資源的反復創建/銷毀所帶來的開銷。需要為哪些資源對象建立“池”了?這些資源對象通常符合下面幾個特性:
            (1)在應用中需要反復的被創建/銷毀。
            (2)創建/銷毀的開銷比較大
            (3)應用中給定時刻,對該資源對象的數量要求比較大
            (4)資源對象最好是無狀態的(Stateless),這樣方便直接復用

                
            AS(回顧
            將所有的功能服務請求轉發給為該AS提供服務的FS群中的一個(參見。。。),然后FS將請求交給對應的功能插件處理。那么ASFS之間的通信通過什么方式進行了?可選的方式有.netRemotingWebServiceTcp/Udp等。基于效率和準確性的考慮,WebServiceUdp是不大合適的。那么TCP.netRemoting,到底選用哪個?我們知道.netRemoting底層也是基于TcpHttp協議的,為了做到模擬本地方法調用的方式,.NETRemoting也做了很多轉換的操作(堆棧幀《=》消息),導致了一些開銷,而直接使用Tcp則可以避免,而且ASFS之間的消息的格式是兼容的(主要是使用了完全相同的消息頭,這就夠了),也就是說一條消息從客戶端發出,可以不需做任何轉換就直接被FS的功能插件處理(加密、壓縮不計在內)。

                
            如你所想,ESFramework推薦的方式是ASFS直接通過低層的Tcp進行通信。為了避免Tcp連接不斷建立、銷毀所帶來的開銷,ASFS通信前,可以建立Tcp連接池。本文就關注Tcp連接池的原理和實現。

               
            Tcp
            連接池中存放的是Tcp連接――即NetworkStream對象,當應用需要使用時,就從Tcp連接池中租借“Rent”一條連接,用完后再歸還“GiveBack”給連接池。
            public class TcpStreamPool :ITcpStreamPool ,ITcpPool

                從上面的定義可以看到TcpStreamPool從兩個接口繼承:ITcpPoolITcpStreamPool。先看看ITcpStreamPool的定義:

             1     /// <summary>
             2     /// ITCPStreamPool tcp連接池用于管理大量的TCP連接
             3     ///  作者:朱偉 sky.zhuwei@163.com  
             4     /// sky 2005.02.24
             5     /// </summary>
             6     public interface ITcpStreamPool 
             7     {        
             8         int         ServerID {get ;set ;}
             9         int            StreamCount           {get ;set ;} //期望連接總數
            10         int            ActiveConnectionCount {get ;} //實際可用的連接數        
            11         IPEndPoint  FsIpe       {get ;set ;} //功能服務器的IPE
            12         int         ReconnectSpan{get ;set ;} // 分鐘     
            13         bool        IsActive{get;}
            14 
            15         void ReConnect() ; //手動重連
            16         void Initialize() ;        
            17         void DisposeConnections() ; //釋放池中所有連接,可以通過ReConnect來重新建立連接        
            18         void SetStreamDamaged(int streamHashCode) ;            
            19 
            20         NetworkStream RentTcpStream() ;    
            21         void GiveBackTcpStream(int streamHashCode) ;//將tcp連接規還給連接池
            22     }    

                AS和每個FS之間都有一個連接池,每個功能服務器的區分是通過ServerID來的,所以連接池也有一個ServerID屬性標志了本連接池是與哪個FS相連的。ReconnectSpan屬性表明連接池要支持重連機制,即當連接池中的所有連接都斷開后(可能是FS掉線引起的),連接池應能定時重連FS,直至該池中的所有連接重新建立。
                如果應用從連接池Rent了一條連接,然后在使用的過程中該連接斷開了,則應用應該調用連接池的SetStreamDamaged方法通知連接池該連接已不可用。RentTcpStream方法和GiveBackTcpStream方法是我們最常用的租借/歸還連接的方法了。
                注意,很多方法的參數中有streamHashCode參數,它是NetworkStream對象的Hashcode,系統中的每個NetworkStream對象的HashCode是不同的,并且,它的HashCodeNetworkStream對象的整個生命期間不變,所以可以使用HashCode唯一標志每個連接。

                似乎,ITcpStreamPool接口已經反映了一個連接池的所有東西,是的。那么ITcpPool接口又起什么作用了?現看看ITcpPool的樣子:

             1 /// <summary>
             2     /// ITcpPool 用于將一個TCP連接池和一組TCP連接池統一起來。這樣消息分派器只需使用ITcpPool接口即可。
             3     /// zhuweisky 
             4     /// </summary>
             5     public interface ITcpPool
             6     {
             7         RentStreamResult RentTcpStream(int poolTypeKey ,int serviceKey ,out NetworkStream stream ,out int serverID) ;//poolTypeKey表示某個城市,serviceKey表示某項服務
             8         void GiveBackTcpStream(int streamHashCode ,int serverID) ;//將tcp連接規還給連接池
             9         void SetStreamDamaged(int streamHashCode ,int serverID) ;//poolKey如果不易保存,則此處簡單的傳-1即可    
            10 
            11         event CallBackCountChanged     ActiveConnectionCountChanged ;     
            12         event CallBackPoolStateChanged PoolStateChanged ;        
            13     }
            14 
            15     public delegate void CallBackCountChanged(int serverID ,int activeConnCount) ;
            16     public delegate void CallBackPoolStateChanged(int serverID ,bool disconnected) ;
            17 
            18     public enum RentStreamResult
            19     {
            20         Succeed ,Busy ,TheServiceNotExist
            21     }

                你可能已經發現,ITcpPool中的所有元素在ITcpStreamPool接口中都可以找到對應物,只是有些方法的參數變復雜了。這主要是因為ITcpStreamPool接口針對的是一個FS,而ITcpPool可能是針對一個FS也可能是一組FS。當ITcpPool背后是一組FS時,就需要參數ServerID來區分每一個FS。我們知道,AS和對應的每個FS之間都使用一個Tcp連接池通信:
             

                所有的這些連接池需要被管理起來,ESFramework中的ITcpPoolsManager連接池管理器)組件實現了對多個Tcp連接池的管理。為了把連接池管理器和單個連接池統一起來,使它們有相同的外部接口,所以引入了ITcpPool接口。
                這樣做的好處是,在應用中直接使用
            ITcpPool接口就可以了,而不用關心這個接口背后是一個“單個連接池”(對應單個FS)還是由連接池管理器管理的“一組連接池”(對應多個FS)。而且ITcpPoolsManager為我們的應用進行了很多復雜的管理,比如動能服務器的調度(實現FS的負載均衡)、連接池的動態添加/移除等。這些將在下文中介紹。

            感謝關注。

            posted on 2007-04-14 22:17 譚文政 閱讀(672) 評論(0)  編輯 收藏 引用 所屬分類: ESFramework
            中文字幕久久亚洲一区| 久久综合九色综合精品| 亚洲精品第一综合99久久| 日韩电影久久久被窝网| 久久久久av无码免费网| 日韩精品久久久久久免费| 久久免费线看线看| 色综合久久88色综合天天 | 久久精品国产亚洲av麻豆图片 | 亚洲七七久久精品中文国产| 婷婷久久五月天| 国产亚洲欧美成人久久片| 久久国产精品免费一区| 久久久亚洲裙底偷窥综合| 国产成人久久激情91| 久久99这里只有精品国产| 久久99精品国产99久久| 久久精品桃花综合| 99久久精品费精品国产| 久久久久亚洲精品天堂| 久久天天躁狠狠躁夜夜av浪潮 | 亚洲国产精品无码久久SM| 国产巨作麻豆欧美亚洲综合久久 | 久久精品草草草| 午夜不卡久久精品无码免费| 久久夜色精品国产亚洲av| 国产69精品久久久久777| 无码专区久久综合久中文字幕 | 欧美久久一级内射wwwwww.| 狠狠久久亚洲欧美专区| 无码国产69精品久久久久网站| 性做久久久久久免费观看| 成人a毛片久久免费播放| 久久婷婷久久一区二区三区| 欧洲精品久久久av无码电影| 久久久久久午夜精品| 精品乱码久久久久久夜夜嗨| 国产精品欧美久久久久天天影视 | 久久综合综合久久狠狠狠97色88| 久久精品麻豆日日躁夜夜躁| 欧洲成人午夜精品无码区久久|