合格站长必备之网站资源监控

序言

最近手里很多服务器都出现了内存满了或者硬盘满了导致服务器宕机等问题,作为一个合格的站长,资源监控已成为必备技能。

站点访问监控

我一直用的是 MySSL 企业版的网站监控,网站无法访问时,邮件 + 微信提醒还是挺好用的,当然如果不嫌麻烦的话,自己写一个脚本也是可以的。
image

服务器内部资源监控

这边自己写了个脚本监控网站硬盘资源发送到钉钉,其中钉钉的部分是从 Berry 小伙子那里直接拿来用的。

代码

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"

	"github.com/shirou/gopsutil/disk"
)

// SendGroupType .
type SendGroupType struct {
	MsgType string   `json:"msgtype"`
	Text    TextType `json:"text"`
	At      AtType   `json:"at"`
	IsAtAll bool     `json:"isAtAll"`
}

// TextType .
type TextType struct {
	Content string `json:"content"`
}

// AtType .
type AtType struct {
	AtMobiles []string `json:"atMobiles"`
}

// SendGroupResp .
type SendGroupResp struct {
	ErrMsg  string `json:"errmsg"`
	ErrCode int    `json:"errcode"`
}

const (
	token       = "your token"
	allensPhone = "your dingtalk phone"

	b = 1024
	k = b * 1024
	g = k * 1024
)

func main() {
	diskInfo, _ := disk.Usage("/")
	if diskInfo.Free/g <= 3 {
		SendDingRobot("告警: 当前您的服务器 [ XXX ] 硬盘内存剩余已不足 3 G", []string{
			allensPhone,
		})
	}
}

// SendDingRobot Send text messages to ding robot
func SendDingRobot(msg string, phone []string) error {
	t := TextType{
		Content: msg,
	}
	a := AtType{
		AtMobiles: phone,
	}
	g := SendGroupType{
		MsgType: "text",
		Text:    t,
		At:      a,
		IsAtAll: true,
	}

	err := sendGroup(g)
	if err != nil {
		return fmt.Errorf("send ding Group err:[%s]", err.Error())
	}
	return nil
}

// SendGroup 发送消息到钉钉群机器人
func sendGroup(sendGroup SendGroupType) error {

	client := &http.Client{
		Timeout: time.Duration(15) * time.Second,
	}

	reqData, err := json.Marshal(sendGroup)
	if err != nil {
		return err
	}

	reader := bytes.NewReader(reqData)
	resp, err := client.Post("https://oapi.dingtalk.com/robot/send?access_token="+token, "application/json;charset=UTF-8", reader)
	if err != nil {
		return err
	}

	defer resp.Body.Close()

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	var respData SendGroupResp
	err = json.Unmarshal(data, &respData)
	if err != nil {
		return err
	}

	if respData.ErrCode != 0 {
		return errors.New(respData.ErrMsg)
	}
	return nil
}

定时任务

代码撸完了,到服务器上设个定时任务执行一下就可以了。

  • SCP 上传脚本到服务器上
scp diskMonitor myservice:~/monitor/disk
  • Linux 定时任务命令
crontab -e
  • 把页面当 VIM 用就可以了

每天下午两点执行一次,不输出日志

0 14 * * * cd /home/ec2-user/monitor && ./disk > /dev/null
--------------- 这是一条分割线 -----------------------------
# 格式解释
- -  - - -
| |  | | |
| |  | | +----- 一星期中星期几 (0 - 7) (星期天 为0)
| |  | +------- 月份 (1 - 12) 
| |  +--------- 一个月中的第几天 (1 - 31)
| +------------ 小时 (0 - 23)
+-------------- 分钟 (0 - 59)
  • 当然你也可以定期清理下 docker
0 14 * * 3 docker system prune -f > /dev/null

参考