ESFramework介绍之(11)-- Tcp连接池管理器

系统 1477 0
上文 已经讲到, Tcp 连接池管理器为我们的应用进行了很多复杂的管理,比如功能服务器的调度(实现 FS 的负载均衡)、连接池的动态添加 / 移除、控制每个连接池的相关参数在 UI 上的显示等,并且连接池管理器与单个连接池拥有一样的接口 ITcpPool 。我们先回顾一下这个接口:
1 public interface ITcpPool
2 {
3 RentStreamResultRentTcpStream( int poolTypeKey, int serviceKey, out NetworkStreamstream, out int serverID); // poolTypeKey表示某个城市,serviceKey表示某项服务
4 void GiveBackTcpStream( int streamHashCode, int serverID); // 将tcp连接规还给连接池
5 void SetStreamDamaged( int streamHashCode, int serverID); // poolKey如果不易保存,则此处简单的传-1即可
6
7 event CallBackCountChangedActiveConnectionCountChanged;
8 event CallBackPoolStateChangedPoolStateChanged;
9 }
10

RentTcpStream 方法中的 serviceKey 参数反映了这样一个事实:与一个 AS 相连的多个 FS 中,每个 FS 加载的功能插件可以是不一样的。

ESFramework介绍之(11)-- Tcp连接池管理器

比如,上图中的
3 FS 中只有 FS1 加载了前面介绍的“天气预测服务”插件,那么当一个“天气预测服务”请求到达 AS 时, AS 就只能从与 FS1 之间的连接池中 Rent 一个 Tcp 连接,而不是从 FS2 FS3 RentTcpStream 方法的 out 参数 serverID 表明了这条连接是指向哪个 FS 的。

接下来考虑这样一个问题,当一个请求到来,这个请求可以被 FS1 FS2 FS3 处理,那么ITcpPoolsManager 到底返回哪个连接池中的连接了?答案是负载最小的那个 FS 上的连接。
这是怎么做到的了?其实很简单。每个 FS 都定时(比如一秒一次)地把自己的负载( CPU 利用率和内存利用率)通知给 AS ,通知给 AS 的方式可以有多种,比如 .Net Remoting ESFramework 中有一个称为连接池调度器 ITcpPoolScheduler 的东东,它记录了每个 FS 实时的负载。这样当一个请求到来时,连接池管理器ITcpPoolsManager会要求连接池调度器从众多的 FS 中选出一个“满足条件”且负载最小的 FS 。这里的“满足条件”主要指的是对应的 FS 上有能处理该请求的功能插件。实现这种调度需要的支持的各个相互协作的组件的联系图大致如下:

ESFramework介绍之(11)-- Tcp连接池管理器

图中 I ServerPerfo rmanceMonitor 是用于监控本地服务器性能的组件,它可以定时发布本服务器的性能数据(主要是 CPU 利用率和内存利用率),其定义如下:
1 public interface IServerPerformanceMonitor
2 {
3 void Start();
4 void Stop();
5
6 int RefreshSpanSecs{ get ; set ;}
7
8 event CBackServerPerformanceServerPerformanceDataRefreshed;
9 }
11
12 public delegate void CBackServerPerformance(ServerPerformanceperformance);

13 public class ServerPerformance
14 {
15 public float CpuUsagePercent;
16 public float MemoryUsagePercent;
17 }

连接池调度器 ITcpPoolScheduler 的定义如下:

1 public interface ITcpPoolScheduler
2 {
3 // 以下方法属性仅仅由多连接池管理者调用
4 int GetNextTcpPool( int poolTypeKey); // 返回的是某连接池的服务端点的serverID,如果没有可用的返回-1
5 int GetNextTcpPool( int poolTypeKey, int serviceKey);
6
7 void Initialize();
8 void Dispose(); // 还原到未初始化的状态
9 void SetServerState( int serverID, bool activated);
10 void AddServer( int serverID);
11 void RemoveServer( int serverID);
12
13
14 // 以下方法属性由外部指定或调用
15 void SetPerformance( int serverID, float cpuUsage, float memUsage);
16 ITcpPoolHelperTcpPoolHelper{ set ;}
17 }

为了使负载均衡的效果更好, ITcpPoolScheduler 可以实现的非常复杂,比如进行历史记录统计、分析、预测等。 ESFramework 给出了默认实现 TcpPoolScheduler

在组件联系图中还有一个IPoolEndPointsDisplayer 组件,它用于在 UI 上显示每个功能服务器的详细信息和性能数据。

1 public interface IPoolEndPointsDisplayer
2 {
3 void RegisterFs( int serverID, string serverName,IPEndPointipe, int exceptCount);
4 void UnRegisterFs( int serverID);
5 void SetFsState( int serverID, bool activated);
6 void SetActiveCount( int serverID, int activeCount);
7 void UpdateFsPerformance( int serverID, float cpuUsage, float memUsage);
8 void Clear();
9 }


FS 管理器管理连接上本 AS 的每个功能服务器,这将在后文中讲到。
除了 ITcpPool 接口,连接池管理器还实现了 ITcpPoolsManager 接口:

1 public interface ITcpPoolsManager:ITcpPool
2 {
3 string TcpPoolSchedulerTypeString{ set ;} // "ESFramework.Network.TcpPool.TcpPoolScheduler,ESFramework"
4 ArrayListPoolEndPointList{ set ;} // 连接池的服务端PoolEndPointInfo列表
5 int ReconnectSpan{ get ; set ;} // 分钟
6
7 void Initialize(); // 初次建立连接池
8 void Dispose(); // 还原到没有初始化的状态
9 void AddPool(PoolEndPointInfoinfo);
10 void RemovePool( int serverID);
11
12 void DisposePoolConnections( int serverID); // 编号为serverID的服务器已停止,所以释放对应的Pool,但是不删除池,仍然定时重连
13 void ReconnectPool( int serverID); // 曾停止的服务器已启动完毕,所以可以重连了
14
15 /// <summary>
16 /// 可直接使用ESFramework.Network.TcpPool.PoolEndPointsDisplayer
17 /// </summary>
18 IPoolEndPointsDisplayerPoolEndPointsDisplayer{ set ;}
19
20 // 由ITcpPoolScheduler使用
21 void SetPerformance( int serverID, float cpuUsage, float memUsage);
22 ITcpPoolHelperTcpPoolHelper{ set ;} // 可由ESFramework.Architecture.LBS.FourTier.FsManager提供
23 }

AddPool 方法和 RemovePool 方法表明可以动态的添加 / 移除 Tcp 连接池。注意接口中的 SetPerformance 方法,这个方法将被 FS 管理器调用,用于把从 Remoting 接收到的 FS 的性能数据通知给 ITcpPoolsManager ,然后 ITcpPoolsManager 再把这些数据提交给 ITcpPoolScheduler 记录,当需要进行调度的时候, ITcpPoolScheduler 从这些记录中进行分析计算并找到负载最小的 FS TcpPoolSchedulerTypeString 属性用于向连接池管理器提供调度者的实际类型,管理器将会通过反射创建调度者的实例。

还有一个需要设置的属性 ITcpPoolHelper

1 public interface ITcpPoolHelper
2 {
3 bool ContainsService( int serverID, int serviceKey);
4 bool ServerIsTheType( int serverID, int destType);
5 bool ServerIsCompatible( int serverID, int destType, int serviceKey);
6 string GetServerNameByID( int serverID);
7 }

由于这个接口提供了每个功能服务器详细信息,所以这个接口的实现可以直接由前面提到的 FS 管理器顺带实现。

ITcpPoolsManager
是一个比较复杂的组件,它需要涉及到多个组件的协作。所以如果看完这篇文章,仍然还有些不清楚的地方,是很正常的。在后面系列文章的继续讲述中,这些不清晰的地方会慢慢拨开迷雾。

感谢关注!

上篇文章: ESFramework介绍之(10)-- Tcp连接池

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

ESFramework介绍之(11)-- Tcp连接池管理器


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

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

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

【本文对您有帮助就好】

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

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