自己最近一直在整理
C
++写的采集器代码,主要两个方面的改动:
- 程序易于扩展
- 性能调优
感慨设计无止境,现将设计的修改列在如下,全当总结或设计不全的教训。
一、原始设计
工作多年,知道设计的重要性,我在设计上下了很大的功夫,当时设计就考虑到采集器需要收集不同设备厂家不同型号的设备数据。于是,我使用
xml
配置文件记录采集的
snmp oid
:如
<CURRATTAINABLERATEUP type="oid" value="1.3.6.1.2.1.10.94.1.1.3.1.8.a_ifIndex" />
其中
a_ifIndex
是采集对应端口的
ifIndex
,而对应的
ifIndex
的取值又通过同一个配置文件的得到如:
<a_ifIndex name="a_ifIndex" type="condition" value="1.3.6.1.2.1.2.2.1.1.?">
<condition name="ifDescr" type="like" value="1.3.6.1.2.1.2.2.1.2.?" like="Adsl?/?/?">ifDescr</condition>
</a_ifIndex>
<condition name="ifDescr" type="like" value="1.3.6.1.2.1.2.2.1.2.?" like="Adsl?/?/?">ifDescr</condition>
</a_ifIndex>
我使用了类似的正则表达式的规则,使用
like
操作通过读取
ifDescr
的值来计算
ifindex
的值。
由于上层需要的值并不一定是底层采集的值,需要进行一定的逻辑运算或数学运算,于是有了诸如:
- transfer
- compute
- condition
- append
- avg
- sum
- plus
通过对
oid
值和一些常量的逻辑运算来得到上层的值。这样的设计使的程序可以依赖这些逻辑运算来做任意组合计算的值。例如新添加一个采集项,只需修改配置的文件,增加一个有一定运算的任务,而无需改动任何代码。易用性和扩展性得到很大的提供。
二、
一次性能调优导致的设计变动
由于采集设备的指标很多,有近
70
个,而且各个指标都有一个以上的
oid
值的采集。开始程序是一个指标和设备通讯一次,采集需要的数据,断开连接。这样耗时较大,所以在现场使用的过程中进行优化,考虑大部分的操作时
snmp get
,而且
snmp get
一次可以得到多个
oid
的值,所以引入了一个
snmp
缓存类,记录所有需要采集的
oid
的值,通过几次
get
操作就可以得到所有的
oid
的值,然后,再对每个指标读取
snmp
缓存
oid
值,计算得到上层所需要的值。这样效率得到极大的提高,所花的时间也变成原来的
10
分之一。
三、
支持特殊情况的设计变动
对于不同的设备,其
ifindex
的取值是不一样的,同时一些设备的私有
mib
计算不能或很难通过运算法则来计算得到,所以就需要用提供一种很方便的插入具体的代码(类似于逻辑运算)来计算上面的提到的值,当前的设计是提供一个接口,每次当有新的指标需要额外处理的指标的话,就继承这个接口,实现对应的方法,这样只在程序中加入
if(type == "new operator type "),
然后调入方法即可,其实这步都可以省的,使用动态创建的技术,但是考虑到那样做要使用新技术,而且增加程序的易读性,目前先这样。