« 一次足够了 | Main | 优化和架构之服务切分 »

在你自己的软件中应用snmp和agentx协议传递信息

作者:virushuo 发表于 2009-05-08 01:05 最后更新于 2009-05-08 01:05
版权声明:按照by-nc-sa的cc协议可转载,拒绝采用“独家” 授权媒介(含网站和平面媒体)转载、引用、链接,除非获得本人许可。转载时请务必以超链接形式标明文章原始出处和作者信息及本声明。


我曾经想自己写一个udp server来接受我的服务器程序发回来的状态,然后做跟踪和统计。后来被Fenng批评为自己重复造轮子。于是转向试图利用snmp协议来做。

用snmp有几个原因:

1 snmp是基于udp协议的,具有udp的所有好处(数据状态这种东西,用tcp是不合适的)
2 snmp比较成熟,周边的软件非常多,后面可以很方便的处理收集数据,绘图等等一系列的功能。(rrdtool/cacti....)
3 因为我们要监控的服务非常多,所以希望能设计一个尽量免配置的方案,snmp的树型结构正好获取节点下面所有的被监控值。


snmp在网管系统中有很大规模的应用,但是似乎没什么人用来监控软件服务。而,目前我们知道的对snmp和cacti的应用,似乎大部分都只停留在了用来监控服务器状态(mem,load average,net io,disk)上,有点可惜。

在这篇blog里面,我提到的用法应该不是最正宗的,但是有效。其实很多大厂商甚至自己修改snmp协议,做出自己的分支协议来。比起他们,虽然我做的不太正宗,但是也不为过。

我要实现的东西大概可以用这张图来描述:

概括起来:很多个服务分布在很多台机器的很多个端口,所以我们需要在每台机器上放一个snmp代理,得到他们的状态,然后再统一通过snmp协议获取这些状态。由于服务太多了,必须要免于配置,这就更显示出了snmp协议的优点。

扩展snmp有几种方法,不过综合起来,我认为最简单和灵活的还是agentx协议。agentx完全是独立在snmp server之外的,可以一层层的套起来。其他的协议要么要在snmp上加东西,要么要写mib的模块文件,都相当麻烦。

不过,最常用的snmpd,反而对agentx支持不好。至少他们自称还是试验性质,不建议用。我试图在snmpd.conf中允许agentx协议,也几经挫折。最终决定找别的方案。似乎大家都习惯把snmpd当作唯一的snmp server,其实类似产品还有很多,snmpd时间比较久,但我认为并非最好的。在ubuntu的apt源里面,都有几种其他方案可用。

当然,由于我并非希望取得系统的硬件状态,所以我也并不一定要找一个通用的产品。所以最后我决定用jagentx(http://eden.dei.uc.pt/agentx/)。

jagentx实现了snmp v1 协议和agetnx协议,一般来说足够用了。他们网站首页的那张图,很好的说明了agentx方式的系统结构。

jagentx提供了比较友好的api和demo,不过还是有一些bug,我做了一些修改。

1 jagentx的master(相当于server),对于master mib的读取,只能支持snmpwalk,不能支持snmpget。其实是一个状态设置错了。
在 Master_Engine.java中

if (!any_subagent_queried){
int error_index = 1;

int error_status = Pdu.NO_SUCH_NAME;

后面,加上

if(value != null)
{
error_status = Pdu.NO_ERROR;
}
就可以了。

2 是关于session的。如果客户端退出,没有注销,就要等自己的session超时,不然连不上。这个在实际应用中很容易出问题。服务不正常退出的情况发生几率很高。于是我做了一些改动,可以通过sessionid来注销其他进程。这样确实会造成一些安全问题。不过可以用防火墙或是其他方式弥补。总比之前要等超时好。
改动的地方分布在几个文件里面,就不挨个列举了。

本来我给jagentx的开发者发了个邮件,告诉他这些改动,不过被退信了。所以我就把代码放这里,有需要的可以下载

修改了这两处之后,这个东西很就好用了,jagetnx网站上的文档有demo代码,可以参考。

为了让我的山寨服务器正规点,我还是去申请了一个enterprise number。申请的方法是到iana 的申请页面添一张简单的表格,几天之后能收到回复,如果顺利通过,就会分配你一个数字号码,以后这个号码的snmp消息就代表你的组织的了。全部企业的enterprise number可以在http://www.iana.org/assignments/enterprise-numbers 这个页面查到(很大的文本文件)。可以看到,我们的银杏搜索ginkgotek是33364。

所以我们的snmp消息就在1.3.6.1.4.1.33364这个节点下面,我用snmpwalk就可以获得所有节点,包括新增的,这样就达到了免配置的目的。当然,到目前为止,我们还只是自己用于服务监控。


一切就绪之后,就可以选择你喜欢的工具来收集监控数据和画图了。比如常见的cacti。

这里是一张隐去了部分信息的cacti做出来的图。数据是从前面写到的这套东西收集上来的。

总结起来,这种办法适应于:

1 你有一个长期需要稳定运行的服务程序
否则你根本不需要监控

2 该程序有大量实例在运行
否则你用脚本把数据输出到snmpd都可以,没必要和我一样希望免配置

3 你不希望通过http或tcp连接来干扰该程序运行
否则你没必要用udp

写完了这篇blog,我也很希望能够侧面证明ginkgotek在保护客户利益上做的比别人多一些,选择我们的服务是可以放心的。

相关文章:
blog comments powered by Disqus
CC License. Some rights reserved.
署名·非商业用途·保持一致
本站之所有未作特别说明的内容均使用 创作共用协议.
POWERED_BY_MT_3.2