今年进行了一次Nginx的大面积升级,把Nginx的安装配置方法记录一下。

依赖准备

  1. 下载一个稳定版本的Nginx源码包

  2. 因为Nginx一般都是挡在最前面的系统,所以要做一些基本的保护,防止死机,github上有一些开源项目可以集成到Nginx中去,比如nginx-http-sysguard。

  3. NginxPlus版本有自定义心跳检查的功能,但是免费版没有提供。为什么要自定义,而不是用默认的upstream心跳检查呢?如果能自定义的话,可以做更加优雅平滑的发布,还可以做引流压测。

  4. Nginx默认的监控比较弱,同样丰富的监控都在NginxPlus里提供,只能自己开发了。配套定制一下Tsar,将监控信息记录在Tsar中。

  5. 现在绝大多数网站都是https了,所以openssl和证书也要准备好。openssl这两年出了好多头条,慎重选择。

  6. Nginx编译时依赖的一些包,比如:pcre、zlib、perl-devel、perl-ExtUtils-Embed等

  7. Nginx的服务器一般都有外网IP,所以也需要定制一些防火墙策略。

  8. 为了提高Nginx的吞吐能力需要修改一些系统参数(/etc/sysctl.conf和/etc/security/limits.conf)

  9. Nginx日志默认是没有daily-rolling功能的,需要配和其他软件来实现。之前是用cronlog和fifo文件来实现的,这次统一换成logrotate,logrotate相关资料这里就不介绍了。注意不要使用copy模式,Nginx的accesslog很大,copy非常消耗性能。下面给一个配置的例子:

/log/nginx/*.log {
    daily
    rotate 1
    missingok
    nocompress
    notifempty
    dateext
    postrotate
    if [ -f /pid/nginx.pid ]; then
        kill -USR1 `cat /pid/nginx.pid`
    fi
    endscript
}

编译安装

Nginx启动一般需要80端口,如果不想用root来启动的话,就需要特殊处理一下

src/nginx/configure --prefix=/local/nginx ....
make -j ${nc} && make install
chown -R nginx:nginx /local/nginx
chown root:nginx /local/nginx/sbin/nginx
chmod 6755 /local/nginx/sbin/nginx

Nginx配置

Nginx的配置实在是太多了,下面只写一些值得注意的配置项

  1. worker_processes和worker_cpu_affinity 在新版nginx中都可以设置为auto

  2. log_format中$upstream_addr最好用引号或者中括号扩起来,因为他的输出不仅仅是一个IP,可能是多个Ip或者upstream的名字或者是中横线

  3. merge_slashes合并url中连续出现的两个/,防止url拼接错误导致无法访问

  4. proxy_set_header设置要注意,在http、server、location层都能够进行定义,但是并不是merge覆盖的逻辑,官方文档是这样说的,These directives are inherited from the previous level if and only if there are no proxy_set_header directives defined on the current level。

  5. proxy_ignore_client_abort默认为off,千万不要轻易开启。可能会导致Nginx活跃链接数持续增长,tcp状态close_wait持续增长,只能重启Nginx进程才能回收,网上说的修改linux内核参数也无法回收。大致过程是,客户端发起请求,后端的业务服务器无法及时响应该请求等待超时,如果客户端配置了较短的超时,客户端就会主动关闭此连接,当Nginx断开与tomcat的proxy连接时,客户端连接早已不存在了,此连接就会挂在Nginx上,无法释放。

  6. ssl_ciphers设置不当可能导致某些浏览器无法访问,认为网站是不安全的,在IE和Firefox中尤为明显。ssl相关配置有一些自动生成器,github上也有一些自动的shell脚本可以参考。

  7. 简化proxy_pass对应upstream的配置,可以将upstream的名字设置为host的值(proxy_pass http://$host;),这样很多server的配置就可以复用了。

  8. server同时有80和443可以配置成这样:

listen 80;
listen 443 ssl;