轉(zhuǎn)自: http://tech.it168.com/a2016/1025/2993/000002993954.shtml
【IT168 技術(shù)】目前在做一個(gè)對(duì)物理機(jī)的性能指標(biāo)監(jiān)控的項(xiàng)目。在業(yè)內(nèi)實(shí)現(xiàn)方式主要有如下兩種方案:
1、在物理機(jī)中部署agent程序,實(shí)現(xiàn)對(duì)數(shù)據(jù)指標(biāo)的采集。此方案在采集數(shù)據(jù)和容錯(cuò)處理上都比較簡單,而且由于agent分布在不同的物理機(jī)上,天生的就避免了集中式采集所造成的性能問題。采用agent方式的缺點(diǎn)是在項(xiàng)目上線進(jìn)行實(shí)施部署時(shí)會(huì)存在較大的工作量,因?yàn)樾枰獙?duì)所有的物理機(jī)進(jìn)行agent的安裝部署。并且一旦agent程序被有意無意的停掉,將獲取不到數(shù)據(jù)。
2、通過遠(yuǎn)程訪問的方式獲取物理機(jī)的連接,運(yùn)行操作系統(tǒng)指令獲取數(shù)據(jù)指標(biāo)。此方案不需要安裝agent程序,實(shí)施工作量小,但是由于使用的是遠(yuǎn)程交互的方式,不太容易進(jìn)行錯(cuò)誤處理,一旦出現(xiàn)操作系統(tǒng)命令運(yùn)行阻塞,而且采集程序沒有及時(shí)發(fā)現(xiàn),接踵而來的是大量的操作系統(tǒng)命令阻塞,會(huì)存在導(dǎo)致物理機(jī)宕機(jī)的風(fēng)險(xiǎn)。另外一方面當(dāng)采集成百上千的物理機(jī)數(shù)據(jù)時(shí),一定要考慮分布式采集。
在開發(fā)過程中發(fā)現(xiàn)了collectd開源框架,下面將從以下幾方面對(duì)collectd進(jìn)行介紹:
1、collectd介紹
2、collectd的基本安裝配置
3、collectd插件編寫
collectd介紹
collectd是一個(gè)守護(hù)進(jìn)程,由c語言實(shí)現(xiàn),用來收集系統(tǒng)信息,可以通過多種方式使其可用(文件、網(wǎng)絡(luò)等)。守護(hù)進(jìn)程本身只有給插件載入、查詢和提交的功能,除此之外沒做其他事情,數(shù)據(jù)的采集和獲取都是通過插件進(jìn)行。collectd支持多種插件,主要分為read類型的插件和write類型的插件。Read類型的插件就是用于讀取監(jiān)控項(xiàng)的指標(biāo)的插件。write類型的插件就是將獲取到的值寫入文件、數(shù)據(jù)庫、緩存等介質(zhì)中。目前collectd可以應(yīng)用在 Linux,Solaris,Mac OS X,AIX,F(xiàn)reeBSD,NetBSD 和 OpenBSD 等常見的操作系統(tǒng)中。

上圖為collectd的架構(gòu)圖,圖中可以看到collectd進(jìn)程通過和各種插件交互完成對(duì)數(shù)據(jù)的采集。
collectd基本安裝配置
下面簡要介紹Collectd的安裝配置。將要以Centos7.X操作系統(tǒng)為例進(jìn)行介紹。在服務(wù)器聯(lián)網(wǎng)的情況下,可以通過Yum進(jìn)行安裝,過程如下:
1、安裝collectd軟件
# yum install epel-release
# yum install collectd
2、啟動(dòng)collectd服務(wù),并且設(shè)置開機(jī)啟動(dòng)
# systemctl start collectd
# systemctl enable collectd
根據(jù)以上命令collectd已經(jīng)成功的安裝到服務(wù)器上,并且配置了開機(jī)自啟動(dòng)。
另外服務(wù)的停止命令和重啟命令分別為:
# systemctl stop collectd
# systemctl restart collectd
4 、修改collectd的配置文件
collectd的插件都需要在collectd.conf文件中進(jìn)行開啟和關(guān)閉。例如,可以將”LoadPlugin cpu”前的 “#”號(hào)去掉,用于啟動(dòng)cpu的read監(jiān)控。

collectd有自己的類型,都存儲(chǔ)在Types.db中,文件內(nèi)容如下。

其中第一列為類型的名稱;第二列為對(duì)類型的描述(包括:GAUGE,DERIVE,COUNTER,ABSOLUTE),由四列組成,分別為數(shù)據(jù)源名、類型、最小值和最大值組成,中間以冒號(hào)”:”進(jìn)行分隔。U表示沒有定義,意思就是沒有范圍。用戶可以根據(jù)需要定義自己的collectd的類型,以方便理解。
我們可以定義從名稱上容易理解的類型。實(shí)現(xiàn)方式是在文件types.db中添加自己定義的類型,或者自定義mytypes.db文件。如 :

