0x01 前言
最近通过zabbix发现服务器的负载特别高,经常超过阈值,发现这种现象已经持续了一段时间:
复查操作记录发现早在12月11日我就将ELK套件升级到了最新版本,而我这个服务器因为是对外的,所以nginx的日志非常庞大,所以导致filebeat读取的时候性能顺好非常大。
0x02 filebeat
在我登入服务器查看相关参数时发现filebeat的CPU占用率居高不下:
而filebeat只巡检三个日志:
- input_type: log paths: - /usr/local/html/*/logs/ngx_access.log - /var/log/nginx/access.log tags: server_ngx_access_log - input_type: log paths: - /var/log/modsecurity/*/*/* tags: modsec_audit_log close_eof: true clean_*: true
其中modsecurity的审计日志记录形式为:
SecAuditLogType Concurrent
也就是每条日志保存为一个单一的文件,这个比较特殊,目录的层级结构如下:
[root@hk1 log]# tree modsecurity/ modsecurity/ ├── 20171210 │ ├── 20171210-0000 │ │ └── 20171210-000023-151283522357.275185 │ ├── 20171210-0014 │ │ ├── 20171210-001449-151283608954.936162 │ │ └── 20171210-001450-151283609056.525275 │ ├── 20171210-0019 │ │ ├── 20171210-001928-151283636851.191223 │ │ ├── 20171210-001933-151283637325.387680 │ │ └── 20171210-001943-151283638395.748607
因为这些文件最会写入一次,所以filebeat读取一次就可以将harvester(收集器)关闭,所以我在配置中将close_eof设为true。
因为我还有另一台服务器使用filebeat手机nginx日志,但没有使用modsecurity,所以我一度认为是因为是因为modsecurity日志的目录增多而导致filebeat负载过高。
当我去除modsecurity日志的读取配置并重启filebeat后发现高负载的情况依旧存在。不过为了降低filebeat状态注册表,我在配置文件中增加了clean_*这个配置,这样可以大大降低状态注册表的大小:
[root@hk1 ~]# ll -h /var/lib/filebeat/registry -rw------- 1 root root 636K 12月 18 21:39 /var/lib/filebeat/registry
这个文件记录着各个文件的读取情况以及偏移量,如果文件非常多,就会导致这个注册表文件逐渐变大,使用clean_*这个参数可以有效减少这个注册文件的大小。
最后我停止读取nginx日志并开始读取modsecurity的日志,发现CPU占用率得到了极大的改善,已经恢复到以前的水平。
在重新读取nginx日之后再次出现CPU负载变高的情况。
0x03 nginx
在比较两个服务器的日志发现香港服务器的nginx日志超过了2G:
[root@hk1 ~]# ll -h /usr/local/html/ngx.hk/logs/ngx_access.log -rw-r--r-- 1 nginx nginx 2.1G Dec 17 01:07 /usr/local/html/ngx.hk/logs/ngx_access.log
我的服务器会定期备份,所以这个庞大的日志也是一个大问题,将nginx日志截断就显得尤为重要。
因为我网站问的人很少,所以日志增长速度比较缓慢,阶段周期设置为每月进行较为合理。计划任务使用crontab即可,而脚本如下:
[root@hk1 ~]# cat /usr/local/shell/ngx_log_rotation_enginx.sh #!/bin/bash logs_path="/usr/local/html/ngx.hk/logs/" pid_path="/var/run/nginx.pid" mv ${logs_path}ngx_access.log ${logs_path}ngx_access_$(date +"%Y-%m").log kill -USR1 `cat ${pid_path}`
- logs_path:定义日志文件的路径
- pid_path:定义pid的路径
- mv:将文件重命名
注意mv命令中的日志文件名:ngx_access.log。请将这个文件名根据实际情况进行修改。
然后使用kill命令向nginx发送USR1信号,停止接收新的连接、等待当前连接断开后立即重载配置文件并重启服务。
因为我是每月分割一次,所以我的文件名为:
ngx_access_$(date +"%Y-%m").log
例如:
ngx_access_2017-12.log
如果需要按天备份,那么文件名建议为:
ngx_access_$(date +"%Y-%m").log
如:
ngx_access_20171218.log
接下来是定时任务,如果是每月1号执行,那么crontab为:
0 0 1 * * root sh /usr/local/shell/ngx_log_rotation_enginx.sh
上面语句的意思是每月1号的0点0分使用root用户执行shell命令。如果需要每天执行,则:
0 0 */1 * * root sh /usr/local/shell/ngx_log_rotation_enginx.sh
以上语句的意义为每天的0点0分使用root用户执行命令,注意一定要指定时与分!
0x04 结语
经过观察,最近服务器的负载已经恢复正常。不过我比较疑惑的是为什么filebeat 6.0.1会有这种问题,在5.6的时候并没有这个问题。
以下是最近三天的负载情况:
从图中可以很明显地看到负载分界线。