天天看点

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 zabbix使用一段时间后总是报zabbix agent不可到达,报错文字如下:

 zabbix server messages: problem: zabbix agent on zabbix server is unreachable for 5 minutes

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题
解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 首先查看zabbix agent的日志,找到关键出错信息,日志如下:

 来自:/tmp/zabbix_agentd.log

 mysqladmin: connect to server at 'localhost' failed    

error: 'can't connect to local mysql server through socket '/tmp/mysql.sock' (2)'     

check that mysqld is running and that the socket: '/tmp/mysql.sock' exists!

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 由此可见,zabbix agent无法连接数据库(作为管理员应该清楚zabbix agent是不会连接数据库的),具体的是无法通过/tmp/mysql.sock连接到本地数据库服务器,由于这是一个socket文件,它的默认权限对其他用户或用户组是开发读写权限的。例如查看当前的配置:

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 而且数据库服务是正在运行的,而且socket文件的确存在,权限也是正常的。而且通过命令行可以验证通过socket文件确实可以连接。

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题
解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 问题分析与解决思路:

 数据库服务器是一直正常的,这个作为管理员即使不运行任何命令也能做到心中有数,应该不是数据库服务器自身的问题,但不能排除跟客户端的连接方式有关。

查看mysql数据库的配置文件

[root@chris ~]# delsc /etc/my.cnf    

[client]     

port = 3306     

socket = /tmp/mysql.sock     

[mysqld]     

datadir = /usr/local/mysql/var     

skip-external-locking     

skip-name-resolve     

key_buffer_size = 384m     

max_connections = 5000     

max_allowed_packet = 1m     

table_open_cache = 64k     

sort_buffer_size = 128m     

net_buffer_length = 8k     

read_buffer_size = 256k     

read_rnd_buffer_size = 512k     

myisam_sort_buffer_size = 128m     

slow-query-log = 0     

tmp_table_size = 8g     

max_heap_table_size = 8g     

table_cache = 512     

binlog_cache_size = 6144m     

query_cache_type = 1     

query_cache_size = 128m     

query_cache_limit = 128m     

query_cache_min_res_unit = 1024     

myisam-recover-options = backup     

innodb_data_home_dir = /usr/local/mysql/var     

innodb_data_file_path = ibdata1:10m:autoextend     

innodb_log_group_home_dir = /usr/local/mysql/var     

innodb_buffer_pool_size = 8g     

innodb_write_io_threads = 8     

innodb_read_io_threads = 8     

innodb_thread_concurrency = 16     

innodb_file_format = barracuda     

innodb_log_file_size = 512m     

innodb_log_buffer_size = 64m     

innodb_flush_log_at_trx_commit = 1     

innodb_flush_method = o_direct     

innodb_lock_wait_timeout = 50     

innodb_log_files_in_group = 3     

innodb_max_dirty_pages_pct = 90     

innodb_lock_wait_timeout = 120     

innodb_use_sys_malloc = 0     

innodb_additional_mem_pool_size = 2g     

innodb_file_per_table = 1     

[mysqld_safe]     

log-error = /usr/local/mysql/var/mysql-error.log     

pid-file = /usr/local/mysql/var/mysql.pid     

[mysqldump]     

quick     

max_allowed_packet = 16m     

[mysql]     

no-auto-rehash     

[myisamchk]     

key_buffer_size = 512m     

sort_buffer_size = 512m     

read_buffer = 8m     

write_buffer = 8m     

[mysqlhotcopy]     

interactive-timeout     

