跳到主要内容

业务线程监控插件

提示

使用场景推荐

  • 线上
  • 开发阶段
  • 性能分析

介绍

ThreadMonitorInOut 是业务线程监控插件,主要的关注点

  • 各业务线程的执行 action 的次数
  • 执行时的平均耗时
  • 当前业务线程积压的任务数量(剩余未执行的任务数量,也就是我们的 action)

开发者可以通过这些数据来分析各线程消费业务情况,根据这些信息适当的增加或减少硬件相关资源, 也可以根据这些信息适当的调整线程相关策略。

从打印预览中可以看到,我们打印了所有线程的相关信息。 总共有 8 个线程(根据机器 cpu 不同对应的线程数量会有不同)。 开发者可以根据当前线程消费的平均耗时,可以大概预测出当前游戏的健康状况。

假设某个线程消费 action 的平均耗时为 100 ms ,而该线程又积压了 50 个任务, 将意味着处理完剩余的任务大约需要花费 100 * 50 = 5000 ms 时间。

通过该插件我们可以得到相关的监控信息,我们可以设置一个阈值,当超过该阈值时, 可以考虑触发通知给相关的开发者(配合上短信、邮件之类的)。

业务线程[RequestMessage-8-1] 共执行了 1 次业务,平均耗时 1 ms, 剩余 91 个任务未执行
业务线程[RequestMessage-8-2] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行
业务线程[RequestMessage-8-3] 共执行了 1 次业务,平均耗时 1 ms, 剩余 36 个任务未执行
业务线程[RequestMessage-8-4] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行
业务线程[RequestMessage-8-5] 共执行了 1 次业务,平均耗时 1 ms, 剩余 88 个任务未执行
业务线程[RequestMessage-8-6] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行
业务线程[RequestMessage-8-7] 共执行了 7 次业务,平均耗时 1 ms, 剩余 56 个任务未执行
业务线程[RequestMessage-8-8] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行

如何使用

@Override
public BarSkeleton createBarSkeleton() {
BarSkeletonBuilder builder = ...;
builder.addInOut(new ThreadMonitorInOut());
...
}

综合示例

通过 ThreadMonitorRegion 对象可以拿监控相关的信息,当项目上线时,通常是不需要打印信息的, 但我们可以配合定时调度把这些数据定期的同步到日志、或 DB、或其他地方中。

下面的示例设置了每 2 分钟检查一次线程相关数据,当超过所设置的 dangerous 值时就发起通知。


代码说明

  • code 10,线程已执行任务的次数
  • code 11,执行任务的平均耗时
  • code 12,当前剩余未执行的任务数
  • code 13,线程名
  • code 14,执行任务的总耗时
  • code 16,当超过该阈值时,可以考虑触发通知给相关的开发者。
var threadMonitorInOut = new ThreadMonitorInOut();
builder.addInOut(threadMonitorInOut);

ThreadMonitorInOut.ThreadMonitorRegion region = threadMonitorInOut.getRegion();

ExecutorKit.newSingleScheduled("Scheduled").scheduleAtFixedRate(() -> {
System.out.println(region);

region.forEach(threadMonitor -> {
LongAdder executeCount = threadMonitor.executeCount();
long avgTime = threadMonitor.getAvgTime();
int countRemaining = threadMonitor.countRemaining();
String name = threadMonitor.name();
LongAdder totalTime = threadMonitor.totalTime();

long dangerous = 8000;
if (avgTime * countRemaining > dangerous) {
// your code
}
});

}, 2, 2, TimeUnit.MINUTES);