1、加入如下信息:test value:GAUGE:0:U
2、然后修改collectd.conf啟用自定義的mytypes.db文件
這樣就成功添加了一個(gè)自定義的類型 test。
collectd插件編寫
collectd實(shí)現(xiàn)了常見的指標(biāo)的監(jiān)控。但是在實(shí)際的項(xiàng)目中collectd已經(jīng)提供了的插件明顯是不夠的,這樣就需要開發(fā)自己的read插件,來實(shí)現(xiàn)對(duì)更多的指標(biāo)的數(shù)據(jù)采集。另外在實(shí)現(xiàn)自己的項(xiàng)目時(shí),總是希望采集得到的數(shù)據(jù)能夠存入自定義的數(shù)據(jù)存儲(chǔ)中,這時(shí)就需要自己實(shí)現(xiàn) write插件,將獲取到的數(shù)據(jù)按照要求插入自己的數(shù)據(jù)存儲(chǔ)中。
collectd 支持各種自定義擴(kuò)展,C-plugins,Perl-plugins,Java-plugins,Python-plugins,UNIX 域套接字,Java 的 MBean 的支持等。這樣就允許通過python或者java等程序?qū)崿F(xiàn)read和write的插件。下面通過一個(gè)簡單的例子介紹一下使用python語言開發(fā)自己的read插件和write插件。
1) 在配置文件中啟用插件
首先需要對(duì)配置文件進(jìn)行修改,將python插件進(jìn)行啟用,以保證由python開發(fā)的插件的程序可用。

配置插件,在此處我們配置插件的路徑為”/root”,并通過Import將寫好的test.py模塊進(jìn)行進(jìn)行加載。如果有多個(gè)模塊可以調(diào)用多個(gè)Import。然后配置<Module>模塊,模塊名和Import相對(duì)應(yīng)。在<Module>模塊中可以根據(jù)插件的需要配置自己的參數(shù),在此處為了看效果隨便配置了參數(shù)t和Interval。

2)開發(fā)自己的python程序。
創(chuàng)建test.py文件,并且放到”/root”路徑下。在test.py文件中引入collectd模塊。collectd提供了基本的方法用于注冊(cè)自己插件的配置加載函數(shù)、數(shù)據(jù)讀取函數(shù)和數(shù)據(jù)寫函數(shù)。

以上三個(gè)方法的參數(shù)最重要的都是一個(gè)回調(diào)函數(shù),分別用于讀取配置文件、采集監(jiān)控?cái)?shù)據(jù)和處理獲取的監(jiān)控?cái)?shù)據(jù)。
1、配置文件回調(diào)函數(shù)
def configure_callback(conf=None):
pass
os.system("echo '"+str(conf)+"'>>/tmp/config.log")
try:
for c in conf.children:
os.system("echo '"+ str(c.values[0])+"'>>/tmp/config.log")
except Exception ,e:
os.system("echo '"+e+"'>>/tmp/config.log")
finally:
pass
1中首先創(chuàng)建讀取配置的函數(shù)。它的作用是讀取collectd.conf文件中的配置,對(duì)應(yīng)的就是上面配置的module,t,Interval。為了能夠看到效果,我們將獲取到的配置信息寫入到config.log文件中。
2是創(chuàng)建的監(jiān)控的讀回調(diào)函數(shù)。在此處定義了一個(gè)getTestValue函數(shù),返回了數(shù)字123(在真實(shí)的系統(tǒng)中,需要根據(jù)自己需要去獲取數(shù)據(jù))。然后定義了讀回調(diào)函數(shù)read_callback,設(shè)置了類型為自定義的類型“test”,接著設(shè)置了其它的參數(shù),最后調(diào)用dispatch方法,發(fā)送獲取的結(jié)果,給write插件讀取。
其中type為上文中自定義的類型,也可以為在types.db中定義的其它類型。
2、讀回調(diào)函數(shù)
def getTestValue():
return 123
def read_callback():
type = "test"
val = collectd.Values(type)
val.plugin = "test"
val.host = "127.0.0.1"
val.type_instance = "test_instance"
val.interval = 30
val.values = [getTestValue()]
val.dispatch()
創(chuàng)建”寫”回調(diào)函數(shù),為了能夠看到效果,我們將數(shù)據(jù)寫 到write.log文件中。在實(shí)際的項(xiàng)目中,可以在此處加入自己的邏輯,將數(shù)據(jù)寫入數(shù)據(jù)庫,緩存等自己需要的介質(zhì)中,以達(dá)到和項(xiàng)目集成的目的。
3、寫回調(diào)函數(shù)
def write_callback(data=None):
os.system("echo '"+str(data)+"'>>/tmp/write.log")
4中是將自己實(shí)現(xiàn)的回調(diào)函數(shù)注冊(cè)到collectd中,使其生效。
4、注冊(cè)回調(diào)函數(shù)
collectd.register_config(configure_callback)
collectd.register_read(read_callback)
collectd.register_write(write_callback)
重啟服務(wù),將會(huì)在/tmp路徑下看到config.log 和 write.log。其中config.log中將會(huì)讀取 t 和 Interval參數(shù),而在write.log中將會(huì)看到test類型 值為123的數(shù)據(jù)。
根據(jù)以上例子我們只是將獲取的結(jié)果記錄到了臨時(shí)文件中,當(dāng)然在和真實(shí)的項(xiàng)目集成時(shí),我們也可以將結(jié)果寫入數(shù)據(jù)庫,緩存等自己需要的存儲(chǔ)介質(zhì)中。
總結(jié)
使用collectd的開源采集框架,是一個(gè)比較好的選擇。collectd實(shí)際上屬于Agent的采集方式,并且 collected已經(jīng)提供了很多常見的采集指標(biāo),如CPU,內(nèi)存等等,不僅能夠減少開發(fā)的工作量,collectd還提供了更加靈活穩(wěn)定的框架,支持自定義插件用于采集滿足需求的數(shù)據(jù)。