abel 发表于 2004-10-13 01:39

給阿骁兄的賀禮二: DNS 流量統計~超強版

其實也稱不上超強版,不過一般人可能較不會往這邊想而以... :mrgreen:
透過修改 bind 的 source code, 利用 rndc 從遠端直接抓出
dns 的query/response 次數,再利用 mrtg 或 rrdtool 來繪圖而以
(註:rndc 不懂的人自己去看,非本處主題)
這是我做的 bind-9.3.0 的 patch file, 有興趣的可拿去看看,如果懂程式
的話,你就會知道不同的版本如何改,如果不懂的話,你就將就用囉!
diff -cr bind-9.3.0/bin/named/query.c bind-9.3.0_abel/bin/named/query.c
*** bind-9.3.0/bin/named/query.c Wed Jun 30 22:13:05 2004
--- bind-9.3.0_abel/bin/named/query.c Wed Oct 13 00:45:07 2004
***************
*** 95,100 ****
--- 95,103 ----
static void
query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype);

+ static int querycount=0;
+ static int replycount=0;
+
/*
   * Increment query statistics counters.
   */
***************
*** 112,121 ****
--- 115,132 ----
zonestats++;
}
}
+ int get_query_count(void) {
+ return(querycount);
+ }
+
+ int get_reply_count(void) {
+ return(replycount);
+ }