[root@chris ~]#

 发现在[client]中存在socket = /tmp/mysql.sock一行,可能(可能性的情况参照下文)会默认导致mysql客户端连接时会自动使用socket进行连接。

 查看zabbix agent的配置文件,观察是否有通过socket连接mysql的配置信息(前面提到,作为管理员应该清楚zabbix agent是不会连接数据库的,此时应该准确的说默认是不会连接数据库,如下图所示zabbix agent添加了一个与mysql有关的监控项,里面用到了mysql程序,但没写socket选项(事实上使用localhost作为连接主机名将会使用socket))。

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 为了缩小问题范围,先将/etc/my.cnf文件中关于[client]中的socket那段先注释掉(事先应该知道没有其他客户端连接)。注意:如果把[client]中的socket注释掉,则在本机mysql客户端程序(包括mysqladmin,mysqldump等)时都需要指定主机名、端口和密码,否则客户端程序会查找socket的默认位置“/var/lib/mysql/mysql.sock”,而这个socket文件的位置并不一定是这个。

 mysql连接通过套接字连接和通过端口号连接有什么不同?unix平台上的mysql客户端能够以两种不同的方式连接到mysql服务器:通过文件系统中的文件(默认为/tmp/mysql.sock)使用unix套接字进行连接,或通过端口号使用tcp/ip进行连接。unix套接字文件的连接速度比tcp/ip快,但仅能在与相同计算机上的服务器相连时使用。如果未指定指定主机名或指定了特殊的主机名localhost(注意此处,如果指定了连接的主机名为localhost将使用socket连接),将使用unix套接字。套接字连接可以理解为指定了ip+端口。

 因此按照上述理论将localhost换成127.0.0.1,取消socket连接方式,改用tcp/ip连接。其实反过来回想,假如指定了连接的主机名(除了localhost)或ip地址、端口号,就不用再使用socket,因此可以将socket那个注释给去掉,这样方便管理员平时连接调试。

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 因为zabbix server是要连接数据库的,因此也顺便检查一下。果然有收获:关于dbport有一个有用的注释“database port when not using local socket. ignored for sqlite.”意思是说如果socket不使用则使用dbport,而默认dbport是不使用而优先使用socket的。

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 因此也将这个dbport设置成启用状态。

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 其他可能影响因素:

 iptables的规则-a input -p tcp -m state --state new -m tcp --dport 3306 -j accept也是正常的,15   accept     tcp  --  0.0.0.0/0            0.0.0.0/0           state new tcp dpt:3306 。

 selinux是事先关闭好了的。

 但修改完上述所提到的后发现问题依然,zabbix依然报错(zabbix server messages: problem: zabbix agent on zabbix server is unreachable for 5 minutes),查看zabbix server的日志后发现有这么一条信息(后来发现还有报数据库跑飞的信息):

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题
解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题
解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 由上图可知,尽管能获取到ntp[pool.ntp.org]数据,但花费的时间比较长,但是没有在zabbix web管理界面中找到跟超时相关的设置,因此可以考虑换一个ntp服务器或者干脆禁用掉。后来也发现这个key获取不到数据时就会导致触发zabbix agent不可到达的报警。

对于第二个报错:问题可能比较复杂,例如数据库所允许传递的包的大小(max_allowed_packet),数据库查询超时时间,(connect_timeout、wait_timeout)等。原始配置数据:

解决Zabbix使用一段时间后总报Zabbix Agent不可到达的问题

 因此将max_allowed_packet = 1m改的大一些,例如改成max_allowed_packet = 2m。

经历了以上几个个操作后,发现zabbix server 不再产生zabbix agent不可到达的报警。

 小总结:

 (1)尽可能快速和有效地缩小问题范围,利用敏捷方法减少故障时间。

 (2)能先解决问题,就不要慢慢去研究;但能慢慢解决问题,就要仔仔细细去研究。

 (3)遇到小问题一定要像面对大问题一样对待,免得小问题发展成大问题。

 (4)要想快速定位问题,需要对自己的服务器环境、整个工作环境中的每一个组件、组件与组件之间的关系都需要了如指掌。

 (5)如果不是自己在维护这些服务,一定要及时与同事做好沟通。

 (6)做好问题记录,温故而知新,哪怕花时间写成一篇博文也是值得的。

--end--