前言:检测服务器运行情况是线上环境最重要的环节,人为监控难免疏忽,而且浪费人力物力。于是研究起了自动化检测软件,Zabbix。
首先提供zabbix中文手册:https://www.zabbix.com/documentation/3.4/zh/manual
这里只会编写笔者在学习Zabbix过程的遇到的问题。
2020/3/11编撰:
一、设置中文
以下界面是我们安装之后访问页面,默认是英文的。oh真让人头疼。
Zabbix很友好的提供了中文语言。点击右上方小人-》Language-》选择Chinese-》点击update即可。并且中文的很全面,不会是那种零零碎碎的。
二、安装agent
手册中并没有给出安装agent这一步,我们可以点进dockerhup中就可以看到介绍。
docker run --name zabbix-agent \
--link zabbix-server-mysql:zabbix-server \
-e ZBX_SERVER_HOST="zabbix-server-mysql" \
-e ZBX_SERVER_PORT=10051 \
-e ZBX_HOSTNAME="zabbix_agent" \
-v /dev/sdc:/dev/sdc \
-p 10050:10050 \
-d zabbix/zabbix-agent
其次是如果是同一台服务器上配置server和agent将会使用到容器ip,查看容器ip,使用如下指令
docker inspect 容器ID |grep IPAddress
不建议使用docker安装agent,安装在容器中的agent监控的是容器的状态,而不是宿主机的状态!
三、配置监控项
笔者写在这篇文章时候版本已经为Zabbix 4.4.6
而手册默认是3.4,想查看4.2版却发现并未编写...跟着3.4版学习,在配置监控项时说使用如下指令
一直提示invalid first parameter,这个命令在4.x版本已经改变了,可以查看key文档https://www.zabbix.com/documentation/3.4/zh/manual/config/items/itemtypes/zabbix_agent
然后我又发现还是提示invalid first paramete,不用着急,勾选监控项,点击现在检查。
然后稍等几分钟就可以了。
笔者后来发现其实原本的system.cpu.load也是可以用的...这就很神奇了~
四:刷新时间
这里的图表刷新时间和设置控制项里的更新时间没有半毛钱关系,真正有关系的是这是中文时候的那个页面里的刷新时间。
控制相里的更新时间决定的是数据的更新时间,建议这两个设置为同一时间。
中间一点一点的是因为我把更新时间设置了10s,而刷新时间是1s,导致数据更新不及时。
五:时间问题
在查看最新数据时候,我发现时间并不对,原来是容器里的时间采用的是UTC标准时区,和我们北京时间差了8小时,这怎么行!
这里就很麻烦了,由于笔者不是用DockerFile构建的,只能重新运行容器挂载 -v /etc/localtime:/etc/localtime:ro
这里有人说直接docker cp 把localtime复制到容器内 我发现是不可以的。localtime本质只是个链文件。
问题又来了,我发现这个时间和我容器的时间还是不一致的。那么这个服务器时间又是哪里来呢?
通过不断研究,终于找到了问题所在。
在web容器内执行如下命令
grep -r "timezone" /etc/php7/
我这里是已经改过来了,你们的应该还是Europe/Riga,使用vi命令修改99-zabbix-ini文件,改成Asia/Shanghai
然后还需要找到php-fpm7这个进程,kill了它,它会立刻重启。
回到页面刷新~见证奇迹的时刻!服务器时间就和我们北京时间同步啦!至于和容器时间相不相关这里我就不再验证了,个人感觉应该是无关的,可以给我评论说一下你的情况。
2020/3/12第二次编撰:
六:触发器显示触发器状态
根据手册前往监控(Monitoring) → 触发器(Triggers)以查看,发现找不到触发器这个地方。我们来到问题,修改过滤器,点击应用就可以看到了。
可以适当的修改表达式的值,满足我们看到效果的小欲望。avg(时间,单位为s),然后去服务器根目录执行find指令,当find指令执行结束后,会自动变回已解决,并闪烁。
{host:system.cpu.load.avg(10)}>0.3
七:发送邮件login denied
一开始我是用qq邮箱,发现一直login denied,还没有报错状态码,无语弄了好久,最后换了163邮箱就可以了。
2020/3/13更新:
八:监控mysql
昨天捣鼓了一天,都没找到docker agent 监控 docker mysql的。后来意识到这貌似不太可能,因为docker agent里面压根用不了宿主机的环境变量。也就是说不建议使用docker安装agent,直接用宿主机安装agent问题就迎刃而解,(怪不得官方文档没有说如何用docker安装agent容器!)
举一反三监控其他应用也是这个说法。
很感谢大佬的一语道破,安装在容器中的agent监控的是容器的状态,而不是宿主机的状态!
2020/3/17更新:
九:发送短信
发送短信最大的坑就是换行符的问题,会出现CRLF ->LF 问题。因为window的换行符是 \r\n 而 linux换行符是 \n 。\r在Linux、unix 中表示返回到当行的最开始位置。于是就会出现覆盖错误。并且我本人使用的是云通信平台,本身也不允许使用换行符,于是在content中使用tr指令删除掉换行符即可。如果你的平台可以使用换行符,可以用tr的替换指令替换为\n。
下面 贴出我的脚本代码
#!/bin/bash
LOGFILE="/var/log/smslog/log.log"
:>"$LOGFILE"
exec 1>"$LOGFILE"
exec 2>&1
#----------------初始化参数---------------------------
#appId
appId="xxx"
#token
token="yyy"
#userId
userId="zzz"
#templateId
templateId="uuu"
#------------------------------------------------------
#-----------------传入参数-----------------------------
#手机号
mobile=$1
# 项目
project=$2
# 网址
url=$3
# 内容
content=`echo $4 |tr -d '\r\n'`
#------------------------------------------------------
#------------------生成参数----------------------------
#生成时间戳
current=`date '+%Y%m%d%H%M%S'`
#生成SigParameter
key=$userId$token$current
typeset -u SigParameter
SigParameter=`echo -n $key|md5sum|cut -d " " -f 1`
#生成Authorzation
key=$userId:$current
Authorization=$(printf "%s""$key" | base64)
#-------------------------------------------------------
#-----------------发送短信------------------------------
data='{"to":"'$mobile'","appId":"'$appId'","templateId":"'$templateId'","datas":["'$project'","'$url'","'$content'"]}'
h1="Accept:application/json"
h2="Content-Type:application/json;charset=utf-8"
h3="Authorization:$Authorization"
h4="Content-Length:256"
api="https://app.cloopen.com:8883/2013-12-26/Accounts/$userId/SMS/TemplateSMS?sig=$SigParameter"
echo $data
echo "send sms:"
curl -v --insecure -X POST --header "$h1" --header "$h2" --header "$h3" --data "$data" "$api"
#------------------------------------------------------
2020/3/18更新
十:监控自定义参数
记得开放10050端口
这里说一下大体步骤,以nginx为例
1. 部分软件需要开放的status功能,例如apache和nginx需要开启。
location /status{
stub_status on;
access_log off;
}
2.编写脚本,检测脚本,通常是一些curl的命令,检验脚本
#! /bin/bash
#date: 2018-05-04
# Description:zabbix监控nginx性能以及进程状态
# Note:此脚本需要配置在被监控端,否则ping检测将会得到不符合预期的结果
HOST="gudaoyufu.com"
PORT="80"
# 检测nginx进程是否存在
function ping {
/sbin/pidof nginx | wc -l
}
# 检测nginx性能
function active {
/usr/bin/curl "http://$HOST:$PORT/status/" 2>/dev/null| grep 'Active' | awk '{print $NF}'
}
function reading {
/usr/bin/curl "http://$HOST:$PORT/status/" 2>/dev/null| grep 'Reading' | awk '{print $2}'
}
function writing {
/usr/bin/curl "http://$HOST:$PORT/status/" 2>/dev/null| grep 'Writing' | awk '{print $4}'
}
function waiting {
/usr/bin/curl "http://$HOST:$PORT/status/" 2>/dev/null| grep 'Waiting' | awk '{print $6}'
}
function accepts {
/usr/bin/curl "http://$HOST:$PORT/status/" 2>/dev/null| awk NR==3 | awk '{print $1}'
}
function handled {
/usr/bin/curl "http://$HOST:$PORT/status/" 2>/dev/null| awk NR==3 | awk '{print $2}'
}
function requests {
/usr/bin/curl "http://$HOST:$PORT/status/" 2>/dev/null| awk NR==3 | awk '{print $3}'
}
# 执行function
$1
3.新建/etc/zabbix/zabbix-agent.d/userparameter_(软件名).conf 输入自定义用户参数
UserParameter=nginx.status[*],/home/scripts/nginx_status.sh $1
4.在客户端重启agent,
systemctl resatrt zabbix-agent.service
5.在server端使用zbbix_get -s ip -k '脚本命令' 测试
zabbix_get -s ip -k 'nginx.status[active]'
5.到web页面编写模板->应用集->监控项->触发器->图形
也可直接导入模板
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>3.4</version>
<date>2018-01-18T11:00:49Z</date>
<groups>
<group>
<name>Templates</name>
</group>
</groups>
<templates>
<template>
<template>Template App NGINX</template>
<name>Template App NGINX</name>
<description>nginx statuses
Author:371304</description>
<groups>
<group>
<name>Templates</name>
</group>
</groups>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<items>
<item>
<name>nginx status server accepts</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[accepts]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>accepts</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
<item>
<name>nginx status connections active</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[active]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>acitve</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
<item>
<name>nginx status server handled</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[handled]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>handled</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
<item>
<name>nginx status PING</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[ping]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>ping</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
<item>
<name>nginx status connections reading</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[reading]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>reading</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
<item>
<name>nginx status server requests</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[requests]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>requests</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
<item>
<name>nginx status connections waiting</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[waiting]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>waiting</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
<item>
<name>nginx status connections writing</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>nginx.status[writing]</key>
<delay>30s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<units/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>writing</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Nginx</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<master_item/>
</item>
</items>
<discovery_rules/>
<httptests/>
<macros/>
<templates/>
<screens/>
</template>
</templates>
<triggers>
<trigger>
<expression>{Template App NGINX:nginx.status[ping].last()}=0</expression>
<recovery_mode>0</recovery_mode>
<recovery_expression/>
<name>nginx was down!</name>
<correlation_mode>0</correlation_mode>
<correlation_tag/>
<url/>
<status>0</status>
<priority>4</priority>
<description>nginx was down!</description>
<type>0</type>
<manual_close>0</manual_close>
<dependencies/>
<tags/>
</trigger>
</triggers>
<graphs>
<graph>
<name>nginx status connections</name>
<width>900</width>
<height>200</height>
<yaxismin>0.0000</yaxismin>
<yaxismax>100.0000</yaxismax>
<show_work_period>1</show_work_period>
<show_triggers>1</show_triggers>
<type>0</type>
<show_legend>1</show_legend>
<show_3d>0</show_3d>
<percent_left>0.0000</percent_left>
<percent_right>0.0000</percent_right>
<ymin_type_1>0</ymin_type_1>
<ymax_type_1>0</ymax_type_1>
<ymin_item_1>0</ymin_item_1>
<ymax_item_1>0</ymax_item_1>
<graph_items>
<graph_item>
<sortorder>0</sortorder>
<drawtype>0</drawtype>
<color>1A7C11</color>
<yaxisside>0</yaxisside>
<calc_fnc>2</calc_fnc>
<type>0</type>
<item>
<host>Template App NGINX</host>
<key>nginx.status[active]</key>
</item>
</graph_item>
<graph_item>
<sortorder>1</sortorder>
<drawtype>0</drawtype>
<color>F63100</color>
<yaxisside>0</yaxisside>
<calc_fnc>2</calc_fnc>
<type>0</type>
<item>
<host>Template App NGINX</host>
<key>nginx.status[reading]</key>
</item>
</graph_item>
<graph_item>
<sortorder>2</sortorder>
<drawtype>0</drawtype>
<color>2774A4</color>
<yaxisside>0</yaxisside>
<calc_fnc>2</calc_fnc>
<type>0</type>
<item>
<host>Template App NGINX</host>
<key>nginx.status[waiting]</key>
</item>
</graph_item>
<graph_item>
<sortorder>3</sortorder>
<drawtype>0</drawtype>
<color>A54F10</color>
<yaxisside>0</yaxisside>
<calc_fnc>2</calc_fnc>
<type>0</type>
<item>
<host>Template App NGINX</host>
<key>nginx.status[writing]</key>
</item>
</graph_item>
</graph_items>
</graph>
<graph>
<name>nginx status server</name>
<width>900</width>
<height>200</height>
<yaxismin>0.0000</yaxismin>
<yaxismax>100.0000</yaxismax>
<show_work_period>1</show_work_period>
<show_triggers>1</show_triggers>
<type>0</type>
<show_legend>1</show_legend>
<show_3d>0</show_3d>
<percent_left>0.0000</percent_left>
<percent_right>0.0000</percent_right>
<ymin_type_1>0</ymin_type_1>
<ymax_type_1>0</ymax_type_1>
<ymin_item_1>0</ymin_item_1>
<ymax_item_1>0</ymax_item_1>
<graph_items>
<graph_item>
<sortorder>0</sortorder>
<drawtype>0</drawtype>
<color>1A7C11</color>
<yaxisside>0</yaxisside>
<calc_fnc>2</calc_fnc>
<type>0</type>
<item>
<host>Template App NGINX</host>
<key>nginx.status[accepts]</key>
</item>
</graph_item>
<graph_item>
<sortorder>1</sortorder>
<drawtype>0</drawtype>
<color>F63100</color>
<yaxisside>0</yaxisside>
<calc_fnc>2</calc_fnc>
<type>0</type>
<item>
<host>Template App NGINX</host>
<key>nginx.status[handled]</key>
</item>
</graph_item>
<graph_item>
<sortorder>2</sortorder>
<drawtype>0</drawtype>
<color>2774A4</color>
<yaxisside>0</yaxisside>
<calc_fnc>2</calc_fnc>
<type>0</type>
<item>
<host>Template App NGINX</host>
<key>nginx.status[requests]</key>
</item>
</graph_item>
</graph_items>
</graph>
</graphs>
</zabbix_export>
6.将模板链接到对应主机