目录
监控什么
1、安装部署
服务器
服务器安装
服务器页面设置
中文作文
图形汉字乱码
代理方
引入代理配置文件
自动检测并安装
步骤1 创建自动发现规则
步骤2 创建检测动作
嘿嘿,是不是还缺什么?
2.添加监控
1.添加监控主机
添加主机组
添加主机
2.添加监控项
各类监测项目单位
3. 触发
触发值选择
设置触发器
4.报警媒体
电子邮件课程
测试
最重要的
5. 添加用户
添加用户
为用户添加报警媒体
为用户添加主机权限
6.添加动作
添加动作
检查操作是否被触发
7. 可视化
添加自定义图形
摘要图
幻灯片放映
拓扑结构
8. 自定义模板
创建模板
使用自定义模板
9.宏
定义宏
使用宏
10.自动检测监控项目(LLD)
3.用户参数(自定义按键)
1.格式
、使用状态显示
3、更新版本如何使用(带参数的监控项)
4. 网络检测
设置自动发现规则
5、agent端多种监控方式
1.主动监控
作品
设置主动监控
使用发送器手动发送数据
2.SNMP方法
在Linux 上启用SNMP
设置SNMP 监控
配置对传入和传出数据包的SNMP 监控
6、分布式监控
1.添加zabbix-proxy主机服务器配置。
2. 页面设置
3.添加代理监控主机
7. 开始监控
1.监控php-fpm服务状态
2. Web服务器监控
创建网络监视器
查看网络监控
3.监控Tomcat
4.监控mysql
生存监测
其他性能监控
5.0版本新方法
8.常用自定义监控项
1.mysql
2.女士
3.nginx
4.TCP相关
5、系统内常用监控项
6.自定义系统常用监控项
9.Zabbix优化
1. 数据库
引擎
数据库
2、监控项目优化
3. 将代理运行模式更改为主动或使用分布式代理。
4.优化涉及的进程数
设置自动检测
缓存设置
十、使用过程中遇到的问题
1、root被占用,因为监控的服务器太多。
迁移zabbix使用的mysql
11. 报警处理
Zabbix服务器:超过75%被历史缓存使用
监控什么
服务器
CPU使用率、内存、网卡输入、网卡输出增加(有或没有流量尖峰;一般情况下流量永远不会超过一定值),进口–》可被攻击,出口–可能受木马(肉鸡)影响)
应用程序
Python、Java、PHP
服务
nginx、tomcat、httpd
开源监控
扎比克斯
Prometheus(使用go语言定时监控)—— 监控容器和微服务
打开风扇
一、安装部署
官方中文安装指南
lcon(小米的)
服务端
服务端安装
#安装zabbix仓库
rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
#安装zabbix服务器和代理
yum -y zabbix-server-mysql 安装zabbix-agent
# 安装红帽软件集合(仓库)
安装yum -y centos-release-scl
# 编辑仓库配置文件/etc/yum.repos.d/zabbix.repo并启用zabbix-frontend仓库
[Zavix前端]
.
有效=1
.
#安装Zabbix前端包
yum -y zabbix-web-mysql-scl 安装zabbix-nginx-conf-scl
# 进入数据库
#创建zabbix数据库
创建数据库zabbix字符集utf8排序规则utf8_bin;
#创建zabbix用户
创建一个由“密码”标识的用户zabbix@localhost。
授权
将zabbix.* 上的所有权限授予zabbix@localhost。
# 导入初始模式和数据后,系统将提示您输入新创建的密码
zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz mysql -uzabbix -p 密码zabbix | zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz
# 数据库设置
vim /etc/zabbix/zabbix_server.conf
DB密码=密码
# 配置rh-nginx
vim /etc/opt/rh/rh-nginx116/nginx/nginx.conf
删除服务器内容
# 配置nginx子配置文件
vim /etc/opt/rh/rh-nginx116/nginx/conf.d/zabbix.conf
取消注释并设置listen 和server_name。
# PHP 设置
vim /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf
# 将nginx添加到listen.acl_users指令的值中
Listen.acl_users=apache、nginx
# 取消下面的注释并设置正确的时区
php_value[日期.时区]=亚洲/上海
# 启动zabbix服务
systemctl 重新启动zabbix-server zabbix-agent rh-nginx116-nginx rh-php72-php-fpm
如果mysql使用的是8.x版本,zabbix-server将无法正常启动。这是因为mysql 8.x版本的密码加密方法与之前的不同。您可以进入数据库并更改密码加密方法。 Zabbix 用户。
# 报告的具体错误为ERROR 2059 (HY000): Unable to loadauthentication plugin \’caching_sha2_password\’ : /usr/lib64/mysql/plugin/caching_sha2_password.so: Unable to open shared object file : No such file or There are no paths
# 变更流程, 1. 首先查看当前规则。
从mysql.user 中选择主机、用户和插件。
+————+—————-+——————– —–+
| 主机用户|
+————+—————-+——————– —–+
本地主机| 缓存_sha2_密码|
本地主机| 缓存_sha2_密码|
本地主机| 缓存_sha2_密码|
本地主机密码|
本地主机| 缓存_sha2_密码|
+————+—————-+——————– —–+
5 行组(0.00 秒)
# 插件是密码加密规则。可以看到zabbix用户的加密规则是caching_sha2_password,之前版本使用的加密规则是mysql_native_password。因此,我们需要恢复加密规则。
# 第二步更改加密规则
修改“Bumy313@.2021”标识的用户“zabbix”@“localhost”,并且不设置密码过期。
修改mysql_native_password中“Bumy313@.2021”标识的用户“zabbix”@“localhost”。
# 再看一遍
+————+—————-+——————– —–+
| 主机用户|
+————+—————-+——————– —–+
本地主机| 缓存_sha2_密码|
本地主机| 缓存_sha2_密码|
本地主机| 缓存_sha2_密码|
本地主机密码|
| 本地主机|
+————+—————-+——————– —–+
5 行组(0.00 秒)
# 现在重新启动zabbix-server,你会看到它可以启动成功。
服务端页面配置
要访问和配置zabbix,只需直接在网页中输入IP和端口即可。
输入Zabbix 服务器的主机名或主机IP 地址和端口号以及安装名称(可选)。最终的Name值是可选的,表示已安装的zabbix服务器的角色。这是因为Zabbix是一个分布式监控系统,可以有一个服务器角色和多个代理角色。
还有一个步骤需要验证信息,我忘记截图了,但是一旦确定正确,就可以继续下一步。
至此zabbix的安装就完成了。
默认登录用户名是Admin,密码是zabbix。
如果成功,进入仪表板
中文配置
图形中文乱码
图形汉字乱码
首先,在Windows 中找到您喜欢的字体文件。具体路径为C:\\Windows\\Fonts(可以选择文件右键查看属性)。
找到合适的匹配后,将其上传到您的服务器,将文件放在/usr/share/zabbix/assets/fonts 目录中,并将文件后缀更改为小写ttf。
接下来,define(\’ZBX_GRAPH_FONT_NAME\’, \’graphfont\’) //更改配置文件/usr/share/zabbix/include/defines.inc.php中的字体文件名。字体文件(无后缀)。换句话说,是的。无需重新启动服务。要启用它,只需刷新您的zabbix 页面即可。
agent 端
使用yum 安装
#安装zabbix仓库
rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
# 安装zabbix代理
yum -y zabbix 安装代理
# 修改配置文件,添加服务器IP。有关更多信息,请参阅下面的配置文件概述。
vim /etc/zabbix/zabbix_agentd.conf
开始
systemctl 重新启动zabbix-agent
二进制安装
# 下载二进制包
wget https://cdn.zabbix.com/zabbix/binaries/stable/5.0/5.0.7/zabbix_agent-5.0.7-linux-3.0-amd64-static.tar.gz
# 解压
mkdir /usr/local/zabbix-agent
tar -xf zabbix_agent-5.0.7-linux-3.0-amd64-static.tar.gz -C /usr/local/zabbix-agent
# 添加zabbix用户
用户添加了zabix
# 注意:默认情况下,即使使用“root”用户启动该程序,该程序最终也会以“zabbix”用户启动。此时请确保系统中存在“zabbix”用户。
# 指定启动的配置文件
/usr/local/zabbix_agent/sbin/zabbix_agentd -c /usr/local/zabbix_agent/conf/zabbix_agentd.conf
agent 配置文件介绍
############ 一般参数################
#####被动检查相关的被动模式
### 选项: 服务器
Server=127.0.0.1 # 被动模式下zabbix server的地址,即哪些主机可以发送指令。
# 修改服务器IP
###可选:监听端口
# ListenPort=10050 # Agent自己的监听端口
### 可选: ListenIP
# ListenIP=0.0.0.0 # Agent自己的监听地址
##### 主动检查相关主动模式
### 选项: 服务器活动
ServerActive=127.0.0.1 # Active模式主动向这些服务器上报监控数据。
### 可选: 主机名
# 主机名=
Hostname=Zabbix Server # 服务器端代理端的标识码。无需改变。
自动发现并安装
自动发现、自动安装代理、自动添加模板、自动添加监控项、自动添加触发器、自动添加动作。
这意味着您可以一次性完成从发现到监控的所有过程。
step 1 创建自动发现规则
设置要检测的IP段
step 2 创建发现动作
记下此路径并确保选择左上角的“检测”操作,然后单击“创建操作”。
新动作需要添加两个条件
第一个是您在第一步中创建的检测规则,它执行ping。
其次,它必须是可ping 通的。
这两个条件必须是and(同时满足)。
添加条件后,添加操作,即满足上述条件时采取的操作。
执行远程命令。该代理不会自动安装,因此您必须创建一个脚本来执行此步骤。
安装并配置代理后,添加主机
添加主机组
添加模板
至此,机器就从头开始创建并自动监控了。
啥,还缺东西
但事实并非如此。我刚刚看了脚本的功能和名称,但我仍然不知道它是关于什么的。
我们将使用nginx 检索并运行脚本,该脚本将自动安装和配置代理。
nginx 没有什么特别的。只需构建常规nginx,将脚本放在其根目录中,然后使用curl 即可获取它。
# 如果您想使用它,请在更改IP之前仔细阅读此脚本。
创建_yum(){
echo -e \’\'[yumop]
名称=Sentos 7.6
Baseurl=http://128.1.70.1/centos
有效=1
gpg检查=0
[玉魔铺2]
名称=Sentos7.7
基本网址=http://128.2.42.165:8090
有效=1
gpgcheck=0 \’\’\’ /etc/yum.repos.d/1.repo
嗯,把所有东西都清理干净
百胜赚钱
}
# 检查代理是否已经存在
rpm -qa|grep zabbix-agent
如果[[ $? -eq 0 ]];那么
出口0
菲
# 检查yum源是否正确
如果[[ -e /etc/yum.repos.d/1.repo ]];那么
grep \’baseurl=http://128.1.70.1/centos\’ /etc/yum.repos.d/1.repo /dev/null grep \’baseurl=http://128.2.42.165:8090\’ /etc/yum.repos.d/1.repo /dev/null
如果[[ $? -ne 0 ]];那么
创建_yum
菲
除此之外
mkdir /etc/yum.repos.d/bak mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak
如果[[ $? -eq 0 ]];那么
创建_yum
除此之外
99号出口
菲
菲
# 下载代理
安装yum -y zabbix-agent /dev/null
如果[[ $? -eq 0 ]];那么
sed -i \’/^Server=/cServer=128.2.64.153\’ /etc/zabbix/zabbix_agentd.conf \\
sed -i \’/^ServerActive==/cServerActive==128.2.64.153\’ /etc/zabbix/zabbix_agentd.conf \\
systemctl 重新启动zabbix-agent.service
菲
二、添加监控
1、添加被监控的主机
在实际操作中,被监控的主机中总会有主机需要监控相同的内容。例如,对于Nginx集群,集群中的所有主机都必须监控nginx进程。此时,您需要创建一个主机组,并将主机组添加到该主机组中。接下来,配置与该主机组相关的监控项。
添加主机组
添加主机
添加的主机必须在配置文件中配置监控方式和服务器IP。
在添加监视项目之前,监视模式(可用性)指示灯不会点亮。
2、添加监控项
初始可选监视器包括:
记下监控项的键值net.dns[ip,name,type,timeout,count,protocol]。方括号中的一些是可选的,其他的是必需的。您可以在这里查看具体参数。
我设置的时候忘记截图了,直接点了一下就显示了,所以我就在这里更新一下
配置完成后,您可以查看被监控主机的状态。
关于监控项单位的种种
注意:只要初始值大于或等于1000,Zabbix就会通过除以1000或1024来处理数据。如果结果仍然大于或等于1000,则继续除以1000或1024。直到得到的结果小于1000。
3、触发器
触发值选择
设置触发器
last(1)代表最后一秒
last(#1) 表示最后一次
4、报警媒介
在Zabbix 中,发送通知的主要方式称为警报媒体类型。默认情况下,报警媒体类型有多种。
电子邮件类
#报警模板
活动: {EVENT.NAME}
活动主持人: {HOST.NAME}
活动时间: {EVENT.DATE} {EVENT.TIME}
事件级别: {TRIGGER.SEVERITY}
活动信息: {TRIGGER.NAME}
活动项目: {TRIGGER.KEY1}
活动详情: {ITEM.NAME} : {ITEM.VALUE}
当前状态: {TRIGGER.STATUS} : {ITEM.VALUE1}
事件ID: {EVENT.ID}
操作数据: {EVENT.OPDATA}
{触发.URL}
测试
Mattermost
由于我们公司是内网环境,通讯依赖Mattermost,所以报警也依赖Mattermost。 Zabbix 有一个默认的警报模板,您可以通过一些修改来使用。
trigger_description 报警描述
//您还可以更改默认脚本来控制显示格式。以下是脚本的全文,其中有注释标记了可以进行更改的地方。
var SEVERITY_COLORS=[
\’#97AAB3\’, \’#7499FF\’, \’#FFC859\’,
“#FFA059”、“#E97659”、“#E45959”
];
var RESOLVE_COLOR=\’#009900\’;
var SEND_MODE_HANDLERS={
警报: 处理程序警报,
事件: 处理程序事件
};
if (!String.prototype.format) {
String.prototype.format=function() {
var args=参数;
返回this.replace(/{(\\d+)}/g, 函数(匹配, 数字) {
返回号码
r in args
? args[number]
: match
;
});
};
}
function isEventProblem(params) {
return params.event_value == 1
&& params.event_update_status == 0
;
}
function isEventUpdate(params) {
return params.event_value == 1
&& params.event_update_status == 1
;
}
function isEventResolve(params) {
return params.event_value == 0;
}
function getPermalink(mattermost_url, team_name, postid) {
return \'{0}/{1}/pl/{2}\’.format(
mattermost_url.replace(/\\/+$/, \’\’),
team_name,
postid
);
}
function getChannel(send_to) {
switch (true) {
case /.+\\/#.+/.test(send_to):
return getChannelByName(send_to);
case /@.+/.test(send_to):
return getDirectChannel(send_to);
default:
return getChannelByID(send_to);
}
}
function getChannelByName(send_to) {
var team_chan = send_to
.trim()
.split(\’/#\’);
var resp = JSON.parse(req.Get(
Mattermost.channel_byname.format(team_chan[0], team_chan[1]),
JSON.stringify(fields)
)
);
if (req.Status() != 200) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
return resp;
}
function getDirectChannel(send_to) {
Zabbix.Log(5, \'[ Mattermost Webhook ] Call {0}({1})\’.format(
arguments.callee.name,
JSON.stringify(arguments)
));
var teamUser = send_to
.trim()
.split(\’/@\’),
bot = getBotUser(),
user = getUserByName(teamUser[1]);
var resp = JSON.parse(req.Post(
Mattermost.direct_channel,
JSON.stringify([bot.id, user.id])
)
);
Zabbix.Log(5, \'[ Mattermost Webhook ] Result {0}: {1}\’.format(
arguments.callee.name,
JSON.stringify(resp)
));
if (req.Status() != 201) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
resp.team_name = teamUser[0];
return resp;
}
function getChannelByID(channelID) {
Zabbix.Log(5, \'[ Mattermost Webhook ] Call {0}({1})\’.format(
arguments.callee.name,
JSON.stringify(arguments)
));
var resp = JSON.parse(req.Get(
Mattermost.get_channel.format(channelID),
JSON.stringify(fields)
)
);
Zabbix.Log(5, \'[ Mattermost Webhook ] Result {0}: {1}\’.format(
arguments.callee.name,
JSON.stringify(resp)
));
if (req.Status() != 200) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
return resp;
}
function getBotUser() {
Zabbix.Log(5, \'[ Mattermost Webhook ] Call {0}({1})\’.format(
arguments.callee.name,
JSON.stringify(arguments)
));
var resp = JSON.parse(req.Get(
Mattermost.bot_user,
JSON.stringify(fields)
)
);
Zabbix.Log(5, \'[ Mattermost Webhook ] Result {0}: {1}\’.format(
arguments.callee.name,
JSON.stringify(resp)
));
if (req.Status() != 200) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
return resp;
}
function getUserByName(userName) {
Zabbix.Log(5, \'[ Mattermost Webhook ] Call {0}({1})\’.format(
arguments.callee.name,
JSON.stringify(arguments)
));
var resp = JSON.parse(req.Get(
Mattermost.user_byname.format(userName),
JSON.stringify(fields)
)
);
Zabbix.Log(5, \'[ Mattermost Webhook ] Result {0}: {1}\’.format(
arguments.callee.name,
JSON.stringify(resp)
));
if (req.Status() != 200) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
return resp;
}
function getTeamByID(teamID) {
Zabbix.Log(5, \'[ Mattermost Webhook ] Call {0}({1})\’.format(
arguments.callee.name,
JSON.stringify(arguments)
));
var resp = JSON.parse(req.Get(
Mattermost.get_team.format(teamID),
JSON.stringify(fields)
)
);
Zabbix.Log(5, \'[ Mattermost Webhook ] Result {0}: {1}\’.format(
arguments.callee.name,
JSON.stringify(resp)
));
if (req.Status() != 200) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
return resp;
}
function createProblemURL(zabbix_url, triggerid, eventid, event_source) {
var problem_url = \’\’;
if (event_source === \’0\’) {
problem_url = \'{0}/tr_events.php?triggerid={1}&eventid={2}\’
.format(
zabbix_url,
triggerid,
eventid
);
}
else {
problem_url = zabbix_url;
}
return problem_url;
}
function getTagValue(event_tags, key) {
var pattern = new RegExp(\'(\’ + key + \’:.+)\’);
var tagValue = event_tags
.split(\’,\’)
.filter(function (v) {
return v.match(pattern);
})
.map(function (v) {
return v.split(\’:\’)[1];
})[0]
|| 0;
return tagValue;
}
function handlerAlarm(req, params) {
var channel = getChannel(params.send_to);
var fields = {
channel_id: channel.id,
props: {}
};
if (isEventProblem(params)) {
var team_name = channel.team_name
? channel.team_name
: getTeamByID(channel.team_id).name;
fields.props.attachments = [
createMessage(
SEVERITY_COLORS[params.event_nseverity] || 0,
params.event_date,
params.event_time,
createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
)
];
var resp = JSON.parse(req.Post(
Mattermost.post_message,
JSON.stringify(fields)
)
);
if (req.Status() != 201) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
result.tags.__mattermost_post_id = resp.id;
result.tags.__mattermost_channel_id = channel.id;
result.tags.__mattermost_channel_name = channel.name;
result.tags.__mattermost_message_link = getPermalink(
params.mattermost_url,
team_name,
resp.id
);
}
else if (isEventUpdate(params)) {
fields.root_id = getTagValue(params.event_tags, \’mattermost_post_id\’);
if (params.event_source === \’0\’) {}
fields.props.attachments = [
createMessage(
SEVERITY_COLORS[params.event_nseverity] || 0,
params.event_update_date,
params.event_update_time,
createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
true
)
];
resp = JSON.parse(req.Post(
Mattermost.post_message, JSON.stringify(fields)
)
);
if (req.Status() != 201) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
}
else if (isEventResolve(params)) {
fields.channel_id = getTagValue(params.event_tags, \’mattermost_channel_id\’);
fields.id = getTagValue(params.event_tags, \’mattermost_post_id\’);
fields.props.attachments = [
createMessage2(
RESOLVE_COLOR,
params.event_date,
params.event_time,
createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
)
];
var post_id = getTagValue(params.event_tags, \’mattermost_post_id\’);
resp = JSON.parse(req.Put(
Mattermost.chat_update.format(post_id),
JSON.stringify(fields)
)
);
if (req.Status() != 200) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
}
}
function handlerEvent(req, params) {
var channel = getChannel(params.send_to);
var fields = {
channel_id: channel.id,
props: {}
};
if (isEventProblem(params)) {
var team_name = channel.team_name
? channel.team_name
: getTeamByID(channel.team_id).name;
fields.props.attachments = [
createMessage(
SEVERITY_COLORS[params.event_nseverity] || 0,
params.event_date,
params.event_time,
createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
)
];
var resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
if (req.Status() != 201) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
result.tags.__mattermost_channel_name = channel.name;
result.tags.__mattermost_message_link = getPermalink(
params.mattermost_url,
team_name,
resp.id
);
}
else if (isEventUpdate(params)) {
fields.props.attachments = [
createMessage(
SEVERITY_COLORS[params.event_nseverity] || 0,
params.event_update_date,
params.event_update_time,
createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
false
)
];
resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
if (req.Status() != 201) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message);
}
}
else if (isEventResolve(params)) {
fields.props.attachments = [
createMessage2(
RESOLVE_COLOR,
params.event_recovery_date,
params.event_recovery_time,
createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
)
];
resp = JSON.parse(req.Post(Mattermost.post_message2, JSON.stringify(fields)));
if (req.Status() != 201) {
throw \'[{0}] {1}\’.format(resp.status_code, resp.message2);
}
}
}
// 从这里开始就是设置 恢复状态 信息格式的地方
function createMessage2(
event_severity_color,
event_date,
event_time,
problem_url,
isShort
) {
var message2 = {
fallbac: params.alert_subject,
title: params.alert_subject,
color: event_severity_color,
footer: \”最终解释权归运维所有\”, // 这里是信息下标,
fields: [
{
title: \’IP:\’,
value: \'{0}\’.format(params.host_ip),
short: true
},
{
title: \’解决时间:\’,
value: \'{0} {1}\’.format(event_date, event_time),
short: true
}
],
};
if (params.event_source === \’0\’) {
message2.fields.push(
{
title: \’严重程度\’,
value: params.event_severity,
short: true
}
);
}
if (!isShort && params.event_source === \’0\’) {
message2.fields.push(
{
title: \’状态\’,
value: \’已解决\’,
short: true
}
);
}
if (params.event_source !== \’0\’ || params.event_update_status === \’1\’) {
message2.fields.push(
{
title: \’Details\’,
value: params.alert_message,
short: false
}
);
}
return message2;
}
// 这里是设置 报警状态 信息格式的位置
function createMessage(
event_severity_color,
event_date,
event_time,
problem_url,
isShort
) {
var message = {
fallbac: params.alert_subject,
title: params.alert_subject,
color: event_severity_color,
footer: \”最终解释权归运维所有\”,
fields: [
{
title: \’IP:\’,
value: \'{0}\’.format(params.host_ip),
short: true
},
{
title: \’发生时间:\’,
value: \'{0} {1}\’.format(event_date, event_time),
short: true
}
],
};
if (params.event_source === \’0\’) {
message.fields.push(
{
title: \’严重程度\’,
value: params.event_severity,
short: true
}
);
}
if (!isShort && params.event_source === \’0\’) {
message.fields.push(
{
title: \’告警描述\’,
value: params.trigger_description,
short: true
}
);
}
if (params.event_source !== \’0\’ || params.event_update_status === \’1\’) {
message.fields.push(
{
title: \’Details\’,
value: params.alert_message,
short: false
}
);
}
return message;
}
function validateParams(params) {
if (typeof params.bot_token !== \’string\’ || params.bot_token.trim() === \’\’) {
throw \’Field \”bot_token\” cannot be empty\’;
}
if (isNaN(params.event_id)) {
throw \’Field \”event_id\” is not a number\’;
}
if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {
throw \’Incorrect \”event_source\” parameter given: \”\’ + params.event_source + \’\”.\\nMust be 0-3.\’;
}
if (params.event_source !== \’0\’) {
params.event_nseverity = \’0\’;
params.event_severity = \’Not classified\’;
params.event_update_status = \’0\’;
params.send_mode = \’event\’;
}
if (params.event_source === \’1\’ || params.event_source === \’2\’) {
params.event_value = \’1\’;
}
if (params.event_source === \’1\’) {
params.host_name = params.discovery_host_dns;
params.host_ip = params.discovery_host_ip;
}
if ([0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity)) === -1) {
throw \’Incorrect \”event_nseverity\” parameter given: \’ + params.event_nseverity + \’\\nMust be 0-5.\’;
}
if (typeof params.event_severity !== \’string\’ || params.event_severity.trim() === \’\’) {
throw \’Field \”event_severity\” cannot be empty\’;
}
if (params.event_update_status !== \’0\’ && params.event_update_status !== \’1\’) {
throw \’Incorrect \”event_update_status\” parameter given: \’ + params.event_update_status + \’\\nMust be 0 or 1.\’;
}
if (params.event_value !== \’0\’ && params.event_value !== \’1\’) {
throw \’Incorrect \”event_value\” parameter given: \’ + params.event_value + \’\\nMust be 0 or 1.\’;
}
if (typeof params.host_ip !== \’string\’ || params.host_ip.trim() === \’\’) {
throw \’Field \”host_ip\” cannot be empty\’;
}
if (typeof params.host_name !== \’string\’ || params.host_name.trim() === \’\’) {
throw \’Field \”host_name\” cannot be empty\’;
}
if (typeof params.mattermost_url !== \’string\’ || params.mattermost_url.trim() === \’\’) {
throw \’Field \”mattermost_url\” cannot be empty\’;
}
if (!/^(http|https):\\/\\/.+/.test(params.mattermost_url)) {
throw \’Field \”mattermost_url\” must contain a schema\’;
}
if ([\’alarm\’, \’event\’].indexOf(params.send_mode) === -1) {
throw \’Incorrect \”send_mode\” parameter given: \’ + params.send_mode + \’\\nMust be \”alarm\” or \”event\”.\’;
}
if (typeof params.send_to !== \’string\’ || params.send_to.trim() === \’\’) {
throw \’Field \”send_to\” cannot be empty\’;
}
if (isNaN(params.trigger_id) && params.event_source === \’0\’) {
throw \’field \”trigger_id\” is not a number\’;
}
if (typeof params.zabbix_url !== \’string\’ || params.zabbix_url.trim() === \’\’) {
throw \’Field \”zabbix_url\” cannot be empty\’;
}
if (!/^(http|https):\\/\\/.+/.test(params.zabbix_url)) {
throw \’Field \”zabbix_url\” must contain a schema\’;
}
}
try {
var params = JSON.parse(value);
validateParams(params);
var req = new CurlHttpRequest(),
fields = {},
result = {tags: {}};
if (typeof params.HTTPProxy === \’string\’ && params.HTTPProxy.trim() !== \’\’) {
req.SetProxy(params.HTTPProxy);
}
req.AddHeader(\’Content-Type: application/json; charset=utf-8\’);
req.AddHeader(\’Authorization: Bearer \’ + params.bot_token);
params.mattermost_url = params.mattermost_url.replace(/\\/+$/, \’\’);
params.zabbix_url = params.zabbix_url.replace(/\\/+$/, \’\’);
var APIEndpoint = params.mattermost_url + \’/api/v4/\’;
var Mattermost = {
post_message: APIEndpoint + \’posts\’,
get_channel: APIEndpoint + \’channels/{0}\’,
get_team: APIEndpoint + \’teams/{0}\’,
chat_update: APIEndpoint + \’posts/{0}\’,
direct_channel: APIEndpoint + \’channels/direct\’,
channel_byname: APIEndpoint + \’teams/name/{0}/channels/name/{1}\’,
user_byname: APIEndpoint + \’users/username/{0}\’,
bot_user: APIEndpoint + \’users/me\’
};
params.send_mode = params.send_mode.toLowerCase();
params.send_mode = params.send_mode in SEND_MODE_HANDLERS
? params.send_mode
: \’alarm\’;
SEND_MODE_HANDLERS[params.send_mode](req, params);
if (params.event_source === \’0\’) {
return JSON.stringify(result);
}
else {
return \’OK\’;
}
}
catch (error) {
Zabbix.Log(4, \'[ Mattermost Webhook ] Mattermost notification failed: \’ + error);
throw \’Mattermost notification failed: \’ + error;
}
5、添加用户
用户的类型有管理员和超级管理员
添加用户
为用户添加报警媒介
如果用户没有添加报警媒介则无法使用该媒介进行报警2
为用户添加主机权限
刚添加的用户是无法看到已经监控的任何一台服务器的,原因是没有赋予用户权限
此时再将用户添加至这个用户组中,再进行登录,就可以看到那些服务器了
6、添加动作
Zabbix 的动作,主要作用是当触发器被触发后,执行相关操作的。
要创建动作需要有两个必须的元素:
条件 规定什么情况下执行此动作
操作 动作具体操作什么
操作可以是:
发送通知 执行系统的内部命令 操作可以是多个步骤,是按照设置好的顺序依次执行的。
发送通知 和 执行内部命令 可以单独使用他们,也可以让两者一起配合使用。 比如可以在服务器意外停止的时候,先执行 一个内部命令,假如执行命令后,服务仍然没有恢复为 正常状态。则可以再发送一个通知。
添加动作
关于步骤就是起始步骤到下一个步骤,假如执行的步骤只有一步,这里可以选择 1 – 1
步骤持续时间 是此步骤执行完毕需要多长时间,比如发送一封电子邮件可能需要 1 秒,删除一些没有的文件需要 1 分钟,重启一个 Java 的应用程序需要 5 分钟等。 但是这里的取值只能是 0 或者 60-604800(单位是秒) 其中的一个。 这里设置的时间会覆盖之前的 默认操作步骤持续时间,假设这里使用 0, 就会使用之前的 默认操作步骤持续时间 的值(默认是 1h)
发送消息可以是一个或多个组,也可以是一个或多个具体的用户。 这里我仅仅选择一个我之前创建的用户 shark
仅送到
仅送到
这里就是选择以那种 报警媒介 发送通知消息
一个用户是可以有多个 报警媒介 的,比如电子邮件,企业微信、钉钉等。
可以选择所有的,也可以i选择某一个。
这里我选择的是之前创建的报警媒介。如下图:
Custom message 是否在这里自定义消息,假如这里设置了,就会覆盖在 报警媒介类型中设置的消息模板。这里我们不做进一步的操作。
条件 这个需要为此此操作步骤设置一个触发条件 此步骤不是必须的
验证动作是否触发
注意:假如你设置了这个动作之前,触发器已经被触发了,并且当前获取的数据之一处于触发器指标的外部,则触发器不会重复产生事件,只能等触发器再次被触发产生新的问题才行。如下图就是这种情况:
7、可视化
zabbix 提供了众多的可视化工具直观展示,如 graph、screen 及 map 等。前面也看到过一些简单的图形展示。如果想要把多个相关的数据定义在同一张图上去查看,就需要去自定义图形
自定义图形中可以集中展示多个时间序列的数据流。支持四种不同形式的图形
线状图(normal)
堆叠面积图(stacked)、
饼图(pie)”
分离型饼图(exploded)
添加自定义图形
设置过程如下:进入 配置 —> 主机 —> node1 —> 图形,选择右上角创建图形:
聚合图形
幻灯片
拓扑图
在拓扑图中,可以定义成一个复杂的网络连接图,可以使用一台主机来连接另一台主机,这样的话,就可以查看出到底是哪个链接出了问题
8、自定义模板
每一个主机的监控项都很多,一个一个的添加实在是太头疼了,更何况,可能不止一个主机。可以把一个 redis 的监控项添加进一个模板里,这样更方便于我们以后的添加。
创建模板
模板中的监控项、触发器等的添加和上面的步骤一样
使用自定义模板
也可以在创建主机时直接使用已有模板
9、宏
宏是一种抽象(Abstraction),它根据一系列预定义的规则替换一定的文本模式,而解释器或编译器在遇到宏时会自动进行这一模式替换。类似地,zabbix基于宏保存预设文本模式,并且在调用时将其替换为其中的文本。
zabbix有许多内置的宏,如{HOST.NAME}、{HOST.IP}、{TRIGGER.DESCRIPTION}、{TRIGGER.NAME}、{TRIGGER.EVENTS.ACK}等。
详细信息请参考官方文档
就是定义一个变量 起一个值
宏一共有三种级别,分别是全局宏、模板宏、主机宏。不同级别的宏的适用范围也不一样。
全局宏也可以作用于所有的模板宏和主机宏,优先级最低。
模板宏则可以作用于所有使用该模板的主机,优先级排在中间。
主机宏则只对单个主机有效,优先级最高。
宏的类型
宏的类型分为系统内建的宏和用户自定义的宏。
为了更强的灵活性,zabbix还支持在全局、模板或主机级别使用用户自定义宏(user macro)。
系统内建的宏在使用的时候需要{MACRO}的语法格式,用户自定义宏要使用{$MACRO}这种特殊的语法格式。
宏可以应用在item keys和descriptions、trigger名称和表达式、主机接口IP/DNS及端口、discovery机制的SNMP协议的相关信息中……
宏的名称只能使用大写字母、数字及下划线。
进一步信息请参考官方文档。
定义宏
全局宏
模板宏和主机宏和上述方法类似,一个在模板里面找,一个在主机里面找
使用宏
可以在任何地方使用
使用效果
10、监控项自动发现(LLD)
自动发现(LLD)提供了一种为受监控节点的不同监控指标自动创建监控项,触发器和图形的分发;此外还可以配置 Zabbix 根据定期执行发现后得到的实际结果,来移除不需要的监控。
暂时只用到了系统自带的一些监控,并没有自己创建的需求,所以暂不做,如有想法可以百度。
三、用户参数(自定义key)
自定义用户参数,也就是自定义key,有时可能想要运行一个代理检查,而不是 Zabbix 的预定义,就可以编写一个命令来检索需要的数据,并将其包含在代理配置文件(\”UserParameter\”配置参数)的用户参数中
1、格式
UserParameter=<key>,<command>
# 等号右边固定,key就类似于net.tcp.listen,command就是linux中的命令
# 配置完成后需要重新启动agent端
、用法展示
选择一个命令,例如free | awk \’/^Mem/{print $3}\’
添加用户参数
cd /etc/zabbix/zabbix_agentd.d/
vim memory_usage.conf
UserParameter=memory.used,free | awk \’/^Mem/{print $3}\’
# 重启服务
systemctl restart zabbix-agent.service
# 在server端查询
zabbix_get -s agent端的IP -p 10050 -k \”memory.used\”
# 这个命令在agent源码包解压后的bin目录中
在监控项中使用该参数
3、升级版用法(带参数的监控项)
添加一个带参数的key
先找到一个命令,例如cat /proc/meminfo
添加用户参数
cd /etc/zabbix/zabbix_agentd.d/
vim memory_usage.conf
UserParameter=memory.stats[*],cat /proc/meminfo | awk \’/^$1/{print $$2}\’
# $$2:表示不是调前边位置参数的$2 ,而是 awk 的参数 $2
# $1是调用前边的[*],位置参数,第一个参数
# 重启服务
systemctl restart zabbix-agent.service
# 在server端查询
./zabbix_get -s 10.9.29.117 -p 10050 -k \”memory.stats[MemTotal]\”
> 1863252
./zabbix_get -s 10.9.29.117 -p 10050 -k \”memory.stats[Cache]\”
> 133400
四、网络发现
设置自动发现规则
五、agent端各种监控方式
主动与被动都是对于agent端而言的
被动检测:server向agent请求获取配置的各监控项相关的数据,agent接收请求、获取数据并响应给server;
主动检测:agent向server请求与自己相关监控项配置,主动地将server配置的监控项相关的数据发送给server;
前面介绍的都是被动模式
1、主动监控
配置
# 配置文件中
vim /etc/zabbix/zabbix_agentd.conf
# 给哪个监控server 发送数据
ServerActive=serverIP
Hostname=node1.qfedu.com # 自己的主机名,假设主机定死了,不设置下一项
#HostnameItem= # 如果自己的主机名易变动,这一项相当于key一样去匹配
# 若后两项同时启用,下边一个选择生效
设置一个主动监控
主动模式下,右侧ZBX不会亮起
使用sender手动发送数据
首先需要配置一个采集器
zabbix_sender
-z zabbix_server_ip
-p zabbix_server_port
-s zabbix_agent_hostname
-k key
-o value 值
zabbix_sender -z 10.9.29.116 -p 10050 -s song1 -k system.cpu.switches -o 9999
2、snmp方式
SNMP:简单网络管理协议;(非常古老的协议)
三种通信方式:读(get, getnext)、写(set)、trap(陷阱);
端口:161/udp 162/udp
为无法安装agent服务的设备使用,例如交换机,路由器
linux启用snmp
# 安装
yum install net-snmp net-snmp-utils
# 配置文件:定义ACL(访问控制列表)
vim /etc/snmp/snmpd.conf
# 可用的视图 OID
# 示例:.1.3.6.1.2.1.1.1.0 系统描述信息
.1.3.6.1.2.1.
1.1.0:系统描述信息,SysDesc
1.3.0:监控时间, SysUptime
1.5.0:主机名,SysName
1.7.0:主机提供的服务,SysService
.1.3.6.1.2.2.
2.1.0:网络接口数目
2.2.1.2:网络接口的描述信息
2.2.1.3:网络接口类型
# 启动
# 被监控端开启的服务
systemctl start snmpd
# 监控端开启的服务(如果允许被监控端启动主动监控时启用)
systemctl start snmptrapd
# 测试
snmpget -v 2c -c public 被测试主机的IP OID
snmpwalk -v 2c -c public HOST OID # 通过这个端口查询到的数据,全列出了
# 例子
snmpget -v 2c -c public 10.9.29.117 .1.3.6.1.2.1.1.1.0
> SNMPv2-MIB::sysDescr.0 = STRING: Linux tomcat2 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64
snmpwalk -v 2c -c public 10.9.29.117 .1.3.6.1.2.1.1.1.0
> SNMPv2-MIB::sysDescr.0 = STRING: Linux tomcat2 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64
snmpwalk -v 2c -c public 10.9.29.117 .1.3.6.1.2.1.1.1.1
> SNMPv2-MIB::sysDescr.1 = No Such Instance currently exists at this OID
配置snmp监控
# 添加视图
vim /etc/snmp/snmpd.conf
view systemview included .1.3.6.1.2.1.1
view systemview included .1.3.6.1.2.1.2 # 网络接口的相关数据
view systemview included .1.3.6.1.4.1.2021 # 系统资源负载,memory, disk io, cpu load
view systemview included .1.3.6.1.2.1.25
可以添加以下模板,方便观察
设置入站出站packets 的SNMP监控
监控网络设备:交换机、路由器的步骤:
把交换机、路由器的SNMP 把对应的OID的分支启用起来
了解这些分支下有哪些OID,他们分别表示什么意义
我们要监控的某一数据:如交换机的某一个接口流量、报文,发送、传入传出的报文数有多少个;传入传出的字节数有多少个,把OID取出来,保存
# 入站
interface traffic packets(in)
# 出站
interface traffic packets(out)
六、分布式监控
Zabbix代理可以代表Zabbix服务器收集性能和可用性数据。这样,代理可以承担一些收集数据的负担,并减轻Zabbix服务器的负担。
1、添加zabbix-proxy主机—服务器设置
# 安装zabbix-proxy
rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
yum -y install zabbix-proxy-mysql zabbix-get zabbix-agent zabbix-sender
# 为zabbix-proxy配置数据库,该数据库必须是独立的,不能和server端使用一个
create database zabbix_proxy character set utf8 collate utf8_bin;
create user zabbix@localhost identified by \’password\’;
grant all privileges on zabbix_proxy.* to zabbix@localhost;
# 导入数据
zcat /usr/share/doc/zabbix-proxy-mysql*/schema.sql.gz | mysql -uzabbix -p密码 zabbix_proxy
# 配置zabbix-proxy
vi /etc/zabbix/zabbix_proxy.conf
# 数据库信息
DBHost=localhost
DBName=zabbix_proxy
DBUser=zabbix
DBPassword=密码
# 配置服务
# 代理模式 0 主动上报给 Zabbix Server, 1 被动,默认 0
ProxyMode=0
Server=Zabbix 服务器的IP
# 唯一的、区分大小写的代理名称。确保服务器知道代理名称!如果未定义,则从HostnameItem获取值。
Hostname=bj-proxy
# 允许日志文件最大多少 MB, 默认是 0,就是不限制大小,也就是不进行日志切割
LogFileSize=2
# 即使数据已经与服务器同步,代理也会在本地保留N个小时。如果第三方应用程序将使用本地数据,则可以使用此参数。默认 0
ProxyLocalBuffer=0
# 如果没有与Zabbix服务器连接,代理将保留数据N小时。旧数据将丢失。默认 1
ProxyOfflineBuffer=1
# 心跳消息的频率(秒)。用于监控服务器端代理的可用性。0-已禁用心跳消息。对于处于被动模式的代理,此参数将被忽略。默认 60
HeartbeatFrequency=60
# 向服务端更新监控配置的间隔时间。为了快速看到实验效果,这里设置5秒,默认3600秒
ConfigFrequency=5
# 向服务端发送监控数据的间隔时间,单位秒
DataSenderFrequency=5
# 启动服务
systemctl start zabbix-proxy.service
# 在被zabbix-proxy监控的agent端将IP设置为zabbix-proxy的IP
vi /etc/zabbix/zabbix_agentd.conf
# Zabbix Proxy 的 IP
Server=192.168.122.100
# 假如开启了 agent 的主动模式,这里也是 Zabbix Proxy 的 IP
ServerActive=192.168.122.100
2、页面设置
3、为proxy添加监控主机
这里嫌麻烦直接修改已有主机,添加新的也很简单,自己摸索
修改完毕后,如果数据正常输出,就表示成功
七、开始监控
1、监控php-fpm服务状态
# 下载php-fpm
yum -y install php-fpm
# 打开php-fpm的状态页面
vim /etc/php-fpm.d/www.conf
user = nginx
group = nginx
pm.status_path = /status # php-fpm 的状态监测页面
ping.path = /ping # ping 接口,存活状态是否ok
ping.response = pong # 响应内容pong
# 开启服务
systemctl start php-fpm
# 设置nginx
vim /etc/nginx/nginx.conf
location ~ \\.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* /(status|ping) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
include fastcgi_params;
allow 127.0.0.1; # 因为这个页面很重要,所有需加访问控制
deny all;
access_log off; # 访问这个页面就不用记录日志了
}
# 复制状态信息页面到网站根目录
cp /usr/share/fpm/status.html /usr/share/nginx/html/
# 开启nginx
systemctl start nginx
# 查看状态
curl 127.0.0.1/status
# 添加用户参数
cd /etc/zabbix/zabbix_agentd.d/
vim php_status.conf
UserParameter=php-fpm.stats[*],curl -s http://127.0.0.1/status | awk \’/^$1/{print $$NF}\’
# 设置用户参数为php-fpm.stats[*],$1为第一个参数;$$NF为awk中的参数,倒数第一列
# 重启服务
systemctl restart zabbix-agent
# 在server端检查
./zabbix_get -s 10.9.29.117 -p 10050 -k \”php-fpm.stats[idle]\”
./zabbix_get -s 10.9.29.117 -p 10050 -k \”php-fpm.stats[active]\”
./zabbix_get -s 10.9.29.117 -p 10050 -k \”php-fpm.stats[max active]\”
# 后续添加监控项自行解决
2、web服务器监控
例如nginx,httpd,监测流量,上传速度,下载速度,并发数
创建web监控
查看web监控
3、监控tomcat
Java虚拟机(JVM)具有内置的插件,使您能够使用JMX监视和管理它。您还可以使用JMX监视工具化的应用程序。
# server端
# 安装 zabbix-java-gateway程序包
yum -y install zabbix-java-gateway
# 配置javagateway
vim /etc/zabbix/zabbix_java_gateway.conf # 安装完后,会生成一个java_gateway 的配置文件
LISTEN_IP=\”0.0.0.0\” #监听服务器地址
LISTEN_PORT=10052 #监听zabbix_java进程的端口,默认是10052
PID_FILE=\”/tmp/zabbix_java.pid\” #zabbix_java的pid路径
START_POLLERS=5 #zabbix_java的进程数
TIMEOUT=10 #zabbix_java的超时时间
# 可不用修改,直接开启服务
systemctl start zabbix-java-gateway.service
# 设置server端
vim /etc/zabbix/zabbix_server.conf
JavaGateway=172.16.0.70 #即 zabbix server IP地址
JavaGatewayPort=10052
StartJavaPollers=5 #监控项
# 重启服务
systemctl restart zabbix-server
# agent端
# 在agent端安装tomcat
yum -y install java-1.8.0-openjdk-devel tomcat-admin-webapps tomcat-docs-webapp
# 配置tomcat
vim /etc/sysconfig/tomcat
CATALINA_OPTS=\”-Djava.rmi.server.hostname=本机IP -Djavax.management.builder.initial= -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false\”
# 启动服务
systemctl start tomcat
页面设置
然后稍候片刻,如果配置没错就可以看到JMX变绿,且可以查看到最新数据
4、监控mysql
需求一:监控MySQL的状态,当状态发生异常,发出报警;
需求二:监控MySQL的操作,并用图表展现;
存活监测
# 创建一个普通用户,并授权
grant usage on *.* to zabbix@127.0.0.1 identified by \’QFedu@123\’;
# 创建一个包含用户名和密码的文件
mkdir /var/lib/zabbix/
vim /var/lib/zabbix/.my.cnf
[mysqladmin]
user=zabbix
host=127.0.0.1
password=\’QFedu@123\’
# 使用这个命令监测
HOME=/var/lib/zabbix/ mysqladmin ping |grep -c alive
# 存活输出1 不存活输出2
# 添加自定义key
vim /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf
UserParameter=mysql.ping,HOME=/var/lib/zabbix mysqladmin ping | grep -c alive
# 检查命令是否正常
/usr/sbin/zabbix_agentd -t mysql.ping
> mysql.ping [t|1]
# 重启服务
systemctl restart zabbix-agent.service
# 在server端检查
./zabbix_get -s 10.9.29.117 -p 10050 -k \”mysql.ping\”
其他性能监测
使用一个自定义的shell脚本来进行监测
# 添加一个自定义的key
vim /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf
# 监控mysql性能的脚本
UserParameter=mysql.status[*],/etc/zabbix/zabbix_agentd.d/check_mysql.sh $1
# 查看版本
UserParameter=mysql.version,mysql -V
# 脚本内容
vim /etc/zabbix/zabbix_agentd.d/check_mysql.sh
#!/bin/bash
# ——————————————————————————-
# FileName: check_mysql.sh
# Revision: 1.0
# ——————————————————————————-
# Copyright:
# License: GPL
# 用户名
MYSQL_USER=\’zabbix\’
# 密码
MYSQL_PWD=\’QFedu@123\’
# 主机地址/IP
MYSQL_HOST=\’127.0.0.1\’
# 端口
MYSQL_PORT=\’3306\’
# 数据连接
MYSQL_CONN=\”/usr/bin/mysqladmin -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_PORT}\”
# 参数是否正确
if [ $# -ne \”1\” ];then
echo \”arg error!\”
fi
# 获取数据
case $1 in
Uptime)
result=`${MYSQL_CONN} status 2>/dev/null |cut -f2 -d\”:\”|cut -f1 -d\”T\”`
echo $result
;;
Com_update)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Com_update\”|cut -d\”|\” -f3`
echo $result
;;
Slow_queries)
result=`${MYSQL_CONN} status 2>/dev/null |cut -f5 -d\”:\”|cut -f1 -d\”O\”`
echo $result
;;
Com_select)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Com_select\”|cut -d\”|\” -f3`
echo $result
;;
Com_rollback)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Com_rollback\”|cut -d\”|\” -f3`
echo $result
;;
Questions)
result=`${MYSQL_CONN} status 2>/dev/null |cut -f4 -d\”:\”|cut -f1 -d\”S\”`
echo $result
;;
Com_insert)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Com_insert\”|cut -d\”|\” -f3`
echo $result
;;
Com_delete)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Com_delete\”|cut -d\”|\” -f3`
echo $result
;;
Com_commit)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Com_commit\”|cut -d\”|\” -f3`
echo $result
;;
Bytes_sent)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Bytes_sent\” |cut -d\”|\” -f3`
echo $result
;;
Bytes_received)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Bytes_received\” |cut -d\”|\” -f3`
echo $result
;;
Com_begin)
result=`${MYSQL_CONN} extended-status 2>/dev/null |grep -w \”Com_begin\”|cut -d\”|\” -f3`
echo $result
;;
*)
echo \”Usage:$0(Uptime|Com_update|Slow_queries|Com_select|Com_rollback|Questions|Com_insert|Com_delete|Com_commit|Bytes_sent|Bytes_received|Com_begin)\”
;;
esac
# 授权
chmod +x /etc/zabbix/zabbix_agentd.d/check_mysql.sh
chown zabbix.zabbix /etc/zabbix/zabbix_agentd.d/check_mysql.sh
# 在server端检查
./zabbix_get -s 10.9.29.117 -p 10050 -k \”mysql.status[Com_update]\”
./zabbix_get -s 10.9.29.117 -p 10050 -k \”mysql.status[Uptime]\”
5.0版本新方法
上面的只是给你提示可以这么做,在新版本中,操作更为便利
然后,下载模板文件,或者直接复制
文件地址
# 创建一个包含用户名和密码的文件
mkdir /var/lib/zabbix/
vim /var/lib/zabbix/.my.cnf
[mysqladmin]
user=zabbix
host=127.0.0.1
password=\’QFedu@123\’
# 或者你懒得去看,直接复制这个
vim /etc/zabbix/zabbix_agentd.d/Template_DB_MySQL.conf
#template_db_mysql.conf created by Zabbix for \”Template DB MySQL\” and Zabbix 4.2
#For OS Linux: You need create .my.cnf in zabbix-agent home directory (/var/lib/zabbix by default)
#For OS Windows: You need add PATH to mysql and mysqladmin and create my.cnf in %WINDIR%\\my.cnf,C:\\my.cnf,BASEDIR\\my.cnf https://dev.mysql.com/doc/refman/5.7/en/option-files.html
#The file must have three strings:
#[client]
#user=\’zbx_monitor\’
#password=\'<password>\’
#
UserParameter=mysql.ping[*], mysqladmin -h\”$1\” -P\”$2\” ping
UserParameter=mysql.get_status_variables[*], mysql -h\”$1\” -P\”$2\” -sNX -e \”show global status\”
UserParameter=mysql.version[*], mysqladmin -s -h\”$1\” -P\”$2\” version
UserParameter=mysql.db.discovery[*], mysql -h\”$1\” -P\”$2\” -sN -e \”show databases\”
UserParameter=mysql.dbsize[*], mysql -h\”$1\” -P\”$2\” -sN -e \”SELECT COALESCE(SUM(DATA_LENGTH + INDEX_LENGTH),0) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=\’$3\’\”
UserParameter=mysql.replication.discovery[*], mysql -h\”$1\” -P\”$2\” -sNX -e \”show slave status\”
UserParameter=mysql.slave_status[*], mysql -h\”$1\” -P\”$2\” -sNX -e \”show slave status\”
# 重启服务
systemctl restart zabbix-agent.service
八、常用自定义监控项
1、mysql
version:数据库版本
key_buffer_size:myisam的索引buffer大小
sort_buffer_size:会话的排序空间(每个线程会申请一个)
join_buffer_size:这是为链接操作分配的最小缓存大小,这些连接使用普通索引扫描、范围扫描、或者连接不适用索引
max_connections:最大允许同时连接的数量
max_connect_errors:允许一个主机最多的错误链接次数,如果超过了就会拒绝之后链接(默认100)。可以使用flush hosts命令去解除拒绝
open_files_limits:操作系统允许mysql打开的文件数量,可以通过opened_tables状态确定是否需要增大table_open_cache,如果opened_tables比较大且一直还在增大说明需要增大table_open_cache
max-heap_tables_size:建立的内存表的最大大小(默认16M)这个参数和tmp_table_size一起限制内部临时表的最大值(取这两个参数的小的一个),如果超过限制,则表会变为innodb或myisam引擎,(5.7.5之前是默认是myisam,5.7.6开始是innodb,可以通过internal_tmp_disk_storage_engine参数调整)。
max_allowed_packet:一个包的最大大小
##########GET INNODB INFO
#INNODB variables
innodb_version:
innodb_buffer_pool_instances:将innodb缓冲池分为指定的多个(默认为1)
innodb_buffer_pool_size:innodb缓冲池大小、5.7.5引入了innodb_buffer_pool_chunk_size,
innodb_doublewrite:是否开启doublewrite(默认开启)
innodb_read_io_threads:IO读线程的数量
innodb_write_io_threads:IO写线程的数量
########innodb status
innodb_buffer_pool_pages_total:innodb缓冲池页的数量、大小等于innodb_buffer_pool_size/(16*1024)
innodb_buffer_pool_pages_data:innodb缓冲池中包含数据的页的数量
########## GET MYSQL HITRATE
1、查询缓存命中率
如果Qcache_hits+Com_select<>0则为 Qcache_hits/(Qcache_hits+Com_select),否则为0
2、线程缓存命中率
如果Connections<>0,则为1-Threads_created/Connections,否则为0
3、myisam键缓存命中率
如果Key_read_requests<>0,则为1-Key_reads/Key_read_requests,否则为0
4、myisam键缓存写命中率
如果Key_write_requests<>0,则为1-Key_writes/Key_write_requests,否则为0
5、键块使用率
如果Key_blocks_used+Key_blocks_unused<>0,则Key_blocks_used/(Key_blocks_used+Key_blocks_unused),否则为0
6、创建磁盘存储的临时表比率
如果Created_tmp_disk_tables+Created_tmp_tables<>0,则Created_tmp_disk_tables/(Created_tmp_disk_tables+Created_tmp_tables),否则为0
7、连接使用率
如果max_connections<>0,则threads_connected/max_connections,否则为0
8、打开文件比率
如果open_files_limit<>0,则open_files/open_files_limit,否则为0
9、表缓存使用率
如果table_open_cache<>0,则open_tables/table_open_cache,否则为0
2、redis
vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/redis.conf
UserParameter=Redis.Status,/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 ping |grep -c PONG
UserParameter=Redis_conn[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”connected_clients\” | awk -F\’:\’ \'{print $2}\’
UserParameter=Redis_rss_mem[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”used_memory_rss\” | awk -F\’:\’ \'{print $2}\’
UserParameter=Redis_lua_mem[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”used_memory_lua\” | awk -F\’:\’ \'{print $2}\’
UserParameter=Redis_cpu_sys[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”used_cpu_sys\” | awk -F\’:\’ \'{print $2}\’
UserParameter=Redis_cpu_user[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”used_cpu_user\” | awk -F\’:\’ \'{print $2}\’
UserParameter=Redis_cpu_sys_cline[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”used_cpu_sys_children\” | awk -F\’:\’ \'{print $2}\’
UserParameter=Redis_cpu_user_cline[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”used_cpu_user_children\” | awk -F\’:\’ \'{print $2}\’
UserParameter=Redis_keys_num[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w \”$$1\” | grep -w \”keys\” | grep db$3 | awk -F\’=\’ \'{print $2}\’ | awk -F\’,\’ \'{print $1}\’
UserParameter=Redis_loading[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep loading | awk -F\’:\’ \'{print $$2}\’
Redis.Status –检测Redis运行状态, 返回整数
Redis_conn –检测Redis成功连接数,返回整数
Redis_rss_mem –检测Redis系统分配内存,返回整数
Redis_lua_mem –检测Redis引擎消耗内存,返回整数
Redis_cpu_sys –检测Redis主程序核心CPU消耗率,返回整数
Redis_cpu_user –检测Redis主程序用户CPU消耗率,返回整数
Redis_cpu_sys_cline –检测Redis后台核心CPU消耗率,返回整数
Redis_cpu_user_cline –检测Redis后台用户CPU消耗率,返回整数
Redis_keys_num –检测库键值数,返回整数
Redis_loding –检测Redis持久化文件状态,返回整数
3、nginx
vim /etc/nginx/conf.d/default.conf
location /nginx-status
{
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/nginx.conf
UserParameter=Nginx.active,/usr/bin/curl -s \”http://127.0.0.1:80/nginx-status\” | awk \’/Active/ {print $NF}\’
UserParameter=Nginx.read,/usr/bin/curl -s \”http://127.0.0.1:80/nginx-status\” | grep \’Reading\’ | cut -d\” \” -f2
UserParameter=Nginx.wrie,/usr/bin/curl -s \”http://127.0.0.1:80/nginx-status\” | grep \’Writing\’ | cut -d\” \” -f4
UserParameter=Nginx.wait,/usr/bin/curl -s \”http://127.0.0.1:80/nginx-status\” | grep \’Waiting\’ | cut -d\” \” -f6
UserParameter=Nginx.accepted,/usr/bin/curl -s \”http://127.0.0.1:80/nginx-status\” | awk \’/^[ \\t]+[0-9]+[ \\t]+[0-9]+[ \\t]+[0-9]+/ {print $1}\’
UserParameter=Nginx.handled,/usr/bin/curl -s \”http://127.0.0.1:80/nginx-status\” | awk \’/^[ \\t]+[0-9]+[ \\t]+[0-9]+[ \\t]+[0-9]+/ {print $2}\’
UserParameter=Nginx.requests,/usr/bin/curl -s \”http://127.0.0.1:80/nginx-status\” | awk \’/^[ \\t]+[0-9]+[ \\t]+[0-9]+[ \\t]+[0-9]+/ {print $3}\’
4、TCP相关
vim /usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh
#!/bin/bash
function ESTAB {
/usr/sbin/ss -ant |awk \'{++s[$1]} END {for(k in s) print k,s[k]}\’ | grep \’ESTAB\’ | awk \'{print $2}\’
}
function TIMEWAIT {
/usr/sbin/ss -ant | awk \'{++s[$1]} END {for(k in s) print k,s[k]}\’ | grep \’TIME-WAIT\’ | awk \'{print $2}\’
}
function LISTEN {
/usr/sbin/ss -ant | awk \'{++s[$1]} END {for(k in s) print k,s[k]}\’ | grep \’LISTEN\’ | awk \'{print $2}\’
}
$1
vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/cattcp.conf
UserParameter=tcp[*],/usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh $1
tcp[TIMEWAIT] –检测TCP的驻留数,返回整数
tcp[ESTAB] –检测tcp的连接数、返回整数
tcp[LISTEN] –检测TCP的监听数,返回整数
5、系统常用自带监控项
agent.ping 检测客户端可达性、返回nothing表示不可达。1表示可达
system.cpu.load –检测cpu负载。返回浮点数
system.cpu.util — 检测cpu使用率。返回浮点数
vfs.dev.read — 检测硬盘读取数据,返回是sps.ops.bps浮点类型,需要定义1024倍
vfs.dev.write — 检测硬盘写入数据。返回是sps.ops.bps浮点类型,需要定义1024倍
net.if.out[br0] –检测网卡流速、流出方向,时间间隔为60S
net-if-in[br0] –检测网卡流速,流入方向(单位:字节) 时间间隔60S
proc.num[] 目前系统中的进程总数,时间间隔60s
proc.num[,,run] 目前正在运行的进程总数,时间间隔60S
###处理器信息
通过zabbix_get 获取负载值
合理的控制用户态、系统态、IO等待时间剋保证进程高效率的运行
系统态运行时间较高说明进程进行系统调用的次数比较多,一般的程序如果系统态运行时间占用过高就需要优化程序,减少系统调用
io等待时间过高则表明硬盘的io性能差,如果是读写文件比较频繁、读写效率要求比较高,可以考虑更换硬盘,或者使用多磁盘做raid的方案
system.cpu.swtiches –cpu的进程上下文切换,单位sps,表示每秒采样次数,api中参数history需指定为3
system.cpu.intr –cpu中断数量、api中参数history需指定为3
system.cpu.load[percpu,avg1] –cpu每分钟的负载值,按照核数做平均值(Processor load (1 min average per core)),api中参数history需指定为0
system.cpu.load[percpu,avg5] –cpu每5分钟的负载值,按照核数做平均值(Processor load (5 min average per core)),api中参数history需指定为0
system.cpu.load[percpu,avg15] –cpu每5分钟的负载值,按照核数做平均值(Processor load (15 min average per core)),api中参数history需指定为0
6、系统常用自定义监控项
####内存相关
vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/catcarm.conf
UserParameter=ram.info[*],/bin/cat /proc/meminfo |awk \’/^$1:{print $2}\’
ram.info[Cached] –检测内存的缓存使用量、返回整数,需要定义1024倍
ram.info[MemFree] –检测内存的空余量,返回整数,需要定义1024倍
ram.info[Buffers] –检测内存的使用量,返回整数,需要定义1024倍
####TCP相关的自定义项
vim /usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh
#!/bin/bash
function ESTAB {
/usr/sbin/ss -ant |awk \'{++s[$1]} END {for(k in s) print k,s[k]}\’ | grep \’ESTAB\’ | awk \'{print $2}\’
}
function TIMEWAIT {
/usr/sbin/ss -ant | awk \'{++s[$1]} END {for(k in s) print k,s[k]}\’ | grep \’TIME-WAIT\’ | awk \'{print $2}\’
}
function LISTEN {
/usr/sbin/ss -ant | awk \'{++s[$1]} END {for(k in s) print k,s[k]}\’ | grep \’LISTEN\’ | awk \'{print $2}\’
}
$1
vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/cattcp.conf
UserParameter=tcp[*],/usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh $1
tcp[TIMEWAIT] –检测TCP的驻留数,返回整数
tcp[ESTAB] –检测tcp的连接数、返回整数
tcp[LISTEN] –检测TCP的监听数,返回整数
九、zabbix优化
1、数据库
引擎
对于数据库而言,Zabbix 属于写多读少的操作,应该使用 Innodb 数据库引擎或者性能更好的 Tokudb,不应该使用 MyISAM
MyISAM 是不支持外键的,而 Zabbix创表的时候是有外键的。
MyISAM 只支持表级锁,就是说没插入/更新一条数据,整个表都要锁住,而 Zabbix 是写数据库比较多的,这样的话就会导致写如的速度很慢。
TokuDB一直被传说有着较高压缩比、较高insert性能、以及在线添加索引和字段速度较快等等优点,
关于 Tokudb 和 InnoDB 的性能对比参考如下博客
国外 国内
官方网站手册
数据库
历史数据不要保存太长时长;
尽量让数据缓存在数据库服务器的内存中;
2、优化监控项
触发器的表达式
减少使用聚合函数min(), max(), avg();尽量使用last(),nodata(),因为聚合函数,要运算
数据收集:polling较慢(减少使用SNMP/agentless/agent);尽量使用trapping(agent(active)主动监控);
数据类型:文本型数据处理速度较慢;尽量少收集类型为文本 text或string类型的数据;多使用类型为numeric 数值型数据 的;
删除无用的监控项
增加数据收集间隔时间
减少历史数据的保留时长
3、Agent 工作模式改为主动或者使用分布式:Proxy
4、优化相关进程数
设置自动发现
制造让其快速繁忙的最有效的办法就是设置一个网段进行自动发现的扫描
保证自动发现规则是 已启用 状态
查看图,尝试在 名称 搜索框中搜索 Utilization of discoverer data collector processes
现在,调整 /etc/zabbix/zabbix_server.conf 文件中的自动发现进程数量
# 默认值为1
# StartDiscoverers=1
# 修改为
StartDiscoverers=10
# 重启服务后查看进程数
ps -ef |grep discovere[r]
缓存设置
对应的配置文件中的选项
十、使用时遇到的问题
1、监控的服务器太多,把根占满了
因为创建数据库时没有特指数据存储的目录,导致数据存在了根下,而根的容量又不大,很快就满了
# 第一步,停服务,先将 zabbix-server 和 mysqld 停掉
[root@song-zabbix-server lib]# systemctl stop mysqld
[root@song-zabbix-server lib]# systemctl stop zabbix-server
# 第二步,迁移数据,将 mysql 的数据文件目录迁移到一个大空间的盘下
[root@song-zabbix-server lib]# mv /var/lib/mysql /data/mysql-data
# 第三步,做链接,将迁移后的目录链接到原地方,这样就不用更改配置文件了
[root@song-zabbix-server lib]# ln -s /data/mysql-data/ /var/lib/mysql
# 第四步,启动服务,然后就ok了
[root@song-zabbix-server lib]# systemctl start mysqld
[root@song-zabbix-server lib]# systemctl start zabbix-server
迁移zabbix使用的mysql
因华为虚拟机性能较低下,导致MySQL读写到瓶颈(表现:iowait 极高),故迁移MySQL至华为发放的MySQL中去
过程:大约80G的数据,dump时间大约1H,sql 文件 20G,导入耗时4小时
有丢失几个G 的数据,不清楚是重新启动mysql后又写入的,还是就是给丢了的,不过都是历史记录,所以问题不太大
# 1.停服务
# 2.dunp mysql
# 3.导入 新库
# 4.修改zabbix配置文件
# 5.重启验证
十一、报警处理
Zabbix server: More than 75% used in the history cache
在 zabbix-server 端,修改 server 的配置文件,将 HistoryCacheSize 值调大
#以上关于zabbix介绍及部署(超级详细讲解)的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92027.html