Nginx重新加载配置最佳实践

时间:2016-12-08 03:14:34

标签: nginx

目前正在设置一个nginx反向代理负载平衡各种域名。

nginx配置文件是以编程方式生成的,可能会经常更改(即添加或删除http / https服务器)

我正在使用:

nginx -s reload

告诉nginx重新读取配置。

主nginx.conf文件包含所有生成的配置文件的包含:

http {
  include /volumes/config/*/domain.conf;
}

包含的配置文件可能如下所示:

server {
  listen 80;
  listen [::]:80;
  server_name mydomain.com;
  location / {
    try_files $uri /404.html /404.htm =404;
    root /volumes/sites/mydomain;
  }
}

我的问题:

运行是健康的还是有害的:

nginx -s reload

每分钟多次通知nginx考虑对配置的修改? 这意味着什么样的表现?

编辑:我想重新提出一个问题:我们如何能够经常动态更改nginx的配置而不会出现大的性能影响?

3 个答案:

答案 0 :(得分:2)

我会在包含生成的conf文件的目录上使用inotifywatch超时,并且只有在此期间在所述目录中修改/创建/删除了某些内容时才重新加载nginx

  

-t, - timeoutout
仅收听指定的秒数。如果未指定,inotifywatch将收集   统计信息直到收到中断信号(例如)   在控制台按CONTROL-C。

while true; do
    if [[ "$(inotifywatch -e modify,create,delete -t 30 /volumes/config/ 2>&1)" =~ filename ]]; then
        service nginx reload;
    fi;
done

通过这种方式,您可以设置一个最小计时器,然后重新加载,在inotifywait的来电之间不会丢失任何监视。

答案 1 :(得分:0)

我建议不要每分钟重复加载nginx几次,只有在保存更改时才会观察配置文件并执行重新加载;您可以使用以下命令inotifywait(通过inotify-tools包提供):

while inotifywait -e close_write /etc/nginx/sites-enabled/default; do service nginx reload; done

答案 2 :(得分:0)

如果您

  1. 使用类似于provided in this answer的脚本,我们称其为check_nginx_confs.sh
  2. 在nginx.service中更改您的ExecStart指令,使/etc/nginx//dev/shm/nginx/
  3. /etc/init.d/添加脚本以将conf文件复制到您的临时目录中------------------------ mkdir /dev/shm/nginx && cp /etc/nginx/* /dev/shm/nginx
  4. 使用rsync(或其他同步工具)将/dev/shm/nginx同步回到/etc/nginx;因此您不会丢失重新启动时在/dev/shm/nginx中创建的配置文件。或者只是将两个位置都置于应用内,以便根据需要进行原子检查
  5. 设置一个cronjob来运行check_nginx_confs.sh中的文件“变旧”的次数check_nginx_confs.sh,这样您就可以知道上次时间范围内是否发生了更改,但只需检查一次即可。
  6. 如果systemctl reload ngnix仅在$ OLDTIME定义的每个时间段内找到一个新文件,则check_nginx_confs.sh
  7. 休息

现在,nginx将更快地加载那些配置;从RAM。仅在需要时,它才会每$ OLDTIME秒重新加载一次。除了将请求路由到您自己的动态处理程序之外;这可能是让Nginx经常重新加载最快的方法

为您使用的temp目录保留一定的磁盘配额是一个好主意,以确保不会耗尽内存。有多种方法可以实现这一目标。您还可以将符号链接添加到一个空的磁盘目录中,以防万一您不得不溢出,但这会带来很多confs

其他答案的脚本:

#!/bin/sh

# Input file
TESTDIR=/dev/shm/nginx
# How many seconds before dir is deemed "older"
OLDTIME=75 
#add a little grace period, optional
# Get current and file times
CURTIME=$(date +%s)
FILETIME=$(date -r $TESTDIR +%s)
TIMEDIFF=$(expr $CURTIME - $FILETIME)

# Check if dir updated in last 120 seconds
if [ $OLDTIME -gt $TIMEDIFF ]; then
   systemctl nginx reload
fi

# Run me every 1 minute with cron

(可选);如果您愿意,可以使用一些&&魔术符将复制和同步命令放入nginx.service的ExecStart中,以便它们总是一起出现。您还可以&&一种“析构函数”进行最终同步并释放ExecStop上的/dev/shm/nginx。这将代替步骤(3)和(4)

cron的替代者;您可以让一个脚本在后台运行一个循环并等待一段时间。如果这样做,您可以在两个脚本之间来回传递LastUpdateTime,以提高准确性,因为LastUpdateTime + GracePeriod更可靠。这样,我仍然会使用cron定期确保循环仍在运行

作为参考,在我的CentOS 7映像上,nginx.service位于 /usr/lib/systemd/system/nginx.service