ESFramework介绍之(10)-- Tcp连接池

系统 1886 0

凡是带有“池”的,比如数据库连接池、对象池、缓冲区池(后面可以看到 IBuffPool )等等,都是为了避免资源的反复创建 / 销毁所带来的开销。需要为哪些资源对象建立“池”了?这些资源对象通常符合下面几个特性:
(1) 在应用中需要反复的被创建 / 销毁。
(2) 创建 / 销毁的开销比较大
(3) 应用中给定时刻,对该资源对象的数量要求比较大
(4) 资源对象最好是无状态的( Stateless ),这样方便直接复用

AS( 回顾
将所有的功能服务请求转发给为该 AS 提供服务的 FS 群中的一个(参见。。。),然后 FS 将请求交给对应的功能插件处理。那么 AS FS 之间的通信通过什么方式进行了?可选的方式有 .netRemoting WebService Tcp/Udp 等。基于效率和准确性的考虑, WebService Udp 是不大合适的。那么 TCP .netRemoting ,到底选用哪个?我们知道 .netRemoting 底层也是基于 Tcp Http 协议的,为了做到模拟本地方法调用的方式, .NETRemoting 也做了很多转换的操作(堆栈帧《=》消息),导致了一些开销,而直接使用 Tcp 则可以避免,而且 AS FS 之间的消息的格式是兼容的(主要是使用了完全相同的消息头,这就够了),也就是说一条消息从客户端发出,可以不需做任何转换就直接被 FS 的功能插件处理(加密、压缩不计在内)。

如你所想, ESFramework 推荐的方式是 AS FS 直接通过低层的 Tcp 进行通信。为了避免 Tcp 连接不断建立、销毁所带来的开销, AS FS 通信前,可以建立 Tcp 连接池。本文就关注 Tcp 连接池的原理和实现。

Tcp
连接池中存放的是 Tcp 连接――即 NetworkStream 对象,当应用需要使用时,就从 Tcp 连接池中租借“ Rent ”一条连接,用完后再归还“ GiveBack ”给连接池。

public class TcpStreamPool:ITcpStreamPool,ITcpPool

从上面的定义 可以看到 TcpStreamPool 从两个接口继承: ITcpPool ITcpStreamPool 。先看看 ITcpStreamPool 的定义:
1 /// <summary>
2 /// ITCPStreamPooltcp连接池用于管理大量的TCP连接
3 /// 作者:朱伟sky.zhuwei@163.com
4 /// sky2005.02.24
5 /// </summary>
6 public interface ITcpStreamPool
7 {
8 int ServerID{ get ; set ;}
9 int StreamCount{ get ; set ;} // 期望连接总数
10 int ActiveConnectionCount{ get ;} // 实际可用的连接数
11 IPEndPointFsIpe{ 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 NetworkStreamRentTcpStream();
21 void GiveBackTcpStream( int streamHashCode); // 将tcp连接规还给连接池
22 }

AS 和每个 FS 之间都有一个连接池,每个功能服务器的区分是通过 ServerID 来的,所以连接池也有一个 ServerID 属性标志了本连接池是与哪个 FS 相连的。 ReconnectSpan 属性表明连接池要支持重连机制,即当连接池中的所有连接都断开后(可能是 FS 掉线引起的),连接池应能定时重连 FS ,直至该池中的所有连接重新建立。
如果应用从连接池 Rent 了一条连接,然后在使用的过程中该连接断开了,则应用应该调用连接池的 SetStreamDamaged 方法通知连接池该连接已不可用。 RentTcpStream 方法和 GiveBackTcpStream 方法是我们最常用的租借 / 归还连接的方法了。
注意,很多方法的参数中有 streamHashCode 参数,它是 NetworkStream 对象的 Hashcode ,系统中的每个 NetworkStream 对象的 HashCode 是不同的,并且,它的 HashCode NetworkStream 对象的整个生命期间不变,所以可以使用 HashCode 唯一标志每个连接。

似乎, ITcpStreamPool 接口已经反映了一个连接池的所有东西,是的。那么 ITcpPool 接口又起什么作用了?现看看 ITcpPool 的样子:

1 /// <summary>
2 /// ITcpPool用于将一个TCP连接池和一组TCP连接池统一起来。这样消息分派器只需使用ITcpPool接口即可。
3 /// zhuweisky
4 /// </summary>
5 public interface ITcpPool
6 {
7 RentStreamResultRentTcpStream( int poolTypeKey, int serviceKey, out NetworkStreamstream, 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 CallBackCountChangedActiveConnectionCountChanged;
12 event CallBackPoolStateChangedPoolStateChanged;
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介绍之(10)-- Tcp连接池

所有的这些连接池需要被管理起来, ESFramework 中的 ITcpPoolsManager 连接池管理器)组件实现了对多个 Tcp 连接池的管理。为了把连接池管理器和单个连接池统一起来,使它们有相同的外部接口,所以引入了 ITcpPool 接口。
这样做的好处是,在应用中直接使用
ITcpPool 接口就可以了,而不用关心这个接口背后是一个“单个连接池”(对应单个 FS )还是由连接池管理器管理的“一组连接池”(对应多个 FS )。而且 ITcpPoolsManager 为我们的应用进行了很多复杂的管理,比如动能服务器的调度(实现 FS 的负载均衡)、连接池的动态添加 / 移除等。这些将在下文中介绍。

下一篇文章:ESFramework介绍之(11)-- Tcp连接池管理器

上一篇文章: ESFramework介绍之(6)―― 基于C/S的4层架构概述

转到: ESFramework 可复用的通信框架(序)

ESFramework介绍之(10)-- Tcp连接池


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论