案例十三:监控CDN各节点是否正常

案例十三:监控CDN各节点是否正常

我想大家对CDN并不陌生,它可以提升用户对网站访问的体验。CDN通常在全国各个城市甚至是国外都部署了节点,这样用户可以就近选择访问的节点,无论是在响应上还是在带宽消耗上都会有不错的表现。但反过来说,既然节点多了,那么某个节点出现问题的可能性就大了。本案例的需求是,监控CDN各个节点,看其是否正常。具体要求如下:

1)提供一个所有CDN节点IP的文本(/data/cdn_ip.list)

2)提供一个监控链接地址(http://www.aminglinux.com/test.php)

3)要对比节点和源站的访问结果是否一致(源节点IP为:88.88.88.88)

4)当某个节点出问题时,需要发告警邮件给[email protected]

5)每分钟执行一次脚本,告警需要做收敛,即当发现节点有故障后,立即告警,如果故障一直存在则下次告警需要在30分钟之后

6)本脚本不用考虑源站不正常的情况,即源站一定是正常的

知识点一:curl命令使用

Curl是一个访问http资源的命令行工具,我经常使用curl来测试web服务器。curl命令后面直接跟网站链接,会把访问到的内容(如,html页面)显示在当前的终端下,用法如下:

 

# curl www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&;tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a>  <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号  <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

 

curl命令非常实用,而且用法很多,以下是curl的几个常见用法:

1)用curl下载文件

# curl -O http://www.apelearn.com/src/images/20170515/logo.png

用-O(大写的字母O)可以直接把logo.png下载到当前目录下,也可以使用-o(小写字母o)更改下载的文件名字,如下:

# curl -o a.png http://www.apelearn.com/src/images/20170515/logo.png

2)查看header信息

 

# curl -I http://www.apelearn.com/src/images/20170515/logo.png  //其中第一行中有一个很关键的指标,就是那个200状态码,我们可以通过这个状态码判断该url是否正常
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Thu, 18 Oct 2018 02:30:46 GMT
Content-Type: image/png
Content-Length: 4803
Connection: keep-alive
Last-Modified: Wed, 22 Nov 2017 09:11:45 GMT
ETag: "5a153f51-12c3"
Expires: Sat, 17 Nov 2018 02:30:46 GMT
Cache-Control: max-age=2592000
Accept-Ranges: bytes

 

3)指定代理服务器

# curl -x127.0.0.1:80  http://www.apelearn.com/src/images/20170515/logo.png

说明:-x后面跟的IP:Port为代理服务器的IP和Port,有时候我们为了测试某个服务器上的网站,可以用-x指定该服务器IP,也就是说这个IP不一定就是代理服务器,也可以是web服务器本身,它的作用类似于在DNS中将该域名解析到了这个IP上。除了-x选项外,还有一种方法也可以实现类似的效果,示例如下:

# curl -H "Host:www.apelearn.com' http://127.0.0.1/test.php

这样相当于是在127.0.0.1这台机器上访问http://www.apelearn.com/test.php。

4)自定义referer

# curl -e "http://www.baidu.com/1.txt" http://www.apelearn.com/test.php

5)自定义user_agent

# curl -A "This is a test user_agent." http://www.apelearn.com/test.php

6)指定超时时间

# curl --connect-timeout 2 http://www.abc.com/123.html  //如果在2秒未访问到结果,则指令结束

本案例参考脚本

 

#!/bin/bash
#监控CDN节点
#作者:阿铭
#日期:2018-10-18
url="http://www.aminglinux.com/test.php"
s_ip="88.88.88.88"
ipf="/data/cdn_ip.list"
[email protected]
#检查是否有curl命令
if ! which curl &>/dev/null
then
    yum install -y curl
fi
mycurl()
{
    curl  --connect-timeout 2 -x$1:80 $url  2>/dev/null
}
#定义告警函数(这里的mail.py是案例二中那个脚本)
m_mail() {
    log=$1
    t_s=`date +%s`
    t_s2=`date -d "1 hours ago" +%s`
    if [ ! -f /tmp/$log ]
    then
        #创建$log文件
        touch /tmp/$log 
        #增加a权限,只允许追加内容,不允许更改或删除
        chattr +a /tmp/$log
        #第一次告警,可以直接写入1小时以前的时间戳
        echo $t_s2 >> /tmp/$log
    fi
    #无论$log文件是否是刚刚创建,都需要查看最后一行的时间戳
    t_s2=`tail -1 /tmp/$log|awk '{print $1}'`
    #取出最后一行即上次告警的时间戳后,立即写入当前的时间戳
    echo $t_s>>/tmp/$log
    #取两次时间戳差值
    v=$[$t_s-$t_s2]
    #如果差值超过1800,立即发邮件
    if [ $v -gt 1800 ]
    then
        #发邮件,其中$2为mail函数的第二个参数,这里为一个文件
        python mail.py $mail_user "节点$1异常" "`cat $2`"  2>/dev/null   
        #定义计数器临时文件,并写入0        
        echo "0" > /tmp/$log.count
    else
        #如果计数器临时文件不存在,需要创建并写入0
        if [ ! -f /tmp/$log.count ]
        then
            echo "0" > /tmp/$log.count
        fi
        nu=`cat /tmp/$log.count`
        #30分钟内每发生1次告警,计数器加1
        nu2=$[$nu+1]
        echo $nu2>/tmp/$log.count
        #当告警次数超过30次,需要再次发邮件
        if [ $nu2 -gt 30 ]
        then
             python mail.py $mail_user "节点$1异常持续30分钟了" "`cat $2`" 2>/dev/null  
             #第二次告警后,将计数器再次从0开始          
             echo "0" > /tmp/$log.count
        fi
    fi
}
mycurl $s_ip >/tmp/s.html
for ip in `cat $ipf`
do
    mycurl $ip >/tmp/$ip.html
    #对比源站的页面和CDN节点的页面是否有差异
    diff /tmp/s.html /tmp/$ip.html > /tmp/$ip.diff 2>/dev/null
    n=`wc -l /tmp/$ip.diff|awk '{print $1}'`
    #如果有差异,那么对比结果行数肯定大于0
    if [ $n -gt 0 ]
    then
        m_mail $ip /tmp/$ip.diff
    fi
done

 

扩展需求

监控指定页面的状态码是否是200,示例脚本如下:

 

#/bin/bash
#监控指定页面是否是非200状态码
#作者:阿铭
#日期:2018-10-18
url="http://www.test.com/test.html"
[email protected]
#检查是否有curl命令
if ! which curl &>/dev/null
then
    yum install -y curl
fi
#定义告警函数(这里的mail.py是案例二中那个脚本)
m_mail() {
    log=$1
    t_s=`date +%s`
    t_s2=`date -d "1 hours ago" +%s`
    if [ ! -f /tmp/$log ]
    then
        #创建$log文件
        touch /tmp/$log 
        #增加a权限,只允许追加内容,不允许更改或删除
        chattr +a /tmp/$log
        #第一次告警,可以直接写入1小时以前的时间戳
        echo $t_s2 >> /tmp/$log
    fi
    #无论$log文件是否是刚刚创建,都需要查看最后一行的时间戳
    t_s2=`tail -1 /tmp/$log|awk '{print $1}'`
    #取出最后一行即上次告警的时间戳后,立即写入当前的时间戳
    echo $t_s>>/tmp/$log
    #取两次时间戳差值
    v=$[$t_s-$t_s2]
    #如果差值超过1800,立即发邮件
    if [ $v -gt 1800 ]
    then
        #发邮件,其中$2为mail函数的第二个参数,这里为一个文件
        python mail.py $mail_user "$url访问异常" "`cat $2`"  2>/dev/null   
        #定义计数器临时文件,并写入0         
        echo "0" > /tmp/$log.count
    else
        #如果计数器临时文件不存在,需要创建并写入0
        if [ ! -f /tmp/$log.count ]
        then
            echo "0" > /tmp/$log.count
        fi
        nu=`cat /tmp/$log.count`
        #30分钟内每发生1次告警,计数器加1
        nu2=$[$nu+1]
        echo $nu2>/tmp/$log.count
        #当告警次数超过30次,需要再次发邮件
        if [ $nu2 -gt 30 ]
        then
             python mail.py $mail_user "$url访问异常持续30分钟了" "`cat $2`" 2>/dev/null  
             #第二次告警后,将计数器再次从0开始          
             echo "0" > /tmp/$log.count
        fi
    fi
}
curl -I $url &>/tmp/curl.txt
code=`grep '^HTTP/1.1' /tmp/curl.txt|awk '{print $2}'`
if [ -z "$code" ] || [ $code -ne 200 ]
then
    m_mail webcode /tmp/curl.txt
fi

 

版权声明:
作者:WaterBear
链接:https://l-t.top/2089.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录