apt install memcached -y
vim /etc/memcached.conf
cat /etc/memcached.conf |grep -vE "#|^$"
-d
logfile /var/log/memcached.log
-m 64
-p 11211
-u memcache
-l 127.0.0.1
-P /var/run/memcached/memcached.pid
memcached -h
PORT="11211”#监听端口
USER="memcached”#启动用户
MAXCONN="1024”#最大连接数
CACHESIZE="1024”#最大使用内存
OPTIONS=””#其他选项
-l 0.0.0.0 #监听地址
systemctl restart memcached
telnet 10.0.0.201 11211
主服务器需要安装:memcached,libevent,keepalived,magent 201
从服务器需要安装:memcached,libevent,keepalived: 202
#关闭防火墙规则跟防护功能等
[root@localhost ~]# iptables -F
[root@localhost ~]# setenforce 0
#解压事件通知库到opt
#Memcache 用到了 libevent 这个库用于 Socket 的处理,所以还需要安装 libevent
[root@master ~]# tar zxvf libevent-2.1.8-stable.tar.gz -C /opt
[root@master ~]# tar zxvf memcached-1.5.6.tar.gz -C /opt
[root@master ~]# mkdir /opt/magent #从服务器不需要创建
[root@master ~]# tar zxvf magent-0.5.tar.gz -C /opt/magent/
yum install gcc gcc-c++ make -y
cd /opt/libevent-2.1.8-stable/
./configure --prefix=/usr #指定安装路径
#编译及安装
make && make install
cd memcached-1.5.6/
./configure \
--prefix=/usr/local/memcached \
--with-libevent=/usr/local/libevent
cd /opt/magent/
[root@master magent]# ls
ketama.c ketama.h magent.c Makefile
[root@master magent]# vim ketama.h
'//修改前两个如下'
#ifndef SSIZE_MAX
#define SSIZE_MAX 32767
..........
#endif
#修改Makefile配置文件
[root@master magent]# vim Makefile
'//首行添加-lm'
LIBS = -levent -lm
[root@master magent]# make
gcc -Wall -O2 -g -c -o magent.o magent.c
gcc -Wall -O2 -g -c -o ketama.o ketama.c
gcc -Wall -O2 -g -o magent magent.o ketama.o -levent -lm
#编译后会产生magent可执行程序
[root@master magent]# ls
ketama.c ketama.h ketama.o magent magent.c magent.o Makefile
#下载远程传输 这样从服务器就不需要修改了
[root@master magent]# yum install openssh-clients -y
将magent可执行程序复制到从服务器的/usr/bin中’
[root@master magent]# scp magent [email protected]:/usr/bin/
2.3:主从服务器搭建keeplived(略,前期文章)
2.4:主服务器创建magent脚本
2.5:主从服务器启动
[root@master shell]# chmod +x magent.sh '//增加执行权限'
[root@master shell]# systemctl stop firewalld.service
[root@master shell]# systemctl start keepalived.service '//启动服务 稍微有点慢'
[root@master shell]# netstat -ntap | grep 12000
tcp 0 0 10.0.0.100:12000 0.0.0.0:* LISTEN 100623/magent
[root@master shell]# vim /var/log/messages
搜索'//Transition to MASTER STATE',有即成功
[root@master shell]# ip addr '//查看漂移地址是否绑定成功'
.....省略内容....
inet 10.0.0.100/32 scope global ens33
.....省略内容....
#从服务器
[root@slave keepalived]# vim /var/log/messages
搜索'//Entering BACKUP STATE',有即成功
[root@slave keepalived]# ip addr '//查看漂移地址是否绑定成功'
...省略内容
inet 10.0.0.100/32 scope global ens33
'//绑定成功 '
...省略内容.....
2.7:主从服务器开启memcache并测试本地连接
-m:指定缓存 -d:指定守护进程 -p:端口号
[root@master shell]# ln -s /usr/local/memcached/bin/* /usr/local/bin/
[root@master shell]# memcached -m 512k -u root -d -l 10.0.0.201 -p 11211
[root@master shell]# netstat -ntap |grep 11211
tcp 0 0 10.0.0.201:11211 0.0.0.0:* LISTEN 100207/memcached
'//设置从服务器'
[root@slave shell]# ln -s /usr/local/memcached/bin/* /usr/local/bin/
[root@slave shell]# memcached -m 512k -u root -d -l 10.0.0.202 -p 11211
[root@slave shell]# netstat -ntap |grep 11211
tcp 0 0 10.0.0.202:11211 0.0.0.0:* LISTEN 22510/memcached
2.9:memcache客户端测试
[root@tom03 ~]# yum install telnet -y
#进行连接
[root@tom03 ~]# telnet 10.0.0.100 12000
Trying 10.0.0.100...
Connected to 10.0.0.100.
Escape character is '^]'.
add shuai 0 0 4 '//客户端插入并新建一个数据'
1234
STORED
#返回主服务器查看是否同步数据
[root@master shell]# telnet 10.0.0.201 11211
Trying 10.0.0.201...
Connected to 10.0.0.201.
Escape character is '^]'.
get shuai '//查看数据'
VALUE shuai 0 4
1234
END
#从服务器进行验证
[root@slave shell]# telnet 10.0.0.202 11211
Trying 10.0.0.202...
Connected to 10.0.0.202.
Escape character is '^]'.
get shuai '//查看数据'
VALUE shuai 0 4
1234
END
'//测试成功,主从都成功生成数据'
客户端直接访问多个 memcache 实例
优点:简单,未引入新的节点;
缺点:维护不方便,未实现集中管理;性能不满足,实例宕机后不能自动踢出(hash 到该实例的请求都要等到超时才能转到其他正常实例)。
[root@master shell]# systemctl stop keepalived.service '//关闭主服务器keepalived服务'
#客户端登录
[root@tom03 ~]# telnet 10.0.0.100 12000 '//客户端登陆成功'
Trying 10.0.0.100...
Connected to 10.0.0.100.
Escape character is '^]'.
set niu 0 0 3
123
STORED
'//从服务器验证'
[root@slave shell]# telnet 10.0.0.202 11211
Trying 10.0.0.202...
Connected to 10.0.0.202.
Escape character is '^]'.
get niu
VALUE niu 0 3
123
END
OK
redis-cli -a redis -h 10.0.0.132 -p 6379
增加此条配置参数:普通则无法查看redis的配置文件,权限不够
禁止redis以root权限去运行,防止被拿到权限后进行写反弹shell操作
useradd -g redis -s /sbin/nologin -M redis # 创建redis用户,并且不可登录
chown -R redis:redis /usr/local/redis/
sudo -u redis /usr/local/bin/redis-server /usr/local/redis/redis.conf
(Redis DataBase)持久化:快速的生成重写文件,基于时间的快照,其默认只保留当前最新的一次快照,特点是比较快,缺点是可能会丢失从上次快照到当前时间点之间未做快照的数据。
RDB实现的具体过程Redis从主进程先fork出一个子进程,使用写时复制机制,子进程将内存的数据保存为一个临时文件,比如dump.rdb.temp,当数据保存完成之后再将上一次保存的RDB文件替换掉,然后关闭子进程,这样可以保证每一次做RDB快照的时候保存的数据都是完整的,因为直接替换RDB文件的时候可能会出现突然新电等问题而导数RDB文件还没有保存完整就突然关机停止保存而导致数摇丢失的情况,可以手动将每次生成的RDB文件进程备份,这样可以最大化保存历史数据。
数据库保存为|RDB|数据库,还原|RDB文件
###:RDB模式的优缺点:
优点:
-RDB快照保存了某个时间点的数据,可以通过脚本执行bgsave(非阻塞)或者save(阻塞)命令自定义时间点备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本。
可以最大化IO的性能,因为父进程在保存RDB文件的时候唯一要做的是fork出一个子进程,然后的操作都会有这个子进程操作,父进程无需任何的1O操作
RDB在大量数据比如几个G的数据,恢复的速度比AOF的快
缺点:
-不能时时的保存数据,会丢失自上一次执行RDB备份到当前的内存数据
数据量非常大的时候,从父进程fork的时候需要一点时间,可能是毫秒或者秒或者分钟,取决于磁盘
append only file,优先级高于RDB优先级,,,,以AOF为准出现问题时,快速的载入数据,肯定是可以让你恢复数据的,
AOF:按照操作顺序依次将操作添加到指定的日志文件当中,特点是数据安全性相对较高,缺点是即使有些操作是重复的也会全部记录。
AOF和RDB一样使用了写时复制机制,AOF默认为每秒钟fsync一次,即将执行的命令保存到AOF文件当中,这样即使redis服务器发生故障的话顶多也就丢失1秒钟之内的数据,也可以设置不同的fsync策略,或者设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到写入AOF文件的
### AOF模式优缺点:
1.AOF的文件大小要大于RDB格式的文件
2.根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存储设备),默认是appendfsync everysec,即每秒执行一次fsync
127.0.0.1:6379> type m43
string
127.0.0.1:6379>LPUSH 1ist1 jack tom
(integer)
3127.0.0.1:6379>TYPE 1ist1
创建集合
127.0.0.1:6379> SADD set1 zhangsan lisi wangwwu
(integer) 3
127.0.0.1:6379> type set1
创建:有序集合zset1,次数1 ,版本:v1
127.0.0.1:6379> zadd zset1 1 v1
(integer) 1
127.0.0.1:6379> type zset1
zset
hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,Redis中每个hash可以存储2^32-1键值对(40多亿)
生成哈希表:
127.0.0.1:6379> hset hash1 name zhangsan age 24 job IT
(integer) 3
127.0.0.1:6379> type hash1
hash
队列当中的消息由不同的生产者写入也会有不同的消费者取出进行消费处理,但是一个消息一定是只能被取出一次也就是被消费一次。
201:
127.0.0.1:6379> Lpush channel1 msg1
(integer) 1
127.0.0.1:6379> Lpush channel1 msg2
(integer) 2
127.0.0.1:6379> Lpush channel1 msg3
(integer) 3
127.0.0.1:6379> Lpush channel1 msg4
(integer) 4
查看队列所有消息
127.0.0.1:6379> lrange channel1 0 -1
1) "msg1"
127.0.0.1:6379> rpop channel1
"msg1"
在发布者订阅者模式下,发布者将消息发布到指定的)channel(频道里面,凡是监听该channel的消费者都会收到同样的一份消息,这种模式类似于是收音机的广播模式,即凡是收听某个频道的听众都会收到主持人发布的相同的消息内容。订阅者同时消费:
数据可以被多个消费者消费,
这种模式用的不是很多,公司一般用不上,但有自己的场景:数据写入相同的三个服务器,监听,通过这种方式实现分布式的数据同步,包括跨机房,主要用于在各个服务之间做数据同步。
127.0.0.1:6379> SUBSCRIBE m43
127.0.0.1:6379> PUBLISH m43 msg1
两台机器就都收到了,但终端2无法收到它启动之前的信息,所以说队列中是不保存那些历史消息的,就像听广播一样,你下午是听不到早上节目的,除非有录音和回放功能。
root@k8s-server1:~# redis-cli
127.0.0.1:6379> SUBSCRIBE m43 m44
作为Key-Value形态的内存数据库,Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数据非常简单,只需要通过string类型将序列化后的对象存起来即可,不过也有一些需要注意的地方:
1.必须保证不同对象的 key 不会重复,并且使 key 尽量短,一般使用类名(表名)加主键拼接而成。
2.选择一个优秀的序列化方式也很重要,目的是提高序列化的效率和减少内存占用。
缓存内容与数据库的一致性,这里一般有两种做法:
1.只在数据库查询后将对象放入缓存,如果对象发生了修改或删除操作,直接清除对应缓存(或设为过期)。
2.在数据库新增和查询后将对象放入缓存,修改后更新缓存,删除后清除对应缓存(或设为过期)。
String 类型,因为 Redis 是分布式的独立服务,可以在多个应用之间共享
例如:分布式Session
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
1
2
3
4
如今都是分布式的环境下java自带的单体锁已经不适用的。在 Redis 2.6.12 版本开始,string的set命令增加了一些参数:
EX:设置键的过期时间(单位为秒)
PX:设置键的过期时间(单位为毫秒)
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。
由于这个操作是原子性的,可以简单地以此实现一个分布式的锁,例如:
set lock_key locked NX EX 1
如果这个操作返回false,说明 key 的添加不成功,也就是当前有人在占用这把锁。而如果返回true,则说明得了锁,便可以继续进行操作,并且在操作后通过del命令释放掉锁。并且即使程序因为某些原因并没有释放锁,由于设置了过期时间,该锁也会在 1 秒后自动释放,不会影响到其他程序的运行。
推荐使用 redisson 第三方库实现分布式锁。
int类型,incrby,利用原子性
incrby userid 1000
分库分表的场景,一次性拿一段
int类型,incr方法
例如:文章的阅读量、微博点赞数、允许一定的延迟,先写入Redis再定时同步到数据库
计数功能应该是最适合 Redis 的使用场景之一了,因为它高频率读写的特征可以完全发挥 Redis 作为内存数据库的高效。在 Redis 的数据结构中,string、hash和sorted set都提供了incr方法用于原子性的自增操作,下面举例说明一下它们各自的使用场景:
如果应用需要显示每天的注册用户数,便可以使用string作为计数器,设定一个名为REGISTERED_COUNT_TODAY的 key,并在初始化时给它设置一个到凌晨 0 点的过期时间,每当用户注册成功后便使用incr命令使该 key 增长 1,同时当每天凌晨 0 点后,这个计数器都会因为 key 过期使值清零。
每条微博都有点赞数、评论数、转发数和浏览数四条属性,这时用hash进行计数会更好,将该计数器的 key 设为weibo:weibo_id,hash的 field 为like_number、comment_number、forward_number和view_number,在对应操作后通过hincrby使hash 中的 field 自增。
如果应用有一个发帖排行榜的功能,便选择sorted set吧,将集合的 key 设为POST_RANK。当用户发帖后,使用zincrby将该用户 id 的 score 增长 1。sorted set会重新进行排序,用户所在排行榜的位置也就会得到实时的更新
等等,redis的应用场景十分广泛,因为它存取速度快,支持并发数量庞大。
zabbix
无论是模式还是被动模式,都是站在zabbix agent角度来说的工作模式,比如被动模式,是说zabbix agent被动的接受zabbix server周期性发送过来的数据收集指令,在被动模式之下,zabbix server会根据主机关联的模板中的监控项和数据采集间隔时间,周期性的打开随机端口并向zabbix agent服务器的10050发起tcp连接,然后发送获取监控项数据的指令,即zabbix server发送什么指令那么zabbix agent就收集什么数据,zabbix server什么时候发送zabbix agent就什么时候采集,zabbix server不发送zabbix agent就一直不响应,所以zabbix agent也不用关心其监控项和数据采集周期间隔时间。
被动模式的优点就是配置简单,安装后即可使用,因此也成为zabbix的默认工作模式,但是波动模式的最大问题就是会加大zabbix server的工作量,在数百甚至数干台服务器的环境下会导致zabbix server需要轮训向每个zabbix agent发送数据采集指令,如果zabbix server负载很高还会导致不能及时获取到最新数据,但由于无需其他复杂配置,被设置为了默认的工作方式。
被动模式端口状态:
被动模式工作流程:
主动模式是由zabbix agent主动向zabbix server的10051端口发起tcp连接请求,因此主动模式下必须在zabbix agent配置文件中指定zabbix server的IP或者主机名(必须可以被解析为IP地址),在连接到zabbix server之前zabbix agent是不知道自己要采集那些数据以及间隔多久采集一次数据的,然后在连接到zabbix server以后获取到自己的监控项和数据采集间隔周期时间,然后再根据监控项采集数据并返回给zabbix server,在主动模式下不再需要zabbix serve向zabbix agent发起连接请求,因此主动模式在一定程度上可减轻zabbix server打开的本地随机端口和进程数,在一定程度就减轻看zabbix server的压力。
apt install openjdk-8-jdk –y
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote -DJava.rmi.server.hostname=10.0.0.203 -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
root@k8s-server3:~# cd /apps/apache-tomcat-8.5.65/
root@k8s-server3:/apps/apache-tomcat-8.5.65# mkdir webapps/yangk
root@k8s-server3:/apps/apache-tomcat-8.5.65# vim webapps/yangk/index.html
tomcat web page
root@k8s-server3:/apps/apache-tomcat-8.5.65# /apps/apache-tomcat-8.5.65/bin/catalina.sh start
找到JDK安装路径:自己安装的路径:G:\Program Files\Java\jdk1.8.0_341\bin
输入ip和端口
测试OK
root@k8s-server1:~# cd /usr/local/src//zabbix-4.0.44/
root@k8s-server1:/usr/local/src/zabbix-4.0.44# ./configure --help | grep java
vim /apps/zabbix_server/sbin/zabbix_java/settings.sh
LISTEN_IP="0.0.0.0"
LISTEN_PORT=10052
START_POLLERS=5 #启用多少个线程
TIMEOUT=30
重启java-getway
root@k8s-server1:/usr/local/src/zabbix-4.0.44# /apps/zabbix_server/sbin/zabbix_java/shutdown.sh
root@k8s-server1:/usr/local/src/zabbix-4.0.44# /apps/zabbix_server/sbin/zabbix_java/startup.sh
查看是否有java
root@k8s-server1:/usr/local/src/zabbix-4.0.44# java –version
/apps/zabbix_server/sbin/zabbix_java/startup.sh
vim /apps/zabbix_server/etc/zabbix_server.conf
JavaGateway=10.0.0.201 JavaGatewayPort=10052
StartJavaPollers=5
重启:/apps/zabbix_server/sbin/zabbix_agentd
成功:监控主机:centos7.2 ip10.0.0.132
改为centos7系统,centos7.12,IP:10.0.0.142
http://10.0.0.142/status
#定义Nginx status页面
ngx_status="http://127.0.0.1/status"
#判断status页面是否存活
ngx_status_code() {
http_code='curl -o /dev/null -s -w %{http_code} ${ngx_status}'
if [ ${http_code} = "200"];then
return 1
else
echo "Nginx status is not running."
fi
}
#获取当前活动的客户端连接数
active() {
ngx_status_code || curl -s ${ngx_status} | grep "Active" | awk '{print $NF}'
}
#获取接收客户端连接的总数量
accepts() {
ngx_status_code || curl -s ${ngx_status} | awk NR==3 | awk '{print $1}'
}
#获取已处理的连接总数量
handled() {
ngx_status_code || curl -s ${ngx_status} | awk NR==3 | awk '{print $2}'
}
#获取客户端请求总数量requests(){
ngx_status_code || curl -s ${ngx_status} | awk NR==3 | awk '{print $3}'
}
#获取正在读取请求标头的当前连接数量
reading() {
ngx_status_code || curl -s ${ngx_status} | grep "Reading" | awk '{print $2}'
}
#获取正在将响应写回到客户端的当前连接数量
writing() {
ngx_status_code || curl-s ${ngx_status} | grep"Writing" | awk'{print $2}'
}
#获取当前正在等待响应的客户端连接数量
waiting() {
ngx_status_code || curt-s ${ngx_status} | grep"Waiting" | awk'{print $2}'
}
#使用位置变量控制脚本输出
case $1 in
active)
active;;
accepts)
accepts;;
handled)
handled;;
requests)
requests;;
reading)
reading;;
writing)
writing;;
waiting)
waiting;;
*)
echo "Unknown options"
esac
添加执行权限:
[root@zbx-agent03 script]# chmod +x ngx_status.sh
10.2自定义监控文件:
[root@zbx-agent03 script]# vim /etc/zabbix/zabbix_agentd.conf
打开自定义监控开关:
UnsafeUserParameters=1
自定义监控路径:
Include=/etc/zabbix/zabbix_agentd.d/*.conf
进入自定义监控路径:写自定义监控文件
vim custom_nginx_status.conf
UserParameter=nginx.active,bash /etc/zabbix/script/ngx_status.sh active
UserParameter=nginx.accepts,bash /etc/zabbix/script/ngx_status.sh accepts
UserParameter=nginx.handled,bash /etc/zabbix/script/ngx_status.sh handled
UserParameter=nginx.requests,bash /etc/zabbix/script/ngx_status.sh requests
UserParameter=nginx.reading,bash /etc/zabbix/script/ngx_status.sh reading
UserParameter=nginx.writing,bash /etc/zabbix/script/ngx_status.sh writing
UserParameter=nginx.waiting,bash /etc/zabbix/script/ngx_status.sh waiting
systemctl restart zabbix-agent
yum install zabbix-get -y
[root@zbx-agent03 zabbix]# cd script/
[root@zbx-agent03 script]#
[root@zbx-agent03 script]# vim redis_status.sh
添加执行权限:chmod +x 文件名
#! /bin/bash
#Name: redis_status.sh
HOST= "127.0.0.1"
PORT=6379
#根据参数信息获取监控信息
if [[ $# == 1 ]];then
case $1 in
version)
result=`redis-cli -h $HOST -p $PORT info | grep -w "redis_version" | awk -F ':' '{print $2}' `
echo $result
;;
uptime)
result=`redis-cli -h $HOST -p $PORT info | grep -w "uptime_in_seconds" | awk -F ':' '{print $2}' `
echo $result
;;
connected_clients)
result=`redis-cli -h $HOST -p $PORT info | grep -w "connected_clients" | awk -F ':' '{print $2}' `
echo $result
;;
blocked_clients)
result=`redis-cli -h $HOST -p $PORT info | grep -w "blocked_clients" | awk -F ':' '{print $2}' `
echo $result
;;
used_memory)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_memory" | awk -F ':' '{print $2}' `
echo $result
;;
used_memory_rss)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_memory_rss" | awk -F ':' '{print $2}' `
echo $result
;;
used_memory_peak)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_memory_peak" | awk -F ':' '{print $2}' `
echo $result
;;
used_memory_lua)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_memory_lua" | awk -F ':' '{print $2}' `
echo $result
;;
used_cpu_sys)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_cpu_sys" | awk -F ':' '{print $2}' `
echo $result
;;
used_cpu_user)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_cpu_user" | awk -F ':' '{print $2}' `
echo $result
;;
used_cpu_sys_children)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_cpu_sys_children" | awk -F ':' '{print $2}' `
echo $result
;;
used_cpu_user_children)
result=`redis-cli -h $HOST -p $PORT info | grep -w "used_cpu_user_children" | awk -F ':' '{print $2}' `
echo $result
;;
rdb_last_bgsave_status)
result=`redis-cli -h $HOST -p $PORT info | grep -w "rdb_last_bgsave_status" | awk -F ':' '{print $2}' | grep -c ok`
echo $result
;;
aof_last_bgrewrite_status)
result=`redis-cli -h $HOST -p $PORT info | grep -w "aof_last_bgrewrite_status" | awk -F ':' '{print $2}' | grep -c ok`
echo $result
;;
aof_last_write_status)
result=`redis-cli -h $HOST -p $PORT info | grep -w "aof_last_write_status" | awk -F ':' '{print $2}' | grep -c ok`
echo $result
;;
*)
echo -e "\033[33mUsage: $0 {connected_clients|blocked_clients|used_memory|used_memory_rss|used_memory_peak|used_memory_lua|used_cpu_sys|used_cpu_user|used_cpu_sys_children|used_cpu_user_children|rdb_last_bgsave_status|aof_last_bgrewrite_status|aof_last_write_status}\033[0m"
;;
esac
elif [[ $ # == 2 ]];then
case $2 in
keys)
result=`redis-cli -h $HOST -p $PORT info | grep -w "$1" | grep -w "keys" | awk -F '=|,' '{print $2}' `
echo $result
;;
expires)
result=`redis-cli -h $HOST -p $PORT info | grep -w "$1" | grep -w "keys" | awk -F '=|,' '{print $4}' `
echo $result
;;
avg_ttl)
result=`redis-cli -h $HOST -p $PORT info | grep -w "$1" | grep -w "avg_ttl" | awk -F '=|,' '{print $6}' `
echo $result
;;
*)
echo -e "\033[33mUsage: $0 {db0 keys|db0 expires|db0 avg_ttl}\033[0m"
;;
esac
fi
[root@zbx-agent03 script]# cd ..
[root@zbx-agent03 zabbix]# cd zabbix_agentd.d/
[root@zbx-agent03 zabbix_agentd.d]# vim custom_redis_status.conf
UserParameter=Redis.Info[*],/etc/zabbix/script/redis _status.sh $1 $2
UserParameter=Redis.Status,(redis-cli -h 127.0.0.1 -p 6379 ping)2>/dev/null |grep -c PONG
重启:systemctl restart zabbix-agent
[root@zbx-agent03 zabbix_agentd.d]# redis-cli info
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:7897e7d0e13773f
redis_mode:standalone
os:Linux 3.10.0-1160.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.5
process_id:5447
run_id:5c1886da58acb30dc09ae388a1dec5ee04001a02
tcp_port:6379
uptime_in_seconds:409094
uptime_in_days:4
hz:10
lru_clock:900690
executable:/usr/bin/redis-server
config_file:/etc/redis.conf
# Clients
connected_clients:7
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
# Memory
used_memory:937712
used_memory_human:915.73K
used_memory_rss:6037504
used_memory_rss_human:5.76M
used_memory_peak:991528
used_memory_peak_human:968.29K
total_system_memory:3953971200
total_system_memory_human:3.68G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:6.44
mem_allocator:jemalloc-3.6.0
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1678316766
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
# Stats
total_connections_received:8
total_commands_processed:68
instantaneous_ops_per_sec:0
total_net_input_bytes:75934
total_net_output_bytes:324126
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:48
keyspace_misses:11
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:398
migrate_cached_sockets:0
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:243.87
used_cpu_user:123.60
used_cpu_sys_children:0.01
used_cpu_user_children:0.00
# Cluster
cluster_enabled:0
重启redis:
systemctl restart redis
[root@zbx-agent03 zabbix_agentd.d]# systemctl status redis
#!/usr/local/python27/bin/python
# author: [email protected]
#
import os, sys, time
import commands
import psutil
import socket
import json
del_list = ["rpc.statd","java"]
def Handle_Connects():
rows = []
lc = psutil.net_connections('inet')
for c in lc:
(ip, port) = c.laddr
if ip == '0.0.0.0' or ip == '::':
if c.type == socket.SOCK_STREAM and c.status == psutil.CONN_LISTEN:
proto_s = 'tcp'
#elif c.type == socket.SOCK_DGRAM:
# proto_s = 'udp'
else:
continue
pid_s = str(c.pid) if c.pid else '(unknown)'
#print pid_s,port
rows.append('%s:%s'%(pid_s,port))
dedup_list = {}.fromkeys(rows).keys()
return dedup_list
def handler_pid(pid,port):
service_dict = {}
p = psutil.Process(int(pid))
if p.as_dict()['name'] == 'jsvc':
service_pname = p.as_dict()['environ']['HOME'].split('/')[3]
service_dict['{#PNAME}'] = service_pname
service_dict['{#PPORT}'] = port
else:
service_pname = p.as_dict()['name']
service_dict['{#PNAME}'] = service_pname
service_dict['{#PPORT}'] = port
return service_dict
def main():
zb_dict = {}
service_list = []
result_list = []
clist = []
for i in Handle_Connects():
pid = i.split(':')[0]
port = i.split(':')[1]
service_list.append(handler_pid(pid,port))
for dictlist in service_list:
if dictlist["{#PNAME}"] in del_list:
result_list.append(dictlist)
#service_list.remove(dictlist)
#print result_list
for delname in service_list:
if delname not in result_list:
clist.append(delname)
zb_dict['data'] = clist
print json.dumps(zb_dict,sort_keys=True,indent=4)
if __name__ == "__main__":
main()
systemctl restart zabbix-agent
#!/usr/bin/python
#coding:utf-8
import json
import urllib.request
from urllib.error import URLError
import sys,argparse
import xlrd
defaultencoding = 'utf-8'
if sys.getdefaultencoding() != defaultencoding:
reload(sys)
sys.setdefaultencoding(defaultencoding)
class zabbix_api:
def __init__(self):
self.url = 'http://zabbix 服务器地址/zabbix/api_jsonrpc.php' #修改URL
self.header = {"Content-Type":"application/json"}
def user_login(self):
data = json.dumps({
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "账号",
"password": "**"
},
"id": 0
})
# data = urllib.parse.quote_plus(data).encode("utf-8")
data = data.encode("utf-8")
request = urllib.request.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
print ("用户认证失败,请检查 !", e.code)
else:
response = json.loads(result.read())
result.close()
self.authID = response['result']
return self.authID
def host_get(self,hostName=''):
data=json.dumps({
"jsonrpc": "2.0",
"method": "host.get",
"params": {
"output": "extend",
"filter":{"host":hostName}
},
"auth": self.user_login(),
"id": 1
})
data = data.encode("utf-8")
request = urllib.request.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
if hasattr(e, 'reason'):
print ('We failed to reach a server.')
print ('Reason: ', e.reason)
elif hasattr(e, 'code'):
print ('The server could not fulfill the request.')
print ('Error code: ', e.code)
else:
response = json.loads(result.read())
#print response
result.close()
print ("主机数量: %s"%(len(response['result'])))
for host in response['result']:
status={"0":"OK","1":"Disabled"}
available={"0":"Unknown","1":"available","2":"Unavailable"}
#print host
if len(hostName)==0:
print ("HostID : %s\t HostName : %s\t Status :%s \t Available :%s"%(host['hostid'],host['name'],status[host['status']],available[host['available']]))
else:
print ("HostID : %s\t HostName : %s\t Status :%s \t Available :%s"%(host['hostid'],host['name'],status[host['status']],available[host['available']]))
return host['hostid']
def hostgroup_get(self, hostgroupName=''):
data = json.dumps({
"jsonrpc":"2.0",
"method":"hostgroup.get",
"params":{
"output": "extend",
"filter": {
"name": hostgroupName
}
},
"auth":self.user_login(),
"id":1,
})
data = data.encode("utf-8")
request = urllib.request.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
print ("Error as ", e)
else:
#print result.read()
response = json.loads(result.read())
result.close()
#print response()
for group in response['result']:
if len(hostgroupName)==0:
print ("hostgroup: %s \tgroupid : %s" %(group['name'],group['groupid']))
else:
print ("hostgroup: %s\tgroupid : %s" %(group['name'],group['groupid']))
self.hostgroupID = group['groupid']
return group['groupid']
def template_get(self,templateName=''):
data = json.dumps({
"jsonrpc":"2.0",
"method": "template.get",
"params": {
"output": "extend",
"filter": {
"name":templateName
}
},
"auth":self.user_login(),
"id":1,
})
data = data.encode("utf-8")
request = urllib.request.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
print ("Error as ", e)
else:
response = json.loads(result.read())
result.close()
#print response
for template in response['result']:
if len(templateName)==0:
print ("template : %s\t id : %s" % (template['name'], template['templateid']))
else:
self.templateID = response['result'][0]['templateid']
print ("Template Name : %s "%templateName)
return response['result'][0]['templateid']
def hostgroup_create(self,hostgroupName):
if self.hostgroup_get(hostgroupName):
print ("hostgroup %s is exist !"%hostgroupName)
sys.exit(1)
data = json.dumps({
"jsonrpc": "2.0",
"method": "hostgroup.create",
"params": {
"name": hostgroupName
},
"auth": self.user_login(),
"id": 1
})
data = data.encode("utf-8")
request=urllib.request.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
print ("Error as ", e)
else:
response = json.loads(result.read())
result.close()
print ("添加主机组:%s hostgroupID : %s"%(hostgroupName,response['result']['groupids']))
def host_create_andy(self,hostName,visibleName, hostip, hostgroupName, templateName):
if self.host_get(hostip):
print ("该主机已经添加!")
sys.exit(1)
group_list=[]
template_list=[]
for i in hostgroupName.split(','):
var = {}
var['groupid'] = self.hostgroup_get(i)
group_list.append(var)
for i in templateName.split(','):
var={}
var['templateid']=self.template_get(i)
template_list.append(var)
data = json.dumps({
"jsonrpc":"2.0",
"method":"host.create",
"params":{
"host": hostName,
"name": visibleName,
"interfaces": [
{
"type": 2, #1:表示IP;2表示SNMP
"main": 1,
"useip": 1,
"ip": hostip,
"dns": "",
"port": "161" #IP端口10051;SNMP端口161
}
],
"groups": group_list,
"templates": template_list,
},
"auth": self.user_login(),
"id":1
})
data = data.encode("utf-8")
request = urllib.request.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
print ("Error as ", e)
else:
response = json.loads(result.read())
result.close()
try:
print ("添加主机 :%s \tid :%s" % (hostip, response['result']['hostids']))
except KeyError as e:
print ("信息 :%s \tid :%s" % (hostip, response['error']['data']))
def host_create(self, hostip, hostgroupName, templateName):
if self.host_get(hostip):
print ("该主机已经添加!")
sys.exit(1)
group_list=[]
template_list=[]
for i in hostgroupName.split(','):
var = {}
var['groupid'] = self.hostgroup_get(i)
group_list.append(var)
for i in templateName.split(','):
var={}
var['templateid']=self.template_get(i)
template_list.append(var)
data = json.dumps({
"jsonrpc":"2.0",
"method":"host.create",
"params":{
"host": hostip,
"interfaces": [
{
"type": 2,
"main": 1,
"useip": 1,
"ip": hostip,
"dns": "",
"port": "161"
}
],
"groups": group_list,
"templates": template_list,
},
"auth": self.user_login(),
"id":1
})
data = data.encode("utf-8")
request = urllib.request.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
print ("Error as ", e)
else:
response = json.loads(result.read())
result.close()
print ("添加主机 : %s \tid :%s" % (hostip, response['result']['hostids']))
def host_disable(self,hostip):
data=json.dumps({
"jsonrpc": "2.0",
"method": "host.update",
"params": {
"hostid": self.host_get(hostip),
"status": 1
},
"auth": self.user_login(),
"id": 1
})
data = data.encode("utf-8")
request = urllib.request.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except URLError as e:
print ("Error as ", e)
else:
response = json.loads(result.read())
result.close()
print ('----主机现在状态------------')
print (self.host_get(hostip))
def host_delete(self,hostid):
hostid_list=[]
#print type(hostid)
for i in hostid.split(','):
var = {}
var['hostid'] = self.host_get(i)
hostid_list.append(var)
data=json.dumps({
"jsonrpc": "2.0",
"method": "host.delete",
"params": hostid_list,
"auth": self.user_login(),
"id": 1
})
data = data.encode("utf-8")
request = urllib.request.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib.request.urlopen(request)
except Exception as e:
print (e)
else:
result.close()
print ("主机 %s 已经删除 !"%hostid)
if __name__ == "__main__":
zabbix=zabbix_api()
parser=argparse.ArgumentParser(description='zabbix api ',usage='%(prog)s [options]')
parser.add_argument('-H','--host',nargs='?',dest='listhost',default='host',help='查询主机')
parser.add_argument('-G','--group',nargs='?',dest='listgroup',default='group',help='查询主机组')
parser.add_argument('-T','--template',nargs='?',dest='listtemp',default='template',help='查询模板信息')
parser.add_argument('-A','--add-group',nargs=1,dest='addgroup',help='添加主机组')
parser.add_argument('-C','--add-host',dest='addhost',nargs=3,metavar=('192.168.2.1', 'test01,test02', 'Template01,Template02'),help='添加主机,多个主机组或模板使用分号')
parser.add_argument('-d','--disable',dest='disablehost',nargs=1,metavar=('192.168.2.1'),help='禁用主机')
parser.add_argument('-L','--allin',dest='allin',nargs='?',default='allin',help='从Excel批量导入主机')
parser.add_argument('-D','--delete',dest='deletehost',nargs='+',metavar=('192.168.2.1'),help='删除主机,多个主机之间用分号')
parser.add_argument('-v','--version', action='version', version='%(prog)s 1.0')
if len(sys.argv)==1:
print (parser.print_help())
else:
args=parser.parse_args()
if args.listhost != 'host' :
if args.listhost:
zabbix.host_get(args.listhost)
else:
zabbix.host_get()
if args.listgroup !='group':
if args.listgroup:
zabbix.hostgroup_get(args.listgroup)
else:
zabbix.hostgroup_get()
if args.listtemp != 'template':
if args.listtemp:
zabbix.template_get(args.listtemp)
else:
zabbix.template_get()
if args.addgroup:
zabbix.hostgroup_create(args.addgroup[0])
if args.addhost:
zabbix.host_create(args.addhost[0], args.addhost[1], args.addhost[2])
if args.disablehost:
zabbix.host_disable(args.disablehost)
if args.deletehost:
zabbix.host_delete(args.deletehost[0])
if args.allin != 'allin':
workbook = xlrd.open_workbook('zabbix_host_add.xlsx') #Excel名
for row in range(workbook.sheets()[0].nrows):
hostname = workbook.sheets()[0].cell(row, 0).value
visible = workbook.sheets()[0].cell(row, 1).value
hostip = workbook.sheets()[0].cell(row, 2).value
hostgroup = workbook.sheets()[0].cell(row, 3).value
hosttemp = workbook.sheets()[0].cell(row, 4).value
zabbix.host_create_andy(hostname,visible,hostip,hostgroup, hosttemp)
7.12(node1) 7.13(node2)
wget --no-check-certificate https://mirrors.tuna./zabbix/5.0/rhel/7/x86_64/zabbix-agent-5.0.0-1.el7.x86_64.rpm
rpm -ivh zabbix-agent-5.0.0-1.el7.x86_64.rpm
vim /etc/zabbix/zabbix_agentd.conf
systemctl restart zabbix-agent
systemctl enable zabbix-agent
如果觉得对您有用,请点个赞哦♪(^∀^●) ↓↓↓