SAE域名绑定之后,一般是用CNAME方式将域名绑定到应用中。但是有时候我们需要用到A记录(比如说根域名,虽然在DNSPOD上可以设置CNAME记录,但很可能会影响到MX记录),而SAE的IP地址经常改变,ping应用二级域名得到的IP没多久就失效了(前些天网站因此几天打不开都没发现,我用的是教育网,自己能打开,但是电信线路变了)。还好DNSPOD有个功能叫D监控,可以帮你监控网站能否正常打开。如果发现宕机,DNSPOD会用邮件、短信、微信等方式提醒你。这里用到的是它的另一个通知方式,那就是URL回调。
“通过DNSPod 提供的D监控 URL 回调功能,您可以让宕机或恢复信息提交到您指定的 URL 上,从而更加灵活地处理各种通知信息。”
我们可以通过宕机之后的URL回调取得相关参数,并通过DNSPOD API实现自动修改记录的功能,再通过飞信发送宕机通知。
代码在后面,先说设置方法:
设置方法
1.点此下载代码,修改其中的参数为你自己的。
2.将代码上传到网站。
3.在DNSPOD开启D监控,在通知设置中回调URL一栏填入monitorCallback.php的地址,如https://blog.gimhoy.com/monitorCallback.php?rHost=hipic.sinaapp.com
.其中rHost是SAE的二级域名。并设置回调密钥。
4.Enjoy~
代码
monitorCallback.php
<?php header('Content-type:text/html; charset=utf-8'); /* * Copyright 2007-2014 Gimhoy Studio. * * @author Gimhoy * @email contact@gimhoy.com * @version 1.0.0 */ $rHost = $_GET['rHost']; // SAE二级域名 if(empty($rHost)) $rHost = 'sinaapp.com'; $logName = 'monitorLog.txt'; //log 文件名 $logStorDomain = 'log'; // Storage Domain $FetionNum = ''; //飞信登陆号码 $FetionPwd = ''; //飞信登陆密码 $MobileNum = ''; //接收通知短信的号码 $callback_key = 'MYKEY'; // 添加监控时设置的密钥 $monitor_id = $_POST['monitor_id']; // 监控编号 $domain_id = $_POST['domain_id']; // 域名编号 $domain = $_POST['domain']; // 域名名称 $record_id = $_POST['record_id']; // 记录编号 $sub_domain = $_POST['sub_domain']; // 主机名称 $record_line = $_POST['record_line']; // 记录线路 $ip = $_POST['ip']; // 记录IP $status = $_POST['status']; // 当前状态 $status_code = $_POST['status_code']; // 状态代码 $reason = $_POST['reason']; // 宕机原因 $created_at = $_POST['created_at']; // 发生时间 $checksum = $_POST['checksum']; // 校检代码 if (md5($monitor_id. $domain_id. $record_id. $callback_key. $created_at) != $checksum) { // 非法请求 echo 'BAD REQUEST'; } else { // 开始处理 if ($status == 'Warn' || $status == 'Ok') { // 宕机恢复 $msg = date("Y-m-d H:i:s").' '.$sub_domain.'.'.$domain."(".$record_line." ".$ip.")宕机恢复"; } elseif ($status == 'Down') { // 宕机 $msg = date("Y-m-d H:i:s").' '.$sub_domain.'.'.$domain."(".$record_line." ".$ip.")在".$created_at."宕机。宕机原因:".$reason."可用IP:"; $ips = @gethostbyname($rHost); include_once 'dnspod.class.php'; $newIP = $ips; $data = array( 'domain_id' => $domain_id, 'record_id' => $record_id, 'sub_domain' => $sub_domain, 'record_type' => 'A', 'record_line' => $record_line, 'ttl' => '600', 'value' => $newIP ); $dnspod = new dnspod(); $response = $dnspod->api_call('Record.Modify', $data); if(isset($response['status']['code']) && $response['status']['code'] == 1) { $msg = $msg.$newIP.'(已切换)'; } else { $msg = $msg.$newIP.'(切换失败,错误代码'.$response['status']['code'].')'; } } //飞信通知 require_once 'Fetion.class.php'; $fetion = new PHPFetion($FetionNum, $FetionPwd); $result = $fetion->send($MobileNum, $msg); if(strpos($result, '短信发送成功!') || strpos($result, '发送消息成功!')) { $r = "成功。";}else{$r = "失败。";} $s = new SaeStorage(); $content = $s -> read($logStorDomain, $logName); $content = $content.$msg.'。飞信通知'.$r.' '; $s -> write($logStorDomain, $logName, $content); // 处理完成 echo 'DONE'; }
dnspod.class.php
<?php header('Content-type:text/html; charset=utf-8'); /* * DNSPod API PHP Web 示例 * https://www.zhetenga.com/ * * Copyright 2011, Kexian Li * Released under the MIT, BSD, and GPL Licenses. * */ class dnspod { public function api_call($api, $data) { if ($api == '' || !is_array($data)) { exit('内部错误:参数错误'); } $api = 'https://dnsapi.cn/' . $api; $data = array_merge($data, array('login_email' => 'DNSPOD登陆账号', 'login_password' => 'DNSPOD登陆密码', 'format' => 'json', 'lang' => 'cn', 'error_on_empty' => 'yes')); $result = $this->post_data($api, $data); if (!$result) { exit('内部错误:调用失败'); } $results = @json_decode($result, 1); if (!is_array($results)) { exit('内部错误:返回错误'); } if ($results['status']['code'] != 1) { exit($results['status']['message']); } return $results; } private function post_data($url, $data) { if ($url == '' || !is_array($data)) { return false; } $ch = @curl_init(); if (!$ch) { exit('内部错误:服务器不支持CURL'); } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_USERAGENT, 'Gimhoy Monitor/1.0 (contact@gimhoy.com)'); $result = curl_exec($ch); curl_close($ch); return $result; } }
Fetion.class.php
<?php header('Content-Type: text/html; charset=utf-8'); /** * PHP飞信发送类 * @author quanhengzhuang <blog.quanhz.com> * @version 1.5.0 */ class PHPFetion { /** * 发送者手机号 * @var string */ protected $_mobile; /** * 飞信密码 * @param string */ protected $_password; /** * Cookie字符串 * @param string */ protected $_cookie = ''; /** * Uid缓存 * @var array */ protected $_uids = array(); /** * csrfToken * @param string */ protected $_csrfToten = null; /** * 构造函数 * @param string $mobile 手机号(登录者) * @param string $password 飞信密码 */ public function __construct($mobile, $password) { if ($mobile === '' || $password === '') { return; } $this->_mobile = $mobile; $this->_password = $password; $this->_login(); } /** * 析构函数 */ public function __destruct() { $this->_logout(); } /** * 登录 * @return string */ protected function _login() { $uri = '/huc/user/space/login.do?m=submit&fr=space'; $data = 'mobilenum='.$this->_mobile.'&password='.urlencode($this->_password); $result = $this->_postWithCookie($uri, $data); //解析Cookie preg_match_all('/.*?\r\nSet-Cookie: (.*?);.*?/si', $result, $matches); if (isset($matches[1])) { $this->_cookie = implode('; ', $matches[1]); } $result = $this->_postWithCookie('/im/login/cklogin.action', ''); return $result; } /** * 获取csrfToken,给好友发飞信时需要这个字段 * @param string $uid 飞信ID * @return string */ protected function _getCsrfToken($uid) { if ($this->_csrfToten === null) { $uri = '/im/chat/toinputMsg.action?touserid='.$uid; $result = $this->_postWithCookie($uri, ''); preg_match('/name="csrfToken".*?value="(.*?)"/', $result, $matches); $this->_csrfToten = isset($matches[1]) ? $matches[1] : ''; } return $this->_csrfToten; } /** * 向指定的手机号发送飞信 * @param string $mobile 手机号(接收者) * @param string $message 短信内容 * @return string */ public function send($mobile, $message) { if($message === '') { return ''; } // 判断是给自己发还是给好友发 if($mobile === $this->_mobile) { return $this->_toMyself($message); } else if(strlen($mobile)===11){ $uid = $this->_getUid($mobile); } else { $uid=$mobile; } return $uid === '' ? $this->_addFriend($mobile) : $this->_toUid($uid, $message); } protected function _getname() { $uri = '/im/index/index.action'; $result = $this->_postWithCookie($uri, '#'); // 匹配 preg_match('/<a href="\/im\/index\/index.action\?t=(.*?)">(.*?)<\/a>/si', $result, $matches); return $matches[2]; } /* * 通过手机号增加好友 * @param string $number 手机号(要加的好友手机) * @param string $nickname 你的名字,出现在对方的验证短信里 * @param string $buddylist 分组,默认为空 * @param string $localName 好友屏显名 * @return string */ protected function _addFriend($number) { $uri = '/im/user/insertfriendsubmit.action'; $data = 'nickname='. urlencode($this->_getname()).'&buddylist=1&localName=&number='. $number .'&type=0'; $result = $this->_postWithCookie($uri, $data); return $result; } /** * 获取飞信ID * @param string $mobile 手机号 * @return string */ protected function _getUid($mobile) { if (empty($this->_uids[$mobile])) { $uri = '/im/index/searchOtherInfoList.action'; $data = 'searchText='.$mobile; $result = $this->_postWithCookie($uri, $data); //匹配 preg_match('/toinputMsg\.action\?touserid=(\d+)/si', $result, $matches); $this->_uids[$mobile] = isset($matches[1]) ? $matches[1] : ''; } return $this->_uids[$mobile]; } /** * 向好友发送飞信 * @param string $uid 飞信ID * @param string $message 短信内容 * @return string */ protected function _toUid($uid, $message) { $uri = '/im/chat/sendMsg.action?touserid='.$uid; $csrfToken = $this->_getCsrfToken($uid); $data = 'msg='.urlencode($message).'&csrfToken='.$csrfToken; $result = $this->_postWithCookie($uri, $data); return $result; } /** * 给自己发飞信 * @param string $message * @return string */ protected function _toMyself($message) { $uri = '/im/user/sendMsgToMyselfs.action'; $result = $this->_postWithCookie($uri, 'msg='.urlencode($message)); return $result; } /** * 退出飞信 * @return string */ protected function _logout() { $uri = '/im/index/logoutsubmit.action'; $result = $this->_postWithCookie($uri, ''); return $result; } protected function getgroup() { $uri = '/im/index/index.action'; $data = 'type=group'; $result = $this->_postWithCookie($uri, $data); // 匹配 preg_match_all('/contactlistView\.action\?idContactList=(\d+)/si', $result, $matches); foreach($matches[1] as $k=>$v){ if( $k== 0 ){ $min = $v; $max = $v; }else if($v!=9998&&$v!=9999){ $min = min($min,$v); $max = max($max,$v); } } return $max; } public function getyou1() { $list=$this->getgroup(); for($i=0;$i<=$list;$i++){ $uri = '/im/index/contactlistView.action'; $data = 'idContactList='.$i.'&type=group'; $result = $this->_postWithCookie($uri, $data); preg_match('/<br\/>(.*?)\|(.*?)\((.*?)\/(.*?)\)<br\/>/si', $result, $listn); if(!$listn[2]){continue;} $shuchu.=str_replace(" ","",$listn[2])."(".$listn[4].")\n"; preg_match('/共(\d+)页/si', $result, $zpage); preg_match('/共<a href="\/im\/index\/contactlistView\.action\?idContactList=(\d+)\&page=(\d+)\&t=(\d+)" class="c_ash" >(\d+)<\/a>页/si', $result, $dpage); isset($zpage[1]) ? $page=$zpage[1] : $page=$dpage[4]; for($j=1;$j<=$page;$j++){ $uri = '/im/index/contactlistView.action'; $data = 'idContactList='.$i.'&page='.$j; $result = $this->_postWithCookie($uri, $data); preg_match_all('/<a href="\/im\/chat\/toinputMsg\.action\?touserid=(.*?)\&(.*?)">(.*?)<\/a>/si', $result, $matches); if(!$matches[1][0]){break;} for($x=0;$x<=9;$x++){ if(!$matches[1][$x]){continue;} $shuchu.=$matches[1][$x]." ".str_replace(" ","",$matches[3][$x])."\n"; } } } return $shuchu; } public function getyou() { $list=$this->getgroup(); for($i=0;$i<=$list;$i++){ $uri = '/im/index/contactlistView.action'; $data = 'idContactList='.$i.'&type=group'; $result = $this->_postWithCookie($uri, $data); preg_match('/<br\/>(.*?)\|(.*?)\((.*?)\/(.*?)\)<br\/>/si', $result, $listn); if(!$listn[2]){continue;} $shuchu.=str_replace(" ","",$listn[2])."(".$listn[4].")\n"; preg_match('/共(\d+)页/si', $result, $zpage); preg_match('/共<a href="\/im\/index\/contactlistView\.action\?idContactList=(\d+)\&page=(\d+)\&t=(\d+)" class="c_ash" >(\d+)<\/a>页/si', $result, $dpage); isset($zpage[1]) ? $page=$zpage[1] : $page=$dpage[4]; for($j=1;$j<=$page;$j++){ $uri = '/im/index/contactlistView.action'; $data = 'idContactList='.$i.'&page='.$j; $result = $this->_postWithCookie($uri, $data); preg_match_all('/<a href="\/im\/chat\/toinputMsg\.action\?touserid=(.*?)\&(.*?)">(.*?)<\/a>/si', $result, $matches); if(!$matches[1][0]){break;} for($x=0;$x<=9;$x++){ if(!$matches[1][$x]){continue;} $shuchu.=$matches[1][$x]." ".str_replace(" ","",$matches[3][$x])."\n"; } } } return $shuchu; } /** * 携带Cookie向f.10086.cn发送POST请求 * @param string $uri * @param string $data */ protected function _postWithCookie($uri, $data) { $fp = fsockopen('f.10086.cn', 80); fputs($fp, "POST $uri HTTP/1.1\r\n"); fputs($fp, "Host: f.10086.cn\r\n"); fputs($fp, "Cookie: {$this->_cookie}\r\n"); fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n"); fputs($fp, "User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1\r\n"); fputs($fp, "Content-Length: ".strlen($data)."\r\n"); fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $data); $result = ''; while (!feof($fp)) { $result .= fgets($fp); } fclose($fp); return $result; } }
谢谢博主,这个留着以后有用
专程来点赞,博客做的好用心!
很厉害,谢谢博主,这个留着以后有用