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