ESFramework 开发手册(12) -- 服务端性能诊断
基于ESFramework构建的系统的服务端,如果在运行时遇到性能问题或某些故障时,可以开启ESFramework服务端引擎的诊断功能。 诊断功能开启后,ESFramework将自动跟踪每种类型消息的处理情况,您可以将这些信息定时记录到日志,之后通过分析日志,就可以很快发现问题所在。
针对 ESFramework 开发手册(11) -- 服务端信息处理模型 中提到的两种信息处理模型,诊断功能都是可以使用的。
一. 开启诊断功能
在 IRapidServerEngine初始化(Initialize方法)之前,将其Advanced属性的DiagnosticsEnabled设置为true,即可开启诊断。
rapidServerEngine.Advanced.DiagnosticsEnabled = true;
开启诊断功能后的服务端在运行时,会额外消耗一点CPU和内存,以跟踪和记录诊断信息。
二. 查看诊断信息
通过IRapidServerEngine的Advanced属性的DiagnosticsViewer,就可以得到诊断查看器(IDiagnosticsViewer)的引用,其定义如下:
public interface IDiagnosticsViewer { /// <summary> /// 获取自定义信息处理的统计数据。 /// </summary> List<InfoHandleRecordStatistics> GetCustomizeInfoStatistics(); /// <summary> /// 获取处理尚未完成的自定义信息。 /// </summary> List<InfoHandleRecord> GetUncommittedCustomizeInfos(); /// <summary> /// 获取线程池信息。 /// </summary> ThreadPoolInfo GetThreadPoolInfo(); }
IDiagnosticsViewer 提供了三个方法,用于获取3种信息:
1.GetThreadPoolInfo
GetThreadPoolInfo 用于获取线程池的信息,如设定的最大的工作者线程数/IOCP线程数,当前可用的工作者线程数/IOCP线程数。
2.GetCustomizeInfoStatistics
GetCustomizeInfoStatistics 用于获取已处理的信息的相关情况。在其返回的List中,针对每种消息类型(informationType)都有一个统计。即,List中的每个元素都对应于一种消息类型的统计。List中的元素类型为InfoHandleRecordStatistics,其类图如下:
InfoHandleRecordStatistics有5个属性,分别解释如下:
(1)InformationType:被统计的信息类型,比如我们用户自定义的消息类型,如用101表示Chat聊天消息类型。
(2)InformationStyle:信息的风格,比如信息是来自客户端ICustomizeOutter的Send调用,还是Query调用。
(3)CallCount:自服务端启动以来,收到这种类型的信息的总个数。
(4)ExceptionCount:处理这种类型的信息时抛出异常的个数(如果类似在实现HandleInformation方法时,没有捕获异常,则其抛出的异常将被框架捕获,并记录在此)。
(5)LastRecords:记录了这种类型的最近10条消息的详细处理情况。这个属性至关重要。其集合中的对象是InfoHandleRecord类型,每一个元素对应一条信息处理记录。
通过其类图可以看到,InfoHandleRecord其有5个属性。其中的InformationType与InformationStyle与上述的InfoHandleRecordStatistics的同名属性是一致的。
ID是框架为收到的每个信息分配的唯一标志。重点注意其StartTime和TimeSpent属性。
StartTime 是服务端处理信息的开始时间。TimeSpent是处理信息的耗时(毫秒)。
通过观察TimeSpent,就可以知道哪些信息的处理花费了过多的时间。然后,通过InformationType的值,在程序中找到对应的代码进行分析。
3.GetUncommittedCustomizeInfos
GetUncommittedCustomizeInfos方法用于获取此刻正在处理中的那些信息,其返回的集合中的对象类型仍然是InfoHandleRecord。
对于尚未处理完成的信息而言,InfoHandleRecord的TimeSpent属性尚未被赋值(默认为0),所以需要特别关注的是其StartTime属性的值与当前时刻的差值。
通过查看GetUncommittedCustomizeInfos方法的返回结果,可以很容易发现那些在处理过程中一直卡住或卡死的信息。
三 .诊断日志记录器
当开启服务端的诊断功能后,通常,我们需要定时记录诊断日志。比如,每隔10秒就调用一次IDiagnosticsViewer的方法,并将得到的诊断信息记录到日志文件中。
ESFramework.Boost 类库(源码开放)提供了DignosticLogger类,用于完成这一目的,二次开发者不用再重复实现了,可以将其直接拿去用。DignosticLogger的构造函数有是三个参数:
public DignosticLogger(IDiagnosticsViewer viewer ,string logFilePath, int logSpanInSecs)
第一个参数就是我们前面讲到的诊断查看器IDiagnosticsViewer,第二个参数logFilePath为日志文件的路径,第三个参数logSpanInSecs是每隔多少秒记录一次。
以下是使用DignosticLogger记录的诊断日志的一个片段:
下一篇:ESFramework 开发手册(13) -- ESFramework 二次开发说明
上一篇:ESFramework 开发手册(11) -- 服务端信息处理模型
-----------------------------------------------------------------------------------------------------------------------------------------------
Q Q:168757008