
如果我拥有无限的精度能否精确的反映系统的运行过程呢?有时候也不能做到,因为指标是在环境中采集的,环境本身限制了它的表达。例如在容器中cpu busy的计算是 :
容器运行的时间/总时间
注:实际可能是
CPU.busy = (cpuacct.usage(T秒) - cpuacct.usage(T-5秒))/((5秒)*CPU核数)
如果容器中监控指标CPU.busy=50%就认为系统还处于健康水位就很有可能被误导。在容器超卖(例如64核的物理机分配了总共128核的容器应用)。在所有应用都很繁忙的情况下,容器中的CPU.busy最多只能达到50%就被其它繁忙的容器抢占。物理机CPU利用率可能已经到了100%,而容器的CPU只能到50%。如下图所示:

那如果我在物理机上直接采集机器指标那么是不是就完全准确呢?也不一定,以x86为例,会有一些SMM(System Management Mode)中断,一旦进入了这种中断(一般是温控/ECC检查/电源管理等),Kernel会被强行block,完全感知不到,那么Kernel管理的user/system time都不会有变化。但可能真实时间已经100ms过去了,唯一的感觉可能只有应用的超时报错,但仅仅从Kernel本身的监控完全不知道发生了什么,如下图所示:

笔者就有一次发现线上应用出现报错尖刺,看了所有监控指标都没有异常,但奇怪的是都落在一台宿主机上。最后发现那台宿主机的温度监控值有变化,推断是 SMM在执行温控/电源管理之类的操作。但Kernel完全不知道这段时间发生了什么,user/system time 没有任何记录。 唯一能感知到的就只用应用层的超时报错。