static void
query_send(ns_client_t *client) {
dns_statscounter_t counter;
+ replycount++;
if (client->;message->;rcode == dns_rcode_noerror) {
if (ISC_LIST_EMPTY(client->;message->;sections)) {
if (client->;query.isreferral) {
***************
*** 3447,3453 ****
query_error(client, result);
return;
}
!
if (ns_g_server->;log_queries)
log_query(client);

--- 3458,3464 ----
query_error(client, result);
return;
}
! querycount++;
if (ns_g_server->;log_queries)
log_query(client);

diff -cr bind-9.3.0/bin/named/server.c bind-9.3.0_abel/bin/named/server.c
*** bind-9.3.0/bin/named/server.c Fri Jun 18 12:39:48 2004
--- bind-9.3.0_abel/bin/named/server.c Wed Oct 13 00:47:47 2004
***************
*** 3998,4003 ****
--- 3998,4005 ----
n = snprintf((char *)isc_buffer_used(text),
       isc_buffer_availablelength(text),
       "number of zones: %u\n"
+      "number of query: %u\n"
+      "number of reply: %u\n"
       "debug level: %d\n"
       "xfers running: %u\n"
       "xfers deferred: %u\n"
***************
*** 4006,4012 ****
       "recursive clients: %d/%d\n"
       "tcp clients: %d/%d\n"
       "server is up and running",
!      zonecount, ns_g_debuglevel, xferrunning, xferdeferred,
       soaqueries, server->;log_queries ? "ON" : "OFF",
       server->;recursionquota.used, server->;recursionquota.max,
       server->;tcpquota.used, server->;tcpquota.max);
--- 4008,4014 ----
       "recursive clients: %d/%d\n"
       "tcp clients: %d/%d\n"
       "server is up and running",
!      zonecount, get_query_count(), get_reply_count(),ns_g_debuglevel, xferrunning, xferdeferred,
       soaqueries, server->;log_queries ? "ON" : "OFF",
       server->;recursionquota.used, server->;recursionquota.max,
       server->;tcpquota.used, server->;tcpquota.max);
註:Patch 動作請自己做, patch -p1 < this_patch_file,本檔僅適合 9.3.0,沒空每版都寫出來
以上的程式僅是在做 rdnc -s IP_addr status 時,可以帶出如下內容:
# rndc -s 211.72.210.251 status
number of zones: 1
number of query: 157
number of reply: 153
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is ON
recursive clients: 0/1000
tcp clients: 0/100
server is up and running
看到沒有,跟你的有什麼不同, 多了
number of query: 157
number of reply: 153
兩欄,也就是我們加上去的,好了,你每一台機器都做了這樣的 patch 後
並做相同的 rndc.conf 的設定,就可以利用 rndc -s Server_IP status 取
得這樣的結果了,我們可以驗證看看數字到底對不對:


#rndc -s Server_IP stats
# cat /var/named/named.stats
success 137
referral 0
nxrrset 6
nxdomain 10
recursion 142
failure 4

上面數字 success+nxrrset+nxdomain+failure=157 表示 dns 收到了
157 查詢,其中有 142 次做 recursion

不計算 failure 即為成功的查詢次數, 所以為 153

故程式的結果沒有問題 !!
我再寫一個小程式來做字串處理:

#!/usr/bin/perl
open(II,"/usr/local/sbin/rndc -s $ARGV status|");
while (<II>;) {
chomp;
split(/: /,$_);
print "$_\n" if ($_ eq 'number of query' or $_ eq 'number of reply');
}
close(II);

Ex:filename 為 dns_flow.pl
./dns_flow.pl Server_IP
輸出結果為:
157
153


是不是變簡單了呢 !?
你若跑十台 DNS 服務,想來很多人會用 query log 來記 Query 量
這是最不好的方式,因為 Disk I/O 會很多
若你用 rndc stats 來做分折,是可以的,但資料滙整將是一個問題

改程式是終南捷徑(要會改就不是捷徑了)...
每部 DNS Server 再配置相同的 rndc.conf ,即可使用此一 rule
(不同也行,但就會變復雜了,相同的 rndc.conf 只要將一些 rndc
的設定copy 到別台機器即可)

利用 mrtg 來輸出結果:

#for UNIX
WorkDir: /www/html/mrtg
#or for NT
# WorkDir: c:\mrtgdata

### Global Defaults

#to get bits instead of bytes and graphs growing to the right
Options: growright, noinfo



#---------------------------------------------------------------

Target: `/home/abel/dns.pl 你的DNS_Server_IP`
MaxBytes: 2500
Title: A.DNS.TW (IPv6)
Legend1: DNS查詢(次數/秒)
Legend2: DNS回應(次數/秒)
LegendI: DNS查詢
LegendO: DNS回應
YLegend: Q. per second
PageTop: <h1>;DNS_Server Query/Response</h1>;

crontab 那些及 mrtg 設定細節就不再贅述

mrtg 結果:
http://211.72.210.251/dns/
http://211.72.210.251/dns/b-dns-week.png

這次我就不寫 rrdtool 版本了,免得大家望文生畏,我也偷懶一下 :em03:
給阿骁兄的賀禮基本上 google 都是沒有或不足的,有興趣的人可好好研究
一下 :em06:

註: 我直接提供一個修改過的9.3.0版本給大家試試
http://211.72.210.251/bind-9.3.0.tar.gz
若不放心,請記得到 ftp://ftp.isc.org 下也抓一個 9.3.0
來做比較(diff -cr isc_dir abel_dir), 即可知我改了什麼

campoeagle 发表于 2004-10-13 10:53

給阿骁兄的賀禮二: DNS 流量統計~超強版

深奥!

unixli 发表于 2004-10-13 11:20

給阿骁兄的賀禮二: DNS 流量統計~超強版

有时间试试!

abel 发表于 2004-10-13 20:09

給阿骁兄的賀禮二: DNS 流量統計~超強版


+++ Statistics Dump +++ (1097653695)# rndc stats 的時間點
success 2764         #成功得到答案的次數
referral 0           #參考量,這個值是你回應 NS 的次數,也就是當你設成
                #recursion=no 時,你沒有的答案你都會回應 . 的 NS 記錄
                #這個NS回應即稱為 Referral,可以遞歸主機此值為0
nxrrset 15        #nx 意即不存在(Not eXist),rrset 即記錄,不存在的記錄即無此名稱
nxdomain 55        #不存在的網域名稱
recursion 16        #遞歸次數,例如有人詢問 www.chinaunix.com 時,完全沒有 cache 狀況
                #下,你會問 ./com/chinaunix.com 最後得到 www 結果,而此值只算一次
                #也就是一次遞歸查詢,但實際查詢次數為3次去,3次回
failure 0        #查詢失敗,也就是你送出了 Query,但 Server 沒有回應
--- Statistics Dump --- (1097653695)

所以,我們看 DNS 流量統計時:
Client <------->; DNS Server <-------->; gTLD/ccTLD (./.com/.cn)

看的都是 Client 到 DNS 這一段,而較少看 DNS 到 TLD 這一段 (這一段 BIND8 可以做,但
很複雜,BIND 9 他不計算來來回回幾次)

Client<----->; DNS Server 流量計算,標準做法:
收到查詢量=success+referral+nxrrset+nxdomain+failure
送出的回應=success+referral+nxrrset+nxdomain

這是計算方法,但是你會發現,有點費事(其實也不會太費事),你對本機做 rndc stats 時
他們產生 named.stats 檔供你擷取,計算,算出數字後,畫成 mrtg 就不成什麼問題,但是
如果第有二台三台N 台 DNS 呢 ? rndc -s Server_IP stats , 這個 named.stats 是存
在遠端,這對你的處理來說會很費事,當然,你可以用 ssh/ftp/expect... 等去擷取,但無疑
是增加許多複雜度.

你要自己做,一定可以做的出來,需要任何 Patch,唯其工作及日後維護問題而以,我們可以
看到這個例子:
範例檔在這
http://211.72.210.251/named-query-hour.png
http://211.72.210.251/named-query-day.png
你可以將每個值都畫出來,但實際上較具意義的如上所說,唯查詢/回應的數字是我們要注意
的. 故使用 rndc status 對工作簡化有一定幫助:
利用 Patch 做出來的總合效果:
範例檔在這
日流量:
http://211.72.210.251/dns/TLD-day.png
月流量:
http://211.72.210.251/dns/TLD-month.png

我相信做法來看應該簡捷許多

阿骁 发表于 2004-10-13 22:06

給阿骁兄的賀禮二: DNS 流量統計~超強版

收到 abel 兄的第二份大礼,不过明天要出差一趟,周末才能回来,没时间消化啊!

风往南吹 发表于 2004-10-14 09:57

給阿骁兄的賀禮二: DNS 流量統計~超強版

实在太厉害了,打自内心佩服。这几份大礼真的是很有分量,得好好学习学习

skylove 发表于 2004-10-14 11:00

給阿骁兄的賀禮二: DNS 流量統計~超強版

不错,以前一直用mrtg记录服务器的风扇转速,cpu使用,内存使用,网卡使用,以及ftp的使用情况。 不过dns因为我们只提供有限的几个外部查询地址,所以流量一般不太大,所以就没用。另外根据我所知,一些邮件系统也是用它来记录。 其实只要可以把数据整理成2维方式,都可以用mrtg来画图操作——不管用shell,perl,反正输入2维数据就行了。

顶一下,上面的分析过程那里很喜欢!

abel 发表于 2004-10-15 12:01

給阿骁兄的賀禮二: DNS 流量統計~超強版

一般來說,二維的做法都很足夠了,但mrtg 的效率及資源的使用個人是較不
喜歡的,且有時我們需要做一個整體性比較時,幾張二維的圖不如整個合一張
,如此更容易了解彼此關係.



如上面看到的我提供的那張 mrtg 圖,其實這是一部 DNS 主機的流量而以
但我有 N 部要做,我如何知道總合狀況呢 ?

另外,像這張圖,基本上就是台灣這兩年來的DNS流量統計
(ccTLD 部份,.tw),只畫一台或是把七台畫成 七張圖,都難以表現出來
"整體" 的概念:
http://211.72.210.251/dns/TLD-2year.png

這兩年來,我們的 TTL 值都沒有變(這是一個很重要的前提),可以發現
.tw 的 DNS 查詢成長了三倍,不看一台而看整體,更有助於我們日後的
規畫.

skylove 发表于 2004-10-16 13:52

給阿骁兄的賀禮二: DNS 流量統計~超強版

谢谢您的指点,受教了。

看来以后我画每个月的web流量访问图除了用awstat外,还可以用这个来分析每个月“总有那么几天”访问量特别高,or低的的出现时间段了。
然后利用这个分析出的时间段来进行维护等工作,就比较不影响用户了。

再次谢谢abel兄的指点!!

abel 发表于 2004-10-17 00:23

給阿骁兄的賀禮二: DNS 流量統計~超強版

原帖由 "skylove" 发表:
谢谢您的指点,受教了。

看来以后我画每个月的web流量访问图除了用awstat外,还可以用这个来分析每个月“总有那么几天”访问量特别高,or低的的出现时间段了。
然后利用这个分析出的时间段来进行维护等工作,就?.........
這個會不準,除非您將 TTL 設成0,才有意義,不然就設的很小很小,最好小於
15 秒,超過這個值.,大多數的 DNS Query 就不會問到您的 Server 了
因為都被外面的 Cache 了

skylove 兄有興趣,可以試試,將 TTL 值改變一下,以了解不同的 TTL 值對 DNS Query 的影響哦!
Ex: 您現在設為 86400 秒
做個 DNS 流量測試(最好做一星期),再改為 38400,再改為xxx, (每次 /2)
你就會知道,什麼 TTL 值對您來說會取得一個最佳的時間
(您會發現,若這個例子中,TTL 為 X 軸, Query 次數為 Y 軸,它會是一個曲線下降而不是直線下降)
页: [1] 2 3 4 5
查看完整版本: 給阿骁兄的賀禮二: DNS 流量統計~超強版