外观
PostgreSQL Nagios监控
Nagios监控架构
Nagios核心组件
Nagios Core
- 监控系统的核心引擎
- 负责调度监控检查
- 处理告警逻辑
- 生成监控报告
Nagios Plugins
- 用于执行具体监控检查的脚本
- 支持多种监控协议和服务
- 可以自定义开发
NRPE (Nagios Remote Plugin Executor)
- 用于在远程主机上执行监控插件
- 减少Nagios服务器的负载
- 提高监控安全性
NSCA (Nagios Service Check Acceptor)
- 用于接收远程主机主动发送的监控结果
- 适合监控防火墙后的主机
- 支持加密传输
Nagios Web界面
- 提供图形化监控视图
- 支持告警确认和注释
- 生成历史报告和趋势图
PostgreSQL监控架构
监控数据流
- Nagios服务器定期执行监控检查
- 通过NRPE或直接连接到PostgreSQL服务器
- 执行监控插件收集PostgreSQL状态信息
- 将结果返回给Nagios服务器
- 根据预定义规则触发告警
监控层次
- 系统级监控:CPU、内存、磁盘、网络
- PostgreSQL服务监控:服务状态、连接数
- 数据库级监控:数据库大小、事务数
- 表级监控:表大小、索引使用情况
- 查询级监控:慢查询、锁等待
Nagios插件安装与配置
安装Nagios插件
安装Nagios核心
bash# CentOS/RHEL系统 yum install -y nagios nagios-plugins-all # Ubuntu/Debian系统 apt update apt install -y nagios3 nagios-plugins安装PostgreSQL监控插件
bash# 安装check_postgres插件 wget https://github.com/bucardo/check_postgres/archive/refs/tags/v2.25.0.tar.gz tar -zxvf v2.25.0.tar.gz cd check_postgres-2.25.0 perl Makefile.PL make && make install # 验证安装 /usr/local/bin/check_postgres.pl --help安装NRPE (可选)
bash# CentOS/RHEL系统 yum install -y nrpe nagios-plugins-nrpe # Ubuntu/Debian系统 apt install -y nagios-nrpe-server
配置监控插件
创建监控用户
sql-- 在PostgreSQL中创建监控用户 CREATE USER nagios_monitor WITH PASSWORD 'nagios_password' NOSUPERUSER NOCREATEDB NOCREATEROLE; GRANT SELECT ON ALL TABLES IN SCHEMA pg_catalog TO nagios_monitor; GRANT SELECT ON ALL TABLES IN SCHEMA information_schema TO nagios_monitor;配置pg_hba.conf
txt# 允许Nagios服务器连接 host all nagios_monitor 192.168.1.100/32 md5配置check_postgres插件
bash# 创建插件配置文件 cat > /etc/nagios/check_postgres.conf << EOF [postgres] dbname=postgres port=5432 user=nagios_monitor password=nagios_password EOF # 设置权限 chmod 600 /etc/nagios/check_postgres.conf chown nagios:nagios /etc/nagios/check_postgres.conf测试插件运行
bash# 测试PostgreSQL连接 /usr/local/bin/check_postgres.pl --action=connection --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password # 测试数据库大小 /usr/local/bin/check_postgres.pl --action=database_size --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password
Nagios监控项配置
配置命令定义
在commands.cfg中添加命令
txt# /etc/nagios/objects/commands.cfg # check_postgres连接检查 define command { command_name check_postgres_connection command_line /usr/local/bin/check_postgres.pl --action=connection --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$' } # check_postgres数据库大小检查 define command { command_name check_postgres_db_size command_line /usr/local/bin/check_postgres.pl --action=database_size --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$' } # check_postgres连接数检查 define command { command_name check_postgres_connections command_line /usr/local/bin/check_postgres.pl --action=connection_count --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$' } # check_postgres慢查询检查 define command { command_name check_postgres_slow_queries command_line /usr/local/bin/check_postgres.pl --action=slow_queries --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$' } # check_postgres复制延迟检查 define command { command_name check_postgres_replication_delay command_line /usr/local/bin/check_postgres.pl --action=replication_delay --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$' }
配置主机和服务
定义PostgreSQL主机
txt# /etc/nagios/objects/postgresql.cfg define host { use linux-server host_name postgres-server-01 alias PostgreSQL主服务器 address 192.168.1.20 max_check_attempts 3 check_interval 5 retry_interval 1 check_command check-host-alive contact_groups admins }定义PostgreSQL服务
txt# PostgreSQL服务状态检查 define service { use generic-service host_name postgres-server-01 service_description PostgreSQL Service Status check_command check_tcp!5432 max_check_attempts 3 check_interval 5 retry_interval 1 contact_groups admins } # PostgreSQL连接检查 define service { use generic-service host_name postgres-server-01 service_description PostgreSQL Connections check_command check_postgres_connection!postgres!5432!nagios_monitor!nagios_password!50!100 max_check_attempts 3 check_interval 5 retry_interval 1 contact_groups admins } # PostgreSQL数据库大小检查 define service { use generic-service host_name postgres-server-01 service_description PostgreSQL Database Size check_command check_postgres_db_size!postgres!5432!nagios_monitor!nagios_password!5GB!10GB max_check_attempts 3 check_interval 30 retry_interval 5 contact_groups admins } # PostgreSQL慢查询检查 define service { use generic-service host_name postgres-server-01 service_description PostgreSQL Slow Queries check_command check_postgres_slow_queries!postgres!5432!nagios_monitor!nagios_password!10!20 max_check_attempts 3 check_interval 10 retry_interval 2 contact_groups admins } # PostgreSQL复制延迟检查 define service { use generic-service host_name postgres-server-01 service_description PostgreSQL Replication Delay check_command check_postgres_replication_delay!postgres!5432!nagios_monitor!nagios_password!30!60 max_check_attempts 3 check_interval 5 retry_interval 1 contact_groups admins }
配置NRPE (可选)
配置NRPE服务器
txt# /etc/nagios/nrpe.cfg # 允许Nagios服务器连接 allowed_hosts=127.0.0.1,192.168.1.100 # 定义NRPE命令 command[check_postgres_connections]=/usr/local/bin/check_postgres.pl --action=connection_count --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password -w 50 -c 100 command[check_postgres_db_size]=/usr/local/bin/check_postgres.pl --action=database_size --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password -w 5GB -c 10GB command[check_postgres_slow_queries]=/usr/local/bin/check_postgres.pl --action=slow_queries --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password -w 10 -c 20在Nagios中配置NRPE命令
txt# /etc/nagios/objects/commands.cfg define command { command_name check_nrpe command_line /usr/lib64/nagios/plugins/check_nrpe -H '$HOSTADDRESS$' -c '$ARG1$' } # 使用NRPE检查PostgreSQL连接 define service { use generic-service host_name postgres-server-01 service_description PostgreSQL Connections (NRPE) check_command check_nrpe!check_postgres_connections max_check_attempts 3 check_interval 5 retry_interval 1 contact_groups admins }
关键监控项与阈值设置
以下是 PostgreSQL Nagios 监控的关键监控项及其配置,使用 mermaid 流程图展示:
告警配置与通知
告警级别配置
配置告警联系人
txt# /etc/nagios/objects/contacts.cfg define contact { contact_name nagiosadmin use generic-contact alias Nagios Admin email nagiosadmin@example.com service_notification_period 24x7 host_notification_period 24x7 service_notification_options w,u,c,r,f,s host_notification_options d,u,r,f,s service_notification_commands notify-service-by-email host_notification_commands notify-host-by-email } define contactgroup { contactgroup_name admins alias Nagios Administrators members nagiosadmin }配置告警命令
txt# /etc/nagios/objects/commands.cfg define command { command_name notify-host-by-email command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **" $CONTACTEMAIL$ } define command { command_name notify-service-by-email command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$ }配置告警升级
txt# /etc/nagios/objects/timeperiods.cfg define timeperiod { timeperiod_name 24x7 alias 24 Hours A Day, 7 Days A Week sunday 00:00-24:00 monday 00:00-24:00 tuesday 00:00-24:00 wednesday 00:00-24:00 thursday 00:00-24:00 friday 00:00-24:00 saturday 00:00-24:00 } # 告警升级配置 define serviceescalation { host_name postgres-server-01 service_description PostgreSQL Replication Delay first_notification 1 last_notification 3 notification_interval 5 contact_groups admins escalation_period 24x7 }
告警通知方式
邮件通知
- 配置SMTP服务器
- 测试邮件发送
- 调整邮件模板
短信通知
- 安装短信网关
- 配置Nagios短信命令
- 测试短信发送
即时通讯工具
- Slack通知:使用slack_nagios.pl插件
- Telegram通知:使用telegram-nagios插件
- 微信通知:使用企业微信或第三方插件
自动语音呼叫
- 安装语音网关
- 配置Nagios语音命令
- 设置紧急告警语音通知
Nagios监控高级配置
自定义监控插件开发
Perl插件开发示例
perl#!/usr/bin/perl # 自定义PostgreSQL监控插件 use strict; use warnings; use DBI; # 插件参数 my $dbname = shift || 'postgres'; my $port = shift || 5432; my $username = shift || 'nagios_monitor'; my $password = shift || 'nagios_password'; my $warning = shift || 10; my $critical = shift || 20; # 连接到PostgreSQL my $dsn = "DBI:Pg:dbname=$dbname;host=localhost;port=$port"; my $dbh = DBI->connect($dsn, $username, $password) or die "Could not connect: " . DBI->errstr; # 执行查询 my $query = "SELECT count(*) FROM pg_stat_activity WHERE state = 'active'"; my $sth = $dbh->prepare($query); $sth->execute(); my ($active_connections) = $sth->fetchrow_array(); # 关闭连接 $sth->finish(); $dbh->disconnect(); # 检查结果 if ($active_connections >= $critical) { print "CRITICAL - Active connections: $active_connections | connections=$active_connections;$warning;$critical\n"; exit 2; } elsif ($active_connections >= $warning) { print "WARNING - Active connections: $active_connections | connections=$active_connections;$warning;$critical\n"; exit 1; } else { print "OK - Active connections: $active_connections | connections=$active_connections;$warning;$critical\n"; exit 0; }Python插件开发示例
python#!/usr/bin/env python3 # 自定义PostgreSQL监控插件 import sys import psycopg2 from psycopg2 import OperationalError def main(): # 插件参数 dbname = sys.argv[1] if len(sys.argv) > 1 else 'postgres' port = sys.argv[2] if len(sys.argv) > 2 else '5432' username = sys.argv[3] if len(sys.argv) > 3 else 'nagios_monitor' password = sys.argv[4] if len(sys.argv) > 4 else 'nagios_password' warning = int(sys.argv[5]) if len(sys.argv) > 5 else 10 critical = int(sys.argv[6]) if len(sys.argv) > 6 else 20 try: # 连接到PostgreSQL conn = psycopg2.connect( dbname=dbname, user=username, password=password, host='localhost', port=port ) cursor = conn.cursor() # 执行查询 cursor.execute("SELECT count(*) FROM pg_stat_activity WHERE state = 'active'") active_connections = cursor.fetchone()[0] # 关闭连接 cursor.close() conn.close() # 检查结果 if active_connections >= critical: print(f"CRITICAL - Active connections: {active_connections} | connections={active_connections};{warning};{critical}") sys.exit(2) elif active_connections >= warning: print(f"WARNING - Active connections: {active_connections} | connections={active_connections};{warning};{critical}") sys.exit(1) else: print(f"OK - Active connections: {active_connections} | connections={active_connections};{warning};{critical}") sys.exit(0) except OperationalError as e: print(f"CRITICAL - Could not connect to PostgreSQL: {e}") sys.exit(2) if __name__ == "__main__": main()
监控数据可视化
Nagios Graph插件
- 安装pnp4nagios
- 配置Nagios使用pnp4nagios
- 生成性能趋势图
Grafana集成
- 安装Grafana
- 配置PostgreSQL数据源
- 导入PostgreSQL监控仪表盘
- 设置告警规则
InfluxDB集成
- 安装InfluxDB
- 配置Nagios将数据发送到InfluxDB
- 使用Grafana可视化数据
高可用性配置
Nagios服务器高可用
- 配置Nagios主备服务器
- 使用DRBD同步数据
- 配置Pacemaker实现自动故障转移
监控代理高可用
- 部署多个NRPE服务器
- 配置负载均衡
- 实现故障自动切换
常见问题与故障处理
监控插件执行失败
问题现象
- Nagios显示"Plugin timed out"
- 插件返回"CRITICAL - Could not connect to PostgreSQL"
- 插件权限错误
排查步骤
- 检查PostgreSQL服务是否运行
- 验证监控用户权限
- 测试插件命令直接执行
- 检查防火墙设置
解决方案
- 重启PostgreSQL服务
- 重新配置监控用户权限
- 修复插件权限问题
- 调整防火墙规则
告警风暴
问题现象
- 短时间内收到大量告警
- 重复告警频繁出现
- 告警通知渠道过载
排查步骤
- 检查PostgreSQL服务器状态
- 分析告警类型和触发原因
- 检查监控阈值设置
解决方案
- 调整告警阈值
- 配置告警抑制规则
- 设置告警升级间隔
- 优化监控检查间隔
监控数据不准确
问题现象
- 监控数据与实际情况不符
- 数据波动过大
- 数据缺失
排查步骤
- 验证监控插件逻辑
- 检查PostgreSQL统计信息
- 分析监控数据采集频率
解决方案
- 修复监控插件bug
- 手动刷新PostgreSQL统计信息
- 调整监控检查间隔
- 优化数据存储和处理
NRPE连接失败
问题现象
- Nagios显示"CHECK_NRPE: Error - Could not complete SSL handshake"
- NRPE服务无法启动
- 权限错误
排查步骤
- 检查NRPE服务状态
- 验证NRPE配置文件
- 测试NRPE连接
- 检查SSL配置
解决方案
- 重启NRPE服务
- 修复NRPE配置错误
- 调整SSL设置
- 检查防火墙规则
Nagios监控最佳实践
监控策略设计
分层监控
- 系统层监控:CPU、内存、磁盘
- 服务层监控:PostgreSQL服务状态
- 应用层监控:数据库性能指标
- 业务层监控:关键业务指标
监控项优先级
- 核心服务监控:高优先级,短检查间隔
- 性能监控:中优先级,中等检查间隔
- 资源监控:低优先级,长检查间隔
告警策略
- 明确告警责任人
- 分级告警:警告、严重、紧急
- 告警升级机制
- 告警确认流程
监控维护
定期检查
- 每周检查监控插件状态
- 每月调整监控阈值
- 每季度更新监控插件
- 每年进行监控系统演练
文档管理
- 维护监控项文档
- 更新告警规则文档
- 记录故障处理过程
- 编写监控系统手册
性能优化
- 优化监控检查间隔
- 减少不必要的监控项
- 优化监控插件性能
- 调整Nagios配置参数
故障响应流程
告警确认
- 收到告警后立即确认
- 初步判断告警级别
- 通知相关责任人
故障排查
- 检查PostgreSQL服务状态
- 分析监控数据和日志
- 定位故障原因
- 制定修复方案
故障修复
- 执行修复操作
- 验证修复效果
- 更新监控状态
- 记录修复过程
事后分析
- 分析故障原因
- 评估监控系统表现
- 提出改进措施
- 更新监控策略
不同版本PostgreSQL的监控差异
PostgreSQL 9.x
监控项限制
- 部分性能指标不可用
- 复制监控功能有限
- 慢查询日志格式不同
插件兼容性
- 需要使用旧版本的check_postgres插件
- 某些高级监控项不支持
- 需要调整监控脚本
PostgreSQL 10.x及以上
新监控功能
- 增强的复制监控
- 更详细的性能统计
- 逻辑复制监控
- 分区表监控
插件优化
- 使用最新版本的check_postgres插件
- 支持更多监控项
- 性能更优
监控配置调整
根据版本调整监控项
- 针对不同版本启用或禁用监控项
- 调整监控阈值
- 更新监控插件版本
兼容性处理
- 编写兼容多版本的监控脚本
- 使用条件判断处理版本差异
- 测试不同版本的监控效果
Nagios监控案例分析
案例1:PostgreSQL连接数过高告警
问题描述
- Nagios发送"PostgreSQL Connections CRITICAL"告警
- 应用程序无法连接到PostgreSQL
- 服务器CPU使用率过高
处理过程
- 登录PostgreSQL服务器
- 执行
pg_stat_activity查看连接状态 - 发现大量空闲连接
- 调整
max_connections参数 - 配置连接超时
解决方案
- 增加
max_connections到200 - 设置
idle_in_transaction_session_timeout = 300000 - 配置连接池
- 优化应用程序连接管理
- 增加
案例2:复制延迟告警
问题描述
- Nagios发送"PostgreSQL Replication Delay CRITICAL"告警
- 从库复制延迟超过60秒
- 主库WAL日志堆积
处理过程
- 检查主从库网络连接
- 查看主库WAL生成速率
- 检查从库WAL应用速率
- 发现从库I/O瓶颈
解决方案
- 优化从库存储性能
- 调整主库WAL参数
- 启用并行复制
- 增加从库资源
案例3:慢查询告警
问题描述
- Nagios发送"PostgreSQL Slow Queries CRITICAL"告警
- 慢查询数超过20个
- 数据库响应变慢
处理过程
- 分析慢查询日志
- 使用
EXPLAIN ANALYZE分析查询计划 - 发现缺少索引
- 优化查询语句
解决方案
- 为频繁查询的列添加索引
- 重写复杂查询
- 调整
work_mem参数 - 优化数据库统计信息
常见问题(FAQ)
Q1: 如何选择合适的监控插件?
A1: 选择监控插件时需要考虑:
- 插件的功能完整性
- 与PostgreSQL版本的兼容性
- 插件的性能开销
- 社区支持和更新频率
- 自定义扩展能力
Q2: 如何设置合理的监控阈值?
A2: 设置监控阈值时需要考虑:
- 系统的正常运行范围
- 业务需求和SLA要求
- 历史数据趋势
- 资源容量限制
- 告警频率和处理能力
Q3: 如何减少监控对PostgreSQL性能的影响?
A3: 可以通过以下方法减少监控影响:
- 调整监控检查间隔
- 减少不必要的监控项
- 使用只读监控用户
- 优化监控插件性能
- 部署专用监控服务器
Q4: 如何实现PostgreSQL的自动故障恢复?
A4: 实现自动故障恢复可以考虑:
- 使用Patroni或repmgr实现PostgreSQL自动故障转移
- 配置Nagios与自动化工具集成
- 编写自定义恢复脚本
- 建立故障恢复流程和文档
Q5: 如何监控PostgreSQL集群?
A5: 监控PostgreSQL集群需要:
- 监控每个节点的状态
- 监控集群复制状态
- 监控集群性能指标
- 监控集群一致性
- 配置集群级告警规则
Q6: 如何集成Nagios与其他监控系统?
A6: 集成Nagios与其他监控系统可以:
- 使用Nagios的API导出数据
- 配置Nagios将数据发送到中央监控系统
- 使用第三方集成工具
- 开发自定义集成插件
Q7: 如何优化Nagios监控性能?
A7: 优化Nagios监控性能可以:
- 调整Nagios配置参数
- 优化监控检查间隔
- 使用NRPE减少网络开销
- 优化监控插件
- 升级Nagios服务器硬件
Q8: 如何实现PostgreSQL的预测性监控?
A8: 实现预测性监控可以:
- 收集长期监控数据
- 使用机器学习算法分析趋势
- 建立预测模型
- 设置预测性告警阈值
- 集成预测分析工具
