本人在工作中一般喜欢把MySQL、Redis、Memcached、MongoDB等数据库按照实例的方式对外提供服务。一般都是一台高配的服务器上开启多个实例给每个业务使用。而监控是重中之重,我自己也尝试了多种监控方式,但对我来说感觉最简单最快的就是使用zabbix了,灵活定义key。
由于我是多实例,所以就需要用到zabbix的自动发现功能(LLD)。基本处理方式就是:
1、写自动发现脚本。
2、写状态取值脚本。
3、添加配置文件。
4、添加权限。
5、配置zabbix web。
一、写自动发现脚本
1 |
$ cat /etc/zabbix/zabbix_agentd.d/scripts/redis_discovery.py |
1 2 3 4 5 6 7 8 9 |
#!/usr/bin/env python import os import json t=os.popen("""sudo netstat -nltp|awk -F: '/redis-server/&&/LISTEN/{print $2}'|awk '{print $1}'| grep -v grep | grep -v '^$' """) ports = [] for port in t.readlines(): r = os.path.basename(port.strip()) ports += [{'{#REDISPORT}':r}] print json.dumps({'data':ports},sort_keys=True,indent=4,separators=(',',':')) |
执行脚本看输出结果(最好使用zabbix用户执行,才能看出效果):
1 2 3 4 5 6 7 8 9 10 |
$ python /etc/zabbix/zabbix_agentd.d/scripts/redis_discovery.py { "data":[ { "{#REDISPORT}":"6379" }, { "{#REDISPORT}":"6379" } } |
我这个脚本中使用了sudo权限,zabbix用户在执行netstat时需要sudo权限。
对于Redis也可以使用ps命令,因为如果你一台机器上有Redis、也有sentinel使用netstat命令就比较恶心了,没办法区分。但是可以使用ps命令,因为也会带端口号信息,所以跟netstat效果一样,如下:
1 2 3 |
$ ps aux | grep redis | grep redis-server | grep -v grep redis 84346 0.0 0.0 147160 4972 ? Ssl 16:31 0:09 redis-server 0.0.0.0:6379 redis 84467 0.1 0.0 136920 2768 ? Sl 16:31 0:10 redis-server *:6380 [sentinel] |
通过ps信息就可以很好地把sentinel过滤掉了,并且ps命令对于zabbix用户不需要sudo权限。
二、写状态取值脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
#!/bin/bash # #Auth: Pengdongwen #Blog: www.ywnds.com #Desc: redis 3.2+ status monitoring #dependent: # 1)python redis_discovery.py # 2)yum install redis-cli dos2unix ######################### CMD="/usr/local/bin/redis-cli" REDIS_IP=127.0.0.1 PORT="$1" METRIC="$2" PASSWD="123456" if [ $# -lt 2 ];then echo "please set argument" exit 1 fi if [ ! -n "$PASSWD" ];then STATUS=`$CMD -h $REDIS_IP -p $PORT info | grep -w "$METRIC" | awk -F':' '{print $2}'` BACK="$CMD -h $REDIS_IP -p $PORT info" else STATUS=`$CMD -a $PASSWD -h $REDIS_IP -p $PORT info | grep -w "$METRIC" | awk -F':' '{print $2}'` BACK="$CMD -a $PASSWD -h $REDIS_IP -p $PORT info" fi case $METRIC in # master or slave 'redis_version') echo $STATUS | sed s/[[:punct:]]//g | sed s/[[:alpha:]]//g ;; 'redis_mode') echo $STATUS ;; 'uptime_in_days') echo $STATUS ;; 'lru_clock') echo $STATUS ;; 'connected_clients') echo $STATUS ;; 'maxclients') if [ -n "$PASSWD" ];then STATUS=`$CMD -h $REDIS_IP -p $PORT -a $PASSWD CONFIG GET maxclients | tail -n1` else STATUS=`$CMD -h $REDIS_IP -p $PORT CONFIG GET maxclients | tail -n1` fi echo $STATUS ;; 'blocked_clients') echo $STATUS ;; 'used_memory') echo $STATUS ;; 'used_memory_rss') echo $STATUS ;; 'used_memory_peak') echo $STATUS ;; 'total_system_memory') echo $STATUS ;; 'maxmemory') echo $STATUS ;; 'aof_enabled') echo $STATUS ;; 'total_connections_received') echo $STATUS ;; 'total_commands_processed') echo $STATUS ;; 'instantaneous_ops_per_sec') echo $STATUS ;; 'expired_keys') echo $STATUS ;; 'evicted_keys') echo $STATUS ;; 'keyspace_hits') echo $STATUS ;; 'keyspace_misses') echo $STATUS ;; 'keys') if [ -n "$PASSWD" ];then STATUS=`$CMD -a $PASSWD -h $REDIS_IP -p $PORT dbsize | sed s/[[:punct:]]//g | sed s/[[:alpha:]]//g` else STATUS=`$CMD -h $REDIS_IP -p $PORT dbsize | sed s/[[:punct:]]//g | sed s/[[:alpha:]]//g` fi echo $STATUS ;; 'role') STATUS=`echo $STATUS | dos2unix` if [ $STATUS == "master" ];then echo 1 # master elif [ $STATUS == "slave" ];then echo 2 # slave else echo 0 # other fi ;; 'connected_slaves') echo $STATUS ;; 'cluster_enabled') if [ -n "$STATUS" ];then echo $STATUS else echo 0 fi ;; 'use_memory_percent') used_memory=`$BACK | grep -w "used_memory" | awk -F':' '{print $2}' | dos2unix` maxmemory=`$BACK | grep -w "maxmemory" | awk -F':' '{print $2}' | dos2unix` #maxmemory=`$CMD -h $REDIS_IP -p $PORT CONFIG GET maxmemory | tail -n1 | dos2unix` if [ -n "$maxmemory" ];then python -c "print float(`echo $used_memory`)/float(`echo $maxmemory`)" | cut -c 1,2,3,4 else echo 0 fi ;; # slave 'master_host') if [ -n "$STATUS" ];then echo $STATUS else echo 0 fi ;; 'master_port') if [ -n "$STATUS" ];then echo $STATUS else echo 0 fi ;; 'slave_read_only') if [ -n "$STATUS" ];then echo $STATUS else echo 0 fi ;; 'master_link_status') if [ -n "$STATUS" ];then if [ $STATUS == "up" ];then echo 1 else echo 0 fi else echo 0 fi ;; *) echo "Not selected metric" exit 0 ;; esac |
脚本很简单,需要传给脚本两个参数,一个是端口号,另一个是监控值。
有几个特别需要说明的就是:
1)这个脚本不支持redis加密。
2)需要指定redis-cli的绝对路径。
3)需要安装dos2unix工具(yum install dos2unix)。
三、添加配置文件
1 2 3 |
$ cat /etc/zabbix/zabbix_agentd.d/userparameter_redis.conf UserParameter=redis.discovery[*],python /etc/zabbix/zabbix_agentd.d/scripts/redis_discovery.py UserParameter=redis[*],/bin/bash /etc/zabbix/zabbix_agentd.d/scripts/redis_status.sh $1 $2 |
这里定义三个key,第一个key是用于自动发现的。第二个key是用于取不同实例的状态值的,传了两个参数,$1是端口号(从自动发现中获取的),第二个是传的参数。端口号和参数我会在zabbix页面配置传给redis[*]这个key。
都配置完后就可以添加重启一下zabbix-agent了。
1 |
$ service zabbix-agent restart |
四、添加权限
需要给zabbix用户添加sudo权限。
1 2 3 4 |
$ cat /etc/sudoers.d/zabbix Defaults:zabbix !requiretty zabbix ALL=(ALL) NOPASSWD: SUPERVISORCTLZB Cmnd_Alias SUPERVISORCTLZB = /sbin/ss,/usr/sbin/ss,/sbin/dmidecode,/usr/sbin/dmidecode,/sbin/service,/usr/sbin/service,/bin/netstat |
另外需要注意的是,普通用户zabbix默认环境变量有如下这些:
1 2 |
$ echo $PATH /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin |
所以你要确认你所有的执行程序都在这些路径下,不然zabbix是获取不到值的。
使用zabbix用户执行看是否正常。
1 2 3 4 5 6 7 8 9 10 |
$ sudo -u zabbix `which zabbix_agentd` -t redis.discovery[*] { "data":[ { "{#REDISPORT}":"6379" }, { "{#REDISPORT}":"6379" } } |
五、配置zabbix web
前期工作都做完了,下面就可以配置zabbix web了。
首先创建一个模板(Template Linux Redis Discovery),然后在模板中创建一个自动发现规则(Linux Redis Discovery)。
在这个自动发现规则内创建一个item。
然后可以创建trigger等,下面是我提供的一个模板。
Github:https://github.com/dongwenpeng/zabbix