ZabbixServer端配置
Zabbix服务器需安装java,编译需添加启动参数–enable-java 本次安装的编译参数为:
./configure --prefix=/data/zabbix/ --enable-server --enable-agent --with-mysql --enable-ipv6 --with-net-snmp --with-libcurl --with-libxml2 --enable-java
ZabbixAgent端配置
ZabbixAgent端不仅需要安装zabbix_agentd,还需要安装zabbix_sender,可以通过地址http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/ 选择合适的版本。 安装 rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-sender-3.0.9-1.el7.x86_64.rpm
监控原理
微服务的特性:
每个进程是直接以java-jar service.jar
的方式启动,并没有依赖于tomcat或者其他web应用。
每台服务器上的微服务并没有固定的数量,可以灵活的增加或者减少。
每个微服务的启动参数已有配置端口很多。
鉴于此种情况,传统的监控方法监控微服务,会造成经常的手动去增加删减web页面配置,服务器内的端口管理也会很混乱。
所以使用discovery自动发现的方式去监控微服务。并将每个微服务的信息通过zabbix_sender发送到ZabbixServer端。
关于微服务的信息主要通过jstat获取,如下
# ps -ef|grep java
root 1891 1 0 Apr02 ? 00:09:38 java -Xms500M -Xmx500M -Xmn400M -XX:+PrintGCDetails -jar /data/work/service_jar/orderService.jar --server.port=14000 --management.port=14001 --config.profile=test
root 17860 1 0 Mar26 ? 00:27:17 java -Xms500M -Xmx500M -Xmn400M -XX:+PrintGCDetails -jar /data/work/service_jar/systemService.jar --server.port=21000 --management.port=21001 --config.profile=test
root 18444 1 0 Mar26 ? 00:39:28 java -Xms500M -Xmx500M -Xmn400M -XX:+PrintGCDetails -jar /data/work/service_jar/resourceService.jar --server.port=18000 --management.port=18001 --config.profile=test
root 18619 1 0 Mar26 ? 00:27:06 java -Xms500M -Xmx500M -Xmn400M -XX:+PrintGCDetails -jar /data/work/service_jar/userService.jar --server.port=13000 --management.port=13001 --config.profile=test
root 19601 1 0 Mar26 ? 00:22:37 java -Xms1000M -Xmx1000M -Xmn800M -jar /data/work/service_jar/manageMiddle.jar --server.port=20000 --management.port=20001 --config.profile=test
root 31282 17046 0 17:00 pts/3 00:00:00 grep --color=auto java
# jstat -gc 1891
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
9216.0 8704.0 4320.0 0.0 391680.0 246746.7 102400.0 77473.4 83112.0 80407.4 9896.0 9400.6 94 1.742 3 0.762 2.504
# jstat -gcutil 1891
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
46.88 0.00 63.00 75.66 96.75 94.99 94 1.742 3 0.762 2.504
# jstat -gccapacity 1891
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
409600.0 409600.0 409600.0 9216.0 8704.0 391680.0 102400.0 102400.0 102400.0 102400.0 0.0 1122304.0 83112.0 0.0 1048576.0 9896.0 94 3
Jdk1.8中取消了永久区Perm
监控脚本
脚本很多调试内容已注释,请忽略,脚本路径及内容:
# pwd
/etc/zabbix/scripts/java
[root@gbw_test_app03 java]# cat jstat.py
#!/usr/bin/env python
#coding=utf-8
'''
功能: 调用jstat获取JVM的各项指标
说明: 用于zabbix自动发现告警
版本: V1.0 2019-04-01
特性: 1. 线程功能,提高脚本执行速度
'''
import datetime
import time
import sys
import os
import commands
import subprocess
import json
import argparse
import socket
import threading
jstat_cmd = commands.getoutput("which jstat")
jstack_cmd = commands.getoutput("which jstack")
jvmname_cmd = "jps -l |grep -Ev 'Jps|JStack|Jstat'|awk '{print $2,$1}'"
jvmport_cmd = "netstat -tpnl|grep -oP '(?<=:)\d+.*\d+(?=/java)'|awk '{print $1,$NF}'"
hostname = socket.gethostname()
zbx_sender='/usr/bin/zabbix_sender'
zbx_cfg='/etc/zabbix/zabbix_agentd.conf'
zbx_tmp_file='/etc/zabbix/scripts/java/.zabbix_jvm_status'
'''
output=sys.stdout
outputfile=open("/etc/zabbix/scripts/java/log.txt","a")
sys.stdout=outputfile
now = time.time()
t = time.localtime(int(now))
dt = time.strftime("%Y%m%d%H%M%S", t)
print dt
'''
jvm_threads = []
def get_status(cmd,opts,pid):
value = commands.getoutput('%s -%s %s' % (cmd,opts,pid)).strip().split('\n')
#print value[0].split(' ')
#print value[1].split(' ')
#print filter(None, value[0].split(' '))
#print filter(None, value[1].split(' '))
if filter(None, value[0].split(' ')):
if filter(None, value[1].split(' ')):
kv = []
for i in filter(None, value[0].split(' ')):
if i != '':
kv.append(i)
vv = []
for i in filter(None, value[1].split(' ')):
if i != '':
vv.append(i)
data = dict(zip(kv,vv))
return data
else:
pass
else:
pass
'''
kv = []
for i in filter(None, value[0].split(' ')):
if i != '':
kv.append(i)
vv = []
for i in filter(None, value[1].split(' ')):
if i != '':
vv.append(i)
data = dict(zip(kv,vv))
return data
'''
def get_thread(cmd,pid):
value = commands.getoutput('sudo %s %s|grep http|wc -l' % (cmd,pid))
data = {"Thread":value}
return data
def get_jvm(jport,jprocess):
'''
使用jstat获取Java的性能指标
'''
file_truncate() # 清空zabbix_data_tmp
gcutil_data = get_status(jstat_cmd,"gcutil",jprocess)
gccapacity_data = get_status(jstat_cmd,"gccapacity",jprocess)
gc_data = get_status(jstat_cmd,"gc",jprocess)
thread_data = get_thread(jstack_cmd,jprocess)
data_dict = dict(gcutil_data.items()+gccapacity_data.items()+gc_data.items()+thread_data.items())
for jvmkey in data_dict.keys():
zbx_data = "%s jvm[%s,%s] %s" %(hostname,jport,jvmkey,data_dict[jvmkey])
with open(zbx_tmp_file,'a') as file_obj: file_obj.write(zbx_data + '\n')
def jvm_name_discovery():
output = subprocess.Popen(jvmname_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
jvm_name_lists = output.stdout.readlines()
jvm_name_proce = []
for jvm_name_tmp in jvm_name_lists:
jvm_name_proce.append(jvm_name_tmp.split())
return jvm_name_proce
def jvm_port_discovery():
output = subprocess.Popen(jvmport_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
jvm_port_lists = output.stdout.readlines()
jvm_port_proce = []
for jvm_port_tmp in jvm_port_lists:
jvm_port_proce.append(jvm_port_tmp.split())
return jvm_port_proce
def file_truncate():
'''
用于清空zabbix_sender使用的临时文件
'''
with open(zbx_tmp_file,'w') as fn: fn.truncate()
def zbx_tmp_file_create():
'''
创建zabbix_sender发送的文件内容
'''
jvmname_list = jvm_name_discovery()
for jvm_name_tmp in jvmname_list:
jvmname = jvm_name_tmp[0]
jvmprocess = jvm_name_tmp[1]
th = threading.Thread(target=get_jvm,args=(jvmname,jvmprocess))
th.start()
jvm_threads.append(th)
def send_data_zabbix():
'''
调用zabbix_sender命令,将收集的key和value发送至zabbix server
'''
zbx_tmp_file_create()
for get_jvmdata in jvm_threads:
get_jvmdata.join()
zbx_sender_cmd = "%s -c %s -i %s" %(zbx_sender,zbx_cfg,zbx_tmp_file)
print zbx_sender_cmd
zbx_sender_status,zbx_sender_result = commands.getstatusoutput(zbx_sender_cmd)
#print zbx_sender_status
print zbx_sender_result
def zbx_name_discovery():
'''
用于zabbix自动发现JVM名称
'''
jvm_zabbix = []
jvmname_list = jvm_name_discovery()
for jvm_tmp in jvmname_list:
jvm_zabbix.append({'{#JNAME}' : jvm_tmp[0],
'{#JPROCESS}' : jvm_tmp[1],
})
return json.dumps({'data': jvm_zabbix}, sort_keys=True, indent=7,separators=(',', ':'))
def zbx_port_discovery():
'''
用于zabbix自动发现JVM端口
'''
jvm_zabbix = []
jvmport_list = jvm_port_discovery()
for jvm_tmp in jvmport_list:
jvm_zabbix.append({'{#JPORT}' : jvm_tmp[0],
'{#JPROCESS}' : jvm_tmp[1],
})
return json.dumps({'data': jvm_zabbix}, sort_keys=True, indent=7,separators=(',', ':'))
def cmd_line_opts(arg=None):
class ParseHelpFormat(argparse.HelpFormatter):
def __init__(self, prog, indent_increment=5, max_help_position=50, width=200):
super(ParseHelpFormat, self).__init__(prog, indent_increment, max_help_position, width)
parse = argparse.ArgumentParser(description='JVM监控"',
formatter_class=ParseHelpFormat)
parse.add_argument('--version', '-v', action='version', version="1.0", help='查看版本')
parse.add_argument('--jvmname', action='store_true', help='获取JVM名称')
parse.add_argument('--jvmport', action='store_true', help='获取JVM端口')
parse.add_argument('--data', action='store_true', help='发送JVM指标数据至zabbix')
if arg:
return parse.parse_args(arg)
if not sys.argv[1:]:
return parse.parse_args(['-h'])
else:
return parse.parse_args()
if __name__ == '__main__':
opts = cmd_line_opts()
if opts.jvmname:
print zbx_name_discovery()
elif opts.jvmport:
print zbx_port_discovery()
elif opts.data:
send_data_zabbix()
else:
cmd_line_opts(arg=['-h'])
脚本使用方法
# ./jstat.py -h
usage: jstat.py [-h] [--version] [--jvmname] [--jvmport] [--data]
JVM监控"
optional arguments:
-h, --help show this help message and exit
--version, -v 查看版本
--jvmname 获取JVM名称
--jvmport 获取JVM端口
--data 发送JVM指标数据至zabbix
# ./jstat.py --version
1.0
# ./jstat.py --jvmname
{
"data":[
{
"{#JNAME}":"manageMiddle.jar",
"{#JPROCESS}":"19601"
},
{
"{#JNAME}":"orderService.jar",
"{#JPROCESS}":"1891"
},
{
"{#JNAME}":"systemService.jar",
"{#JPROCESS}":"17860"
},
{
"{#JNAME}":"userService.jar",
"{#JPROCESS}":"18619"
},
{
"{#JNAME}":"resourceService.jar",
"{#JPROCESS}":"18444"
}
]
}
# ./jstat.py --jvmport
{
"data":[
{
"{#JPORT}":"14000",
"{#JPROCESS}":"1891"
},
{
"{#JPORT}":"18000",
"{#JPROCESS}":"18444"
},
{
"{#JPORT}":"14001",
"{#JPROCESS}":"1891"
},
{
"{#JPORT}":"18001",
"{#JPROCESS}":"18444"
},
{
"{#JPORT}":"20000",
"{#JPROCESS}":"19601"
},
{
"{#JPORT}":"20001",
"{#JPROCESS}":"19601"
},
{
"{#JPORT}":"13000",
"{#JPROCESS}":"18619"
},
{
"{#JPORT}":"21000",
"{#JPROCESS}":"17860"
},
{
"{#JPORT}":"13001",
"{#JPROCESS}":"18619"
},
{
"{#JPORT}":"21001",
"{#JPROCESS}":"17860"
}
]
}
# ./jstat.py --data
/usr/bin/zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -i /etc/zabbix/scripts/java/.zabbix_jvm_status
info from server: "processed: 170; failed: 0; total: 170; seconds spent: 0.001286"
sent: 170; skipped: 0; total: 170
.zabbix_jvm_status文件中存储要发送到server端的值,文件的权限为:
# ll .zabbix_jvm_status
-rw-r--rw- 1 root root 686 Apr 4 15:15 .zabbix_jvm_status
如果文件权限不是646,最好重新授权。
监控项解释:
- NGCMN:新生代最小容量
- NGCMX:新生代最大容量
- NGC:当前新生代容量
- OGCMN:老年代最小容量
- OGCMX:老年代最大容量
- OGC:当前老年代大小
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:元数据空间大小
- MU:元数据空间使用大小
- M:元数据空间使用百分比
- EC:Eden区大小
- EU:Eden区使用大小
- E:Eden区使用百分比
- S0C:第一个幸存区大小
- S0U:第一个幸存区使用大小
- S0:第一个幸存区使用百分比
- S1C:第二个幸存区大小
- S1U:第二个幸存区使用大小
- S1:第二个幸存区使用百分比
- OC:老年代大小
- OU:老年代使用大小
- O:老年代使用百分比
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- CCS:压缩类空间使用百分比
- YGCT:年轻代GC消耗时间
- YGC:年轻代GC次数
- FGCT:老年代GC消耗时间
- FGC:老年代GC次数
- GCT:GC消耗总时间
- Thread:线程数
- userparameter配置
路径及内容如下
# pwd
/etc/zabbix/zabbix_agentd.d
# cat userparameter_java_discovery_status.conf
UserParameter=jvmname,/usr/bin/python /etc/zabbix/scripts/java/jstat.py --jvmname
UserParameter=jvmdata,/usr/bin/python /etc/zabbix/scripts/java/jstat.py --data
zabbix_agentd.conf配置如下
# cat zabbix_agentd.conf |grep -Ev '^$|^#'
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server=172.19.138.53
ListenPort=10050
ServerActive=172.19.138.53
Hostname=gbw_test_app03
Timeout=10
AllowRoot=1
Include=/etc/zabbix/zabbix_agentd.d/
为了防止脚本执行超时,出现报错ZBX_NOTSUPPORTED,修改默认Timeout=3为Timeout=10。 AllowRoot=1是给Agent服务提升权限,并且会以root用户启动(默认为zabbix用户),这样是不安全的。 在生产环境中不建议配置AllowRoot=1,使用以下方式替代:
ll /etc/sudoers
-r--r----- 1 root root 3938 Sep 6 2017 /etc/sudoers
# chmod 640 /etc/sudoers #修改可写权限
# vim /etc/sudoers #添加下面这一句
zabbix ALL=(ALL) NOPASSWD: ALL
# chmod 440 /etc/sudoers #恢复权限
# ll /etc/sudoers
-r--r----- 1 root root 3937 Apr 3 17:20 /etc/sudoers
配置完成后重启agent客户端,确保是以zabbix用户启动。
模板配置
模板地址:https://download.csdn.net/download/u010571301/12610278。 导入模板关联主机即可。
转自 https://www.cnops.top/posts/748ad64f.html
评论列表,共 0 条评论
暂无评论