在任何操作系统(包括AIX)的内核中, 都会有很多关于性能的计数器, 例如关于网络的, 可以想象得到的就有下面几个.

1, Input Packets
2, Input Bytes
3, Output Packets
4, Output Bytes

    要监控一个系统的负荷, 网络流量也是一个很重要的因素, 但在AIX中要取得准确的网络流量, 却不容易, 虽然有Perfstat API可以用, 但按照Demo中代码去做时, 发现过二到三分钟就会出现一个异常流量值, 大到天文数字, 很明显是因为内核中的计数器溢出(Overflow)了.

    要解决这个问题, 先要理解为什么那么快会溢出, 假设平均每秒钟的网络流量为30MB, 在AIX 5.3及以前版本的内核计数器还是一个32位的数字, 因此多长时间, 就会溢出呢? 可以用如下计算公式.

(2**32) = 4096M/30M = 136秒

    大约136秒钟就会出现溢出, 这个频率和Demo中报的一致, 因此更确定了是这个原因. 然后看Perfstat函数说明, 发现接口中用的是64位的类型去映谢这个值的.

The perfstat_netinterface_total_t structure contains the following members:

int          number      number of network interfaces
u_longlong_t ipackets    number of packets received on interface
u_longlong_t ibytes      number of bytes received on interface
u_longlong_t ierrors    number of input errors on interface
u_longlong_t opackets    number of packets sent on interface
u_longlong_t obytes      number of bytes sent on interface
u_longlong_t oerrors    number of output errors on interface
u_longlong_t collisions  number of collisions on csma interface

    问题应当出在这个映射这儿, 于是就试试将这个64位值做了以下转换.

int net_obytes1, net_obytes2;
……
net_obytes1 = (int)(netstats.obytes & 0xffffffff);
……
while(1)
{
  sleep(10);
  net_obytes2 = (int)(netstats.obytes & 0xffffffff);
  print(net_obytes2 – net_obytes1);
  net_obytes1 = net_obytes2;
}

    然后改了改oramon程序, 得到了以下的OS信息输出.

www.AnySQL.net  Load SY/WT/US  Net Pgio
02/12-18:29:30  3.55  7/23/20 276M    0
02/12-18:29:40  3.63  8/23/19 374M    0
02/12-18:29:50  3.37  8/22/20 339M    0
02/12-18:30:00  3.39  8/24/19 311M    1
02/12-18:30:10  3.39 10/21/32 366M    2
02/12-18:30:20  3.26  8/25/22 349M    0
02/12-18:30:30  3.44  9/26/21 406M    0
02/12-18:30:40  3.31  7/26/21 185M    0
02/12-18:30:50  3.50  8/23/23 286M    2
02/12-18:31:00  3.63  9/24/22 399M    0

    Perl的Perfstat包也有这个问题, 改天去Fix一下试试了.