Aldebaran

人生最棒的感觉,就是你做到别人说你做不到的事。

0%

源码编译Nginx

三田寺円

前言

Nginx是异步框架的Web服务器,也可以用作反向代理,负载平衡器 和 HTTP缓存。该软件由Igor Sysoev 创建,并于2004年首次公开发布。 同名公司成立于2011年,以提供支持。2019年3月11日,Nginx公司被F5 Networks以6.7亿美元收购。

Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性:

  • 作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型.
  • 作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。
  • 作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),Last.fm 描述了成功并且美妙的使用经验。

正常安装Nginx的时候如果没特殊需要, 建议直接yum/apt安装。当然如果有需求则需要编译了。

准备工作

  • 下载对应版本的源码包。

    $ cd /usr/local/src
    $ sudo wget http://nginx.org/download/nginx-1.14.2.tar.gz
    $ sudo wget https://ftp.pcre.org/pub/pcre/pcre-8.42.tar.gz
    $ sudo wget http://zlib.net/zlib-1.2.11.tar.gz
    $ sudo wget https://www.openssl.org/source/openssl-1.1.1b.tar.gz
    
  • 同级目录解压。

    $ sudo tar xf nginx-1.14.2.tar.gz
    $ sudo tar xf pcre-8.42.tar.gz
    $ sudo tar xf zlib-1.2.11.tar.gz
    $ sudo tar xf openssl-1.1.1b.tar.gz
    
  • 安装相关的编译依赖包

    ## CentOS
    $ sudo yum -y install gcc gcc+ gcc-c++ vixie-cron ntsysv make \
      patch sysstat dos2unix flex bison autoconf automake \
      bzip2-devel zlib-devel ncurses-devel libjpeg-devel libpng-devel \
      libtiff-devel freetype-devel pam-devel openssl openssl-devel \
      mod_ssl libxml2-devel gettext-devel pcre-devel curl-devel \
      libevent-devel perl-devel perl-ExtUtils-Embed libxslt libxslt-devel \
      GeoIP GeoIP-devel GeoIP-data gd-devel
    
    ## Ubuntu
    $ sudo apt-get -y install autoconf automake build-essential pkg-config \
          libperl-dev libxml2 libxslt1-dev libgeoip-dev zlib1g-dev libssl-dev
    
  • 创建nginx用户,并禁止其登陆

    $ sudo useradd -s /sbin/nologin nginx
    

编译安装

  $ cd /usr/local/src/nginx-1.14.2
  $ sudo ./configure --user=nginx --group=nginx \
      --prefix=/usr/local/nginx-1.14.2 \
      --conf-path=/usr/local/nginx-1.14.2/conf/nginx.conf \
      --pid-path=/var/run/nginx.pid \
      --with-compat \
      --with-pcre=../pcre-8.42 \
      --with-zlib=../zlib-1.2.11 \
      --with-openssl=../openssl-1.1.1b \
      --with-stream \
      --with-stream_ssl_module \
      --with-stream_realip_module \
      --with-stream_geoip_module \
      --with-http_ssl_module \
      --with-http_v2_module \
      --with-http_geoip_module \
      --with-http_realip_module \
      --with-http_xslt_module \
      --with-file-aio \
      --with-http_auth_request_module \
      --with-http_gzip_static_module \
      --with-http_secure_link_module \
      --with-http_sub_module \
      --with-http_slice_module \
      --with-http_stub_status_module

   ## 正常上述的编译参数已经可以满足正常的工作需求。
   ## 如果要缩略图功能那么 --with-http_image_filter_module
   ## 如果想要Nginx支持perl脚本,那么需要添加 --with-http_perl_module

  $ sudo make && make install
  $ sudo ln -s /usr/local/nginx-1.14.2 /usr/local/nginx

守护进程

编译完Nginx是需要自己创建启动脚本的。

systemd(centos7/ubuntu16/ubuntu18)

systemd系统下的脚本可以参考下面创建(记得修改目录)

  1. nginx.service(可选)

     $ vim /usr/lib/systemd/system/nginx.service
    
     # Stop dance for nginx
     # =======================
     #
     # nginx signals reference doc:
     # https://www.nginx.com/resources/wiki/start/topics/examples/systemd/
     [Unit]
     Description=The NGINX HTTP and reverse proxy server
     After=syslog.target network.target remote-fs.target nss-lookup.target
    
     [Service]
     Type=forking
     PIDFile=/var/run/nginx.pid
     ## Execute pre and post scripts as root
     #PermissionsStartOnly=true
     ExecStartPre=/usr/local/nginx/sbin/nginx -t
     ExecStart=/usr/local/nginx/sbin/nginx
     ExecReload=/usr/local/nginx/sbin/nginx -s reload
     ExecStop=/bin/kill -s QUIT $MAINPID
     PrivateTmp=true
    
     [Install]
     WantedBy=multi-user.target
    
  2. nginx.service(可选)

     $ vim /usr/lib/systemd/system/nginx.service
    
     # Stop dance for nginx
     # =======================
     #
     # ExecStop sends SIGSTOP (graceful stop) to the nginx process.
     # If, after 5s (--retry QUIT/5) nginx is still running, systemd takes control
     # and sends SIGTERM (fast shutdown) to the main process.
     # After another 5s (TimeoutStopSec=5), and if nginx is alive, systemd sends
     # SIGKILL to all the remaining processes in the process group (KillMode=mixed).
     #
     # nginx signals reference doc:
     # http://nginx.org/en/docs/control.html
     #
     [Unit]
     Description=A high performance web server and a reverse proxy server
     Documentation=man:nginx(8)
     After=network.target
    
     [Service]
     Type=forking
     PIDFile=/var/run/nginx.pid
     ExecStartPre=/usr/local/nginx/sbin/nginx  -t -q -g 'daemon on; master_process on;'
     ExecStart=/usr/local/nginx/sbin/nginx  -g 'daemon on; master_process on;'
     ExecReload=/usr/local/nginx/sbin/nginx  -g 'daemon on; master_process on;' -s reload
     ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /var/run/nginx.pid
     TimeoutStopSec=5
     KillMode=mixed
    
     [Install]
     WantedBy=multi-user.target
    

init/service(centos6/ubuntu14)

service系统下的脚本,正常在Nginx编译包里面的contrib里面有个参考脚本。

由于未来的主流操作系统版本都是systemd系统,这里就不贴出来了。

调整配置文件

  • 调整路径,拷贝配置文件

    $ mkdir /var/log/nginx
    # /run一般都有,需要注意: /run是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。如果你的系统上有/var/run目录,应该让它指向/run。
    $ mkdir /var/run
    $ mkdir -p /data/httplogs/old
    $ mkdir /usr/local/nginx/conf/vhosts
    $ mkdir /usr/local/nginx/conf/stream
    $ sudo cp -pv /usr/local/nginx/conf/nginx.conf{,.default}
    

具体的参数调整可以查看这一章

  • 启动Nginx

      $ systemctl daemon-reload
      $ systemctl enable nginx
      $ systemctl start nginx
      $ systemctl stop nginx
      $ systemctl reload nginx
    

使用logrotate日志切割

使用logrotate切割Nginx日志,具体可以查考下面。

$ vim /etc/logrotate.d/nginx

/data/httplogs/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    copytruncate
    dateext
    dateyesterday
    # dateformat .%Y%m%d%H
    create 0640 nginx nginx
    olddir /data/httplogs/old
    sharedscripts
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi \
    endscript
    postrotate
        /bin/systemctl reload nginx >/dev/null 2>&1
    endscript
}

# 启动logrotate
$ logrotate -vf /etc/logrotate.d/nginx