Zabbix源码解析之windows性能计数器performance counter采值问题修正

Zabbix的cpu性能监控对windows的performance counter值的修正处理(以system.cpu.util为例)

问题描述:在使用perf_counter监控项时cpu使用率不定期突然飙高到100%

环境:zabbix agent 4.0+windows

问题分析:

zabbix自身会保持一个counter列表,其中的元素使用zbx_perf_counter_data_t结构体来存储数据,如下图所示,其中的value_array成员是一个循环列表,而rawValues数组用于存储从windows性能计数器获取的原始数据,sum和value_count分别为value_array中存储的值的合计以及个数。这一结构中的数据由zabbix collector进程负责写入和更新,并由agentd进程读取作为最终的cpu性能、硬盘性能等监控项的值。

 

一、Zabbix collector进程计算和更新counter中数据的过程如下:

l 首先,如下图所示,zabbix agent端的collector进程每隔1秒调用一次collect_perfstat函数(也可能同时调用zbx_procstat_collect函数);

l 然后,collect_perfstat函数负责从windows系统的performance counter中收集数据。如下图所示,collect_perfstat会调用zbx_PdhGetRawCounterValue函数和PdhCalculateCounterFromRawValue函数来获取并计算每一个counter的rawValues、sum、value_count成员的值。对于那些处于notsupported状态的counter,该函数会每隔10分钟进行一次检查,并激活或者添加counter。

 

二、Zabbix agentd进程会通过两类监控项来读取counter结构中的数据,一个是perf_counter,另一个是以system.cpu.util为代表的system类监控项,如下图所示。

perf_counter在执行时实际所使用的函数为PERF_COUNTER,该函数最终调用get_perf_counter_value_by_path函数进行实际计算。下图为其计算过程代码,具体步骤为:

  • 获取counter列表访问锁,从当前counter列表中查找到符合条件的counter,并扩展该counter的interval;
  • 然后计算该counter中的数据的平均值(使用compute_average_value函数)作为结果;
  • 如果没有找到符合条件的counter,则添加counter,并调用calculate_counter_value函数进行计算;
  • 释放counter列表锁,调用calculate_counter_value函数计算最近1秒的性能数据,并对value结果赋值。

system.cpu.util 在执行时实际所使用的函数为SYSTEM_CPU_UTIL,该函数最终调用get_perf_counter_value函数对监控项进行计算。get_perf_counter_value函数也会尝试从counter中获取数据然后计算平均值并返回。但是,与perf_counter不同的是,当从counter获取数据失败时(counter不存在,或者状态不是active),get_perf_counter_value函数会直接返回错误,而不会添加counter并重算。

总之,当我们采集cpu的一分钟平均使用率时,perf_counter监控项在特定情况下会以一秒钟的cpu使用率作为返回结果,而在一秒钟这样的短周期内cpu使用率很可能达到100%。而system.cpu.util不会使用一秒的cpu使用率作为返回结果,因此更加可靠。

 

发布了14 篇原创文章 · 获赞 2 · 访问量 2135

猜你喜欢

转载自blog.csdn.net/mcmoo/article/details/103438671