Zabbix使用指北
source link: https://wsgzao.github.io/post/zabbix/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Zabbix是目前最为主流的开源监控方案之一,部署本身并不困难,难的是深入理解
学习使用Zabbix
更新历史
2018年08月06日 - 初稿
阅读原文 - https://wsgzao.github.io/post/zabbix/
扩展阅读
Zabbix - https://www.zabbix.com/
官方文档
zabbix-server
以下是基于LNMP手动编译安装Zabbix的过程,仅供参考
# hostname hostnamectl set-hostname <host-name> # firewall systemctl stop firewalld systemctl disable firewalld # selinux getenforce setenforce 0 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config # epel yum install epel-release # nginx yum install nginx systemctl enable nginx systemctl start nginx systemctl status nginx nginx -s reload # mysql | mariadb yum -y install mariadb mariadb-server systemctl enable mariadb.service systemctl start mariadb.service mysql_secure_installation # php wget http://cn2.php.net/distributions/php-7.2.8.tar.gz tar xf php-7.2.8.tar.gz cd ./php-7.2.8/ yum install -y libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libcurl libcurl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel gmp gmp-devel libmcrypt libmcrypt-devel readline readline-devel libxslt libxslt-devel yum install -y libmcrypt libmcrypt-devel gcc ./configure --prefix=/usr/local/php --with-config-file-path=/etc --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx --enable-inline-optimization --disable-debug --disable-rpath --enable-shared --enable-soap --with-libxml-dir --with-xmlrpc --with-openssl --with-mcrypt --with-mhash --with-pcre-regex --with-sqlite3 --with-zlib --enable-bcmath --with-iconv --with-bz2 --enable-calendar --with-curl --with-cdb --enable-dom --enable-exif --enable-fileinfo --enable-filter --with-pcre-dir --enable-ftp --with-gd --with-openssl-dir --with-jpeg-dir --with-png-dir --with-zlib-dir --with-freetype-dir --enable-gd-native-ttf --enable-gd-jis-conv --with-gettext --with-gmp --with-mhash --enable-json --enable-mbstring --enable-mbregex --enable-mbregex-backtrack --with-libmbfl --with-onig --enable-pdo --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-zlib-dir --with-pdo-sqlite --with-readline --enable-session --enable-shmop --enable-simplexml --enable-sockets --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-wddx --with-libxml-dir --with-xsl --enable-zip --enable-mysqlnd-compression-support --with-pear --enable-opcache make && make install vi /etc/profile PATH=$PATH:/usr/local/php/bin export PATH source /etc/profile echo $PATH php -v # php-fpm cp ./php.ini-production /etc/php.ini cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm chmod +x /etc/init.d/php-fpm vi /etc/php.ini max_execution_time = 300 max_input_time = 300 memory_limit = 128M post_max_size = 16M date.timezone = Asia/Singapore /etc/init.d/php-fpm start # nginx vi /etc/nginx/conf.d/default.conf server{ listen 80; server_name localhost; root /data/www; location / { index index.php index.html index.htm; if (!-e $request_filename) { rewrite ^/(.*)$ /index.php/$1; #rewrite ^/subdir/(.*)$ /subdir/index.php/$1; } } #proxy the php scripts to php-fpm location ~ \.php { include fastcgi_params; set $path_info ""; set $real_script_name $fastcgi_script_name; if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") { set $real_script_name $1; set $path_info $2; } fastcgi_param SCRIPT_FILENAME $document_root$real_script_name; fastcgi_param SCRIPT_NAME $real_script_name; fastcgi_param PATH_INFO $path_info; fastcgi_intercept_errors on; fastcgi_pass 127.0.0.1:9000; } } nginx -s reload vi /data/www/info.php <?php phpinfo(); ?> http://127.0.0.1/info.php # zabbix-server rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm yum -y install zabbix-server-mysql zabbix-agent # create zabbix in db mysql -u root -p create database zabbix character set utf8 collate utf8_bin; grant all privileges on zabbix.* to 'zabbix'@'%' identified by 'zabbix'; flush privileges; cd /usr/share/doc/zabbix-server-mysql-3.4.11/ zcat create.sql.gz | mysql -u root -p zabbix vi /etc/zabbix/zabbix_server.conf DBHost=localhost DBName=zabbix DBUser=zabbix DBPassword=zabbix chown -R zabbix:zabbix /etc/zabbix chown -R zabbix:zabbix /usr/lib/zabbix systemctl enable zabbix-server systemctl start zabbix-server # zabbix-web wget -O zabbix-3.4.11.tar.gz https://excellmedia.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/3.4.11/zabbix-3.4.11.tar.gz tar zxvf zabbix-3.4.11.tar.gz cp -rf ./zabbix-3.4.11/frontends/php/ /data/www/zabbix mv /data/www/zabbix/conf/zabbix.conf.php.example /data/www/zabbix/conf/zabbix.conf.php vi /data/www/zabbix/conf/zabbix.conf.php <?php // Zabbix GUI configuration file. global $DB, $HISTORY; $DB['TYPE'] = 'MYSQL'; $DB['SERVER'] = '127.0.0.1'; $DB['PORT'] = '0'; $DB['DATABASE'] = 'zabbix'; $DB['USER'] = 'zabbix'; $DB['PASSWORD'] = 'zabbix'; // Schema name. Used for IBM DB2 and PostgreSQL. $DB['SCHEMA'] = ''; $ZBX_SERVER = 'localhost'; $ZBX_SERVER_PORT = '10051'; $ZBX_SERVER_NAME = ''; $IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG; // Elasticsearch url (can be string if same url is used for all types). $HISTORY['url'] = [ 'uint' => 'http://127.0.0.1:9200', 'text' => 'http://127.0.0.1:9200' ]; // Value types stored in Elasticsearch. $HISTORY['types'] = ['uint', 'text']; http://127.0.0.1/zabbix ## zabbix-agent rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm yum -y install zabbix-agent vi /etc/zabbix/zabbix_agentd.conf Server=127.0.0.1 ServerActive=127.0.0.1 Hostname=Zabbix server systemctl enable zabbix-agent systemctl start zabbix-agent
docker
https://www.zabbix.com/documentation/3.4/zh/manual/installation/containers
# install docker-ce sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce sudo systemctl start docker # docker: Error response from daemon: Get https://registry-1.docker.io/v2/: x509: certificate has expired or is not yet valid. ntpdate 0.pool.ntp.org # run docker docker run --name mysql-server -t \ -e MYSQL_DATABASE="zabbix" \ -e MYSQL_USER="zabbix" \ -e MYSQL_PASSWORD="zabbix" \ -e MYSQL_ROOT_PASSWORD="zabbix" \ -d mysql:5.7 \ --character-set-server=utf8 --collation-server=utf8_bin docker run --name zabbix-server-mysql -t \ -e DB_SERVER_HOST="mysql-server" \ -e MYSQL_DATABASE="zabbix" \ -e MYSQL_USER="zabbix" \ -e MYSQL_PASSWORD="zabbix" \ -e MYSQL_ROOT_PASSWORD="zabbix" \ --link mysql-server:mysql \ -p 10051:10051 \ -d zabbix/zabbix-server-mysql:latest docker run --name zabbix-web-nginx-mysql -t \ -e DB_SERVER_HOST="mysql-server" \ -e MYSQL_DATABASE="zabbix" \ -e MYSQL_USER="zabbix" \ -e MYSQL_PASSWORD="zabbix" \ -e MYSQL_ROOT_PASSWORD="zabbix" \ --link mysql-server:mysql \ --link zabbix-server-mysql:zabbix-server \ -p 8080:80 \ -d zabbix/zabbix-web-nginx-mysql:latest [root@zabbix_server ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 98cbe8d8a6bd zabbix/zabbix-web-nginx-mysql:latest "docker-entrypoint.sh" 6 seconds ago Up 5 seconds 443/tcp, 0.0.0.0:8080->80/tcp zabbix-web-nginx-mysql de040d43d60f zabbix/zabbix-server-mysql:latest "docker-entrypoint.sh" 59 seconds ago Up 59 seconds 0.0.0.0:10051->10051/tcp zabbix-server-mysql 3276f18def8d mysql:5.7 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp mysql-server [root@zabbix_server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE zabbix/zabbix-web-nginx-mysql latest 4db891b4393a 10 hours ago 177MB zabbix/zabbix-server-mysql latest f5e58dafe9ac 10 hours ago 62.2MB mysql 5.7 f0f3956a9dd8 7 days ago 409MB http://127.0.0.1:8080 Admin/zabbix
Zabbix分区优化
https://www.zabbix.org/wiki/Docs/howto/mysql_partition
https://cloud.tencent.com/developer/article/1006301Zabbix数据库优化
目的: 快速清理历史数据,并减少数据存储容量
方法: 历史表使用分区表(删除分区表速度快),使用Tokudb引擎(适合大量insert少量update和select等日志表)
Zabbix版本: 3.4
涉及表项:
存储不同类型item的历史数据,最终1小时或者1天等段时间的绘图数据从其中获取
history、history_log、history_str、history_text、history_uint
存储不同类型item的历史趋势数据,每隔一小时从历史数据中统计一次,并计算统计区间的平均值,最大值,最小值trends、trends_uint
zabbix的db有做分表 根据这个来的
https://www.zabbix.org/wiki/Docs/howto/mysql_partition
cronjob里的脚本包括了建新表和删除旧表,用mysql的procedure控制,删除旧表可以释放空间
想要修改短一点,需要修改procedure partition_maintenance_all里规定的时间
我的做法是Drop旧procedure再创建新的
关闭zabbix的housekeeper功能
- login mysql zabbix
- DROP PROCEDURE IF EXISTS partition_maintenance_all
- 根据需要修改括号内第三列的时间,估计得改成45或者30了。每列的定义请参照最上面给的链接
- 再手动跑下cronjob内的那个指令就好
[root@sg-gop-10-65-200-90 mysql]# grep -Ev '^$|#' /etc/zabbix/zabbix_server.conf LogFile=/var/log/zabbix/zabbix_server.log LogFileSize=0 PidFile=/var/run/zabbix/zabbix_server.pid SocketDir=/var/run/zabbix DBName=zabbix DBUser=zabbix DBPassword=zabbix StartPollers=500 StartPingers=50 SNMPTrapperFile=/var/log/snmptrap/snmptrap.log CacheSize=8G TrendCacheSize=1G Timeout=15 AlertScriptsPath=/usr/lib/zabbix/alertscripts ExternalScripts=/usr/lib/zabbix/externalscripts LogSlowQueries=3000 [root@sg-gop-10-65-200-90 percona-server.conf.d]# grep -Ev '^$|#' /etc/percona-server.conf.d/mysqld.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid max_connections=1000
# login mysql mysql -uroot -p zabbix mysql> use zabbix; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show variables like '%dir%'; +-----------------------------------------+-------------------------------------+ | Variable_name | Value | +-----------------------------------------+-------------------------------------+ | basedir | /usr/ | | binlog_direct_non_transactional_updates | OFF | | character_sets_dir | /usr/share/percona-server/charsets/ | | datadir | /var/lib/mysql/ | | ignore_db_dirs | | | innodb_data_home_dir | | | innodb_log_group_home_dir | ./ | | innodb_max_dirty_pages_pct | 75.000000 | | innodb_max_dirty_pages_pct_lwm | 0.000000 | | innodb_tmpdir | | | innodb_undo_directory | ./ | | lc_messages_dir | /usr/share/percona-server/ | | plugin_dir | /usr/lib64/mysql/plugin/ | | slave_load_tmpdir | /tmp | | tmpdir | /tmp | +-----------------------------------------+-------------------------------------+ 15 rows in set (0.07 sec) mysql> SELECT table_name AS "Tables", round(((data_length + index_length) / 1024 / 1024), 2) "Size in MB" FROM information_schema.TABLES WHERE table_schema = 'zabbix' ORDER BY (data_length + index_length) DESC; +----------------------------+------------+ | Tables | Size in MB | +----------------------------+------------+ | history | 545043.75 | | history_uint | 44729.66 | | trends | 13500.41 | | trends_uint | 1666.66 | | history_text | 650.31 | # Zabbix > 3.2, history 30, Trends 300 #cat partition.sql DELIMITER $$ CREATE PROCEDURE `partition_create`(SCHEMANAMEvarchar(64), TABLENAME varchar(64), PARTITIONNAME varchar(64), CLOCK int) BEGIN /* SCHEMANAME = The DB schema in which to make changes TABLENAME = The table with partitions to potentially delete PARTITIONNAME = The name of the partition to create */ /* Verify that the partition does not already exist */ DECLARE RETROWS INT; SELECT COUNT(1) INTO RETROWS FROM information_schema.partitions WHERE table_schema = SCHEMANAME AND table_name = TABLENAME ANDpartition_description >= CLOCK; IF RETROWS = 0 THEN /* 1. Print a messageindicating that a partition was created. 2. Create the SQL to createthe partition. 3. Execute the SQL from #2. */ SELECT CONCAT( "partition_create(", SCHEMANAME, ",",TABLENAME, ",", PARTITIONNAME, ",", CLOCK, ")" )AS msg; SET @sql = CONCAT( 'ALTER TABLE ', SCHEMANAME, '.', TABLENAME, ' ADDPARTITION (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', CLOCK, '));' ); PREPARE STMT FROM @sql; EXECUTE STMT; DEALLOCATE PREPARE STMT; END IF; END$$ DELIMITER ; DELIMITER $$ CREATE PROCEDURE `partition_drop`(SCHEMANAMEVARCHAR(64), TABLENAME VARCHAR(64), DELETE_BELOW_PARTITION_DATE BIGINT) BEGIN /* SCHEMANAME = The DB schema in which tomake changes TABLENAME = The table with partitions to potentially delete DELETE_BELOW_PARTITION_DATE = Delete any partitions with names that aredates older than this one (yyyy-mm-dd) */ DECLARE done INT DEFAULT FALSE; DECLARE drop_part_name VARCHAR(16); /* Get a list of all the partitions that are older than the date in DELETE_BELOW_PARTITION_DATE. All partitions are prefixed with a "p", so use SUBSTRING TOget rid of that character. */ DECLARE myCursor CURSOR FOR SELECT partition_name FROM information_schema.partitions WHERE table_schema = SCHEMANAME AND table_name = TABLENAME ANDCAST(SUBSTRING(partition_name FROM 2) AS UNSIGNED) <DELETE_BELOW_PARTITION_DATE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; /* Create the basics for when we need to drop the partition. Also, create @drop_partitions to hold a comma-delimited list of all partitions that should be deleted. */ SET @alter_header = CONCAT("ALTER TABLE ", SCHEMANAME,".", TABLENAME, " DROP PARTITION "); SET @drop_partitions = ""; /* Start looping through all the partitions that are too old. */ OPEN myCursor; read_loop: LOOP FETCH myCursor INTO drop_part_name; IF done THEN LEAVE read_loop; END IF; SET @drop_partitions = IF(@drop_partitions = "",drop_part_name, CONCAT(@drop_partitions, ",", drop_part_name)); END LOOP; IF @drop_partitions != "" THEN /* 1. Build the SQL to drop allthe necessary partitions. 2. Run the SQL to drop thepartitions. 3. Print out the tablepartitions that were deleted. */ SET @full_sql = CONCAT(@alter_header, @drop_partitions, ";"); PREPARE STMT FROM @full_sql; EXECUTE STMT; DEALLOCATE PREPARE STMT; SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`,@drop_partitions AS `partitions_deleted`; ELSE /* No partitions are beingdeleted, so print out "N/A" (Not applicable) to indicate that no changes were made. */ SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`,"N/A" AS `partitions_deleted`; END IF; END$$ DELIMITER ; DELIMITER $$ CREATE PROCEDURE`partition_maintenance`(SCHEMA_NAME VARCHAR(32), TABLE_NAME VARCHAR(32),KEEP_DATA_DAYS INT, HOURLY_INTERVAL INT, CREATE_NEXT_INTERVALS INT) BEGIN DECLARE OLDER_THAN_PARTITION_DATE VARCHAR(16); DECLARE PARTITION_NAME VARCHAR(16); DECLARE OLD_PARTITION_NAME VARCHAR(16); DECLARE LESS_THAN_TIMESTAMP INT; DECLARE CUR_TIME INT; CALL partition_verify(SCHEMA_NAME,TABLE_NAME, HOURLY_INTERVAL); SET CUR_TIME = UNIX_TIMESTAMP(DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00')); SET @__interval = 1; create_loop: LOOP IF @__interval > CREATE_NEXT_INTERVALS THEN LEAVE create_loop; END IF; SET LESS_THAN_TIMESTAMP = CUR_TIME + (HOURLY_INTERVAL * @__interval *3600); SET PARTITION_NAME = FROM_UNIXTIME(CUR_TIME + HOURLY_INTERVAL *(@__interval - 1) * 3600, 'p%Y%m%d%H00'); IF(PARTITION_NAME != OLD_PARTITION_NAME) THEN CALLpartition_create(SCHEMA_NAME, TABLE_NAME, PARTITION_NAME, LESS_THAN_TIMESTAMP); END IF; SET @__interval=@__interval+1; SET OLD_PARTITION_NAME = PARTITION_NAME; END LOOP; SET OLDER_THAN_PARTITION_DATE=DATE_FORMAT(DATE_SUB(NOW(), INTERVALKEEP_DATA_DAYS DAY), '%Y%m%d0000'); CALL partition_drop(SCHEMA_NAME, TABLE_NAME, OLDER_THAN_PARTITION_DATE); END$$ DELIMITER ; DELIMITER $$ CREATE PROCEDURE `partition_verify`(SCHEMANAMEVARCHAR(64), TABLENAME VARCHAR(64), HOURLYINTERVAL INT(11)) BEGIN DECLARE PARTITION_NAME VARCHAR(16); DECLARE RETROWS INT(11); DECLARE FUTURE_TIMESTAMP TIMESTAMP; /* * Check if any partitions exist for the given SCHEMANAME.TABLENAME. */ SELECT COUNT(1) INTO RETROWS FROM information_schema.partitions WHERE table_schema = SCHEMANAME AND table_name = TABLENAME ANDpartition_name IS NULL; /* * If partitions do not exist, go ahead and partition the table */ IFRETROWS = 1 THEN /* * Take the current date at 00:00:00 and add HOURLYINTERVAL to it. This is the timestamp below which we willstore values. * We begin partitioning based on the beginning of a day. This is because we don't want to generate arandom partition * that won't necessarily fall in line with the desired partition naming(ie: if the hour interval is 24 hours, we could * end up creating a partition now named "p201403270600" whenall other partitions will be like "p201403280000"). */ SET FUTURE_TIMESTAMP = TIMESTAMPADD(HOUR, HOURLYINTERVAL,CONCAT(CURDATE(), " ", '00:00:00')); SET PARTITION_NAME = DATE_FORMAT(CURDATE(), 'p%Y%m%d%H00'); -- Create the partitioning query SET @__PARTITION_SQL = CONCAT("ALTER TABLE ", SCHEMANAME,".", TABLENAME, " PARTITION BY RANGE(`clock`)"); SET @__PARTITION_SQL = CONCAT(@__PARTITION_SQL, "(PARTITION ",PARTITION_NAME, " VALUES LESS THAN (",UNIX_TIMESTAMP(FUTURE_TIMESTAMP), "));"); -- Run the partitioning query PREPARE STMT FROM @__PARTITION_SQL; EXECUTE STMT; DEALLOCATE PREPARE STMT; END IF; END$$ DELIMITER ; DELIMITER $$ CREATE PROCEDURE`partition_maintenance_all`(SCHEMA_NAME VARCHAR(32)) BEGIN CALL partition_maintenance(SCHEMA_NAME, 'history', 30, 24, 14); CALL partition_maintenance(SCHEMA_NAME, 'history_log', 30, 24, 14); CALL partition_maintenance(SCHEMA_NAME, 'history_str', 30, 24, 14); CALL partition_maintenance(SCHEMA_NAME, 'history_text', 30, 24, 14); CALLpartition_maintenance(SCHEMA_NAME, 'history_uint', 30, 24, 14); CALL partition_maintenance(SCHEMA_NAME, 'trends', 120, 24, 14); CALL partition_maintenance(SCHEMA_NAME, 'trends_uint', 120, 24, 14); END$$ DELIMITER ;
# import partition.sql mysql -u'zabbix' -p'zabbix' zabbix < partition.sql # run nohup mysql -u'zabbix' -p'zabbix' 'zabbix' -e "CALL partition_maintenance_all('zabbix')" &> /root/partition.log& tail -f /root/partition.log # 查看过程逻辑 show create procedure partition_maintenance_all \G; # 删除存储过程 drop procedure if exists partition_maintenance_all; # 查看存储过程 show procedure status like 'partition_maintenance%' \G; # 查看 show create table history # crontab [root@sg-gop-10-65-200-90 wangao]# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed 15 3 * * * root bash /opt/sa_scripts/zabbix_partitioning.sh [root@sg-gop-10-65-200-90 wangao]# cat /opt/sa_scripts/zabbix_partitioning.sh #!/bin/bash user='zabbix' password='zabbix' database='zabbix' mysql -u${user} -p$password $database -e "CALL partition_maintenance_all('zabbix');"
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK