Nginx服务之安装和使用


纸上得来终觉浅,绝知此事要躬行。

Nginx服务之安装和使用


1. 简介

Nginx 是异步框架的网页服务器,也可以用作反向代理、负载平衡器和 HTTP 缓存。

Nginx最初设计是为了解决HTTP服务器C10K问题的,为了实现这个目的,Nginx通过基于事件的处理机制并且操作系统也要使用对应得事件机制。

1.1 HTTP 服务特性

  • 基础特性

    • 提供静态(static)和索引(indexautoindex)文件;同时支持文件描述符缓存
    • 支持更快的反向代理缓存;同时支持负载平衡和容错
    • 支持更快的FastCGIuwsgiSCGImemcached缓存;同时支持负载平衡和容错
    • 模块化的机构体系;过滤器包含gzipXSLTSSI、分块响应(chunk)和图像转换;如果它们运行在代理或者FastCGI等应用程序,则支持多个SSI包含在单个页面可以并行处理
    • 支持SSL/TLS加密协议
    • 支持加权和基于依赖关系的优先级的HTTP/2协议
  • 扩展特性

    • 支持基于名称(Name-based)和 IP 地址(IP-based)的虚拟主机
    • 支持Keep-alive和管道(pipline)连接机制
    • 访问日志格式、缓存日志写入、日志轮转和syslog日志
    • 3xx-5xx错误代码重定向
    • 重写模块(rewrite):基于正则表达式修改URI
    • 基于客户端地址执行不同操作(geohttp_user_agent等)
    • 支持基于客户端 IP 地址的访问控制,通过用户名/密码(basic)认证
    • 验证HTTP referer来源(invalid_referer)
    • 支持PUTDELETEMKCOLCOPYMOVE方法
    • 支持FLVMP4流媒体
    • 响应速度限制(limit_rate)
    • 限制的并发连接数(limit_conn)或请求来自一个地址(limit_req)
    • 基于 IP 地址的地理位置
    • A/B压力测试
    • 请求镜像(mirror)
    • 嵌入Perl
    • nginScript

1.2 邮件代理服务特性

  • 使用外部HTTP身份认证服务器重定向用户到IMAPPOP3
  • 用户身份验证使用外部HTTP身份验证服务器和连接重定向到内部SMTP服务器
  • 身份验证方法
    • POP3:USER/PASS、APOP、AUTH LOGIN/PLAIN/CRAM-MD5
    • IMAP:LOGIN、AUTH LOGIN/PLAIN/CRAM-MD5
    • SMTP:AUTH LOGIN/PLAIN/CRAM-MD5
  • 邮件支持SSL加密协议
  • 支持STARTTLSSTLS协议

1.3 TCP/UDP 代理服务特性

  • TCP 和 UDP 的通用代理
  • SSL 和 TLS 对 TCP 的支持
  • 负载平衡和容错
  • 基于客户地址的访问控制
  • 限制的并发连接数(limit_conn)或请求来自一个地址(limit_req)
  • 基于 IP 地址的地理位置
  • A/B压力测试
  • nginxScript

1.4 体系结构和可伸缩性

  • 一个master和多个worker进程组成,worker进程使用普通用户运行
  • 灵活的配置文件
  • 不中断更改配置和升级
  • 支持kqueue(FreeBSD 4.1+)、epoll(Linux 2.6+)、/dev/pollpolleventselect等事件驱动模型
  • 支持多种kqueue特性,如EV_CLEAREV_DISABLENOTE_LOWATEV_EOF、,可用数据的数量、错误代码
  • 支持多种epoll特性,如EPOLLRDHUPEPOLLEXCLUSIVE
  • 支持文件的AIO(异步 I/O)
  • 支持DIRECTIO
  • 10000不活跃的HTTP活动连接消耗 2.5M 内存
  • 数据拷贝操作都降到最低
事件驱动模块 解释 使用平台
select 标准方法;在平台不支持更高效的方法时,nginx 会自动编译此模块;--with-select_module/--without-select_module 基本都可以使用
poll 标准方法;在平台不支持更高效的方法时,nginx 会自动编译此模块;--with-poll_module/--without-poll_module 基本都可以使用
kqueue 高效的方法,推荐使用 FreeBSD 4.1+、OpenBSD 2.9+、NetBSD 2.0、macOS
epoll 高效的方法,推荐使用 Linux 2.6+
/dev/poll 高效的方法,推荐使用 Solaris 7 11/99+、HP/UX 11.22+ (eventport)、IRIX 6.5.15+
eventport 事件端口 Solaris 10 的高效方法

2. 安装

建议从官网直接获取最新的安装方式!

Nginx的安装方式有很多,常见的有包管理器安装(如源中提供了Nginx的安装包)、二进制包安装(没有提供了可以添加安装包源)、源代码编译安装(自定义配置时使用)。

2.1 包管理器安装

  • 使用包管理器安装 Nginx
    • 使用的发行版本中提供了Nginx安装包
    • 安装的Nginx会被安装到操作系统的标准位置下
    • 更多的适配版本,可以通过查看官方安装文档确认
# 基于deb的Linux
$ sudo apt-get install nginx

# 基于rpm的Linux
$ sudo yum install nginx

# FreeBSD
$ sudo pkg_install nginx
# 版本: nginx-1.13.8

RHEL/CentOS:
    Version    Supported Platforms
    6.x    x86_64, i386
    7.4+    x86_64, ppc64le

Debian:
    Version    Codename    Supported Platforms
    8.x    jessie    x86_64, i386
    9.x    stretch    x86_64, i386
  • 预编译二进制安装 Nginx
    • 对于没有发布Nginx二进制的系统(CentOS),可使用预编译安装
    • 安装分为稳定版本和主线版本,这里只说明了稳定版本的安装方式
# RHEL/CentOS配置稳定的版本Nginx

# 配置安装源
$ sudo vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1

# 包管理器安装
$ sudo yum install nginx
# Debian/Ubuntu配置稳定的版本Nginx

# 为了消除安装验证错误信息,需要添加签名的Key
$ sudo wget http://nginx.org/keys/nginx_signing.key
$ sudo apt-key add nginx_signing.key

# 将nginx.org仓库追加到/etc/apt/sources.list文件末尾
$ sudo vim /etc/apt/sources.list
deb http://nginx.org/packages/debian/ codename nginx
deb-src http://nginx.org/packages/debian/ codename nginx

# 包管理器安装
$ sudo apt-get install nginx

2.2 源代码编译安装

Nginx提供两个独立的分支,标准版本开发版本,区别在开发版中内部的API可能发生变动,而标准版不会变动且向下兼容第三方模块。

为了从源代码编译Nginx服务,操作系统需要具备某些必要的条件,如编译器(gcc 用于编译 C 和 C++代码)、SSL 支持(需要 OpenSSL 工具)、rewrite 模块支持(PCRE 库以及开发头文件)等。

如果在系统了使用--with-<library>=<path>选项,意为将其作为独立的静态的依赖库,从而提供性能和独立。如使用某些特定的版本工具时,就会需要使用此方法。

  • 编译配置
# 下载特定的Nginx源码包并解压
$ wget http://nginx.org/download/nginx-1.13.8.tar.gz
$ tar xzf nginx-1.13.8.tar.gz

# 需要自定义配置可以使用下列选项
$ cd nginx-1.13.8 && ./configure

# 编译安装
$ make && make install

2.3 编译的配置选项

Nginx提供了很多编译时使用的配置选项,根据用户不同的需求,可以配置成不同的服务器,如Web服务器、代理服务器、加速服务器等。

  • 通用配置选项
配置选项 选项说明
--prefix=path Nginx 安装的根路径;所有路径都要依赖该选项
--sbin-path=path 指定 Nginx 二进制文件的路径;如果没有指定,那么此路径依赖于–prefix 选项
--conf-path=path 如果在命令行没有指定配置文件,那么将会通过这里指定的路径
--pid-path=path 指定的文件将会写入 Nginx master 进程的 pid 号;如果不指定通常在/var/run 下
--error-log-path=path 指定错误文件路径,Nginx 将会往其中写入错误日志信息
--http-log-path=path 指定访问文件路径,Nginx 将会往其中写入访问日志信息
--user=name worker 进程运行的用户
--group=name worker 进程运行的组
--with-debug 启动调试日志功能;在生产环境下不建议开启
  • 优化配置选项
配置选项 选项说明
--with-select_module 使用 select 模型
--with-poll_module 使用 poll 模型
--with-file-aio 为 Linux2.6+系统启用异步 I/O
--with-cpu-opt=cpu 通过该选项为特定的 CPU 构建 Nginx
--with-pcre-jit 编译 PCRE 库时增加实时编译支持
--with-cc=path 如果想设置一个不再默认 PATH 路径下的 C 编译器
--with-cpp=path 设置 C 预处理器的对应路径
--with-cc-opt=parameters 指定必要的 include 文件路径
--with-ld-opt=parameters 包含连接器库的路径和运行路径
  • 指定路径的配置选项
配置选项 选项说明
--with-pcre=path 如果默认 PATH 路径找不到 Perl,则需要指定配置
--with-zlib=path 设置 zlib 库源文件的路径位置;该库应用于 ngx_http_gzip_module 模块
--with-http_perl_module 配置 nginx 能够使用 perl 代码;启用此选项会降低性能
--with-perl_modules_path=path 指定 Perl 解析器的路径
--http-proxy-temp-path=path 指定在使用代理后存放临时文件路径
--http-fastcgi-temp-path=path 指定 FastCGI 临时文件路径
--http-uwsgi-temp-path=path 指定 uWSGI 临时文件路径
--http-scgi-temp-path=path 指定 SCGI 临时文件路径
--http-client-body-temp-path=path 从客户端收到请求后,用于存放请求体临时存放的目录;如果启用 WebDAC 模块,推荐设置该路径为同一文件系统上的目录最为最终的目的地
# Nginx安装选项示例,基础配置
./configure
    --sbin-path=/usr/local/nginx/nginx
    --conf-path=/usr/local/nginx/nginx.conf
    --pid-path=/usr/local/nginx/nginx.pid
    --with-http_ssl_module
    --with-pcre=../pcre-8.41
    --with-zlib=../zlib-1.2.11
  • 邮件代理配置选项
配置选项 选项说明
--with-mail 启用 mail 模块;该模块默认没有被激活
-with-mail_ssl_module 启用任何一种类型的 SSL/TLS 支持
--without-mail_pop3_module 在启用 mail 模块后,单独禁用 POP3 模块
--without-mail_imap_module 在启用 mail 模块后,单独禁用 IMAP 模块
--without-mail_smtp_module 在启用 mail 模块后,单独禁用 SMTP 模块
--without-http 完全禁用 http 模块;如果只是想单独支持 mail 功能,可以禁止 nginx 的 http 功能
# Nginx安装选项示例,邮件配置
./configure
    --with-mail
    --with-mail_ssl_module
    --with-openssl=../openssl-1.0.1c
  • 使用模块的配置选项
配置选项 选项说明
--with-http_ssl_module 为 HTTP 服务器编译 HTTPS 协议支持的模块;该模块默认是不编译的;它需要 OpenSSL 库才能编译和运行
--with-http_realip_module 如果你的 Nginx 在七层负载均衡器或者其他设备之后,他们将 Http 头中的客户端 IP 地址传递,那么你需要启用此功能
--with-http_addition_module 这个模块作为一个输出过滤器,能够在请求经过一个 location 前或后时在该 location 本身添加内容
--with-http_image_filter_module 作为图像过滤器使用,在将图片投递给客户端之前进行处理;需要 libgd 库的支持才能运行和使用
--with-http_geoip_module 启用该模块能够基于地理位置查找客户端 IP 地址;需要 MaxMfind GeoIP 库和对应预编译数据库文件的支持
--with-http_sub_module 该模块实现了替代过滤,在响应中用一个字符串代替另一个字符串
--with-http_dav_module 启用该模块将激活使用 WebDAV 的配置指令
--with-http_flv_module 提供对 Flash 流媒体视频文件的支持
--with-http_mp4_module 提供对 H.264/AAC 文件流媒体的支持
--with-http_gzip_module 对于 gzip 的支持,用于为客户解压缩内容
--with-http_gunzip_module 对于不支持 gzip 编码的客户提供解压缩
--with-http_random_index_module 如果你想提供从一个目录中随机选择文件的索引文件
--with-http_sercure_link_module 提供了将一个哈希值链接到一个 URL 中,因此只有那些使用正确的密码能够计算链接
--with-http_stub_status_module 启用此模块时,将会收集 Nginx 自身的状态信息;输出的状态信息嫩能够通过 RRDtool 等工具绘制成图表
# Nginx安装选项示例,网络加速器/代理
./configure
    --with-http_ssl_module
    --with-http_realip_module
    --with-http_geoip_module
    --with-http_stub_status_module
    --with-openssl=../openssl-1.0.1c
  • 不使用模块的配置选项
配置选项 选项说明
--without-http_proxy_module 不编译 HTTP 服务器的代理模块
--without-http_gzip_module 不编译 http_gzip_module 模块;该模块可以压缩 HTTP 服务器的响应,该模块需要 zlib 库才能编译和运行
--without-http_rewrite_module 编译 http_rewrite_module 模块;该模块允许 HTTP 服务器重定向请求,改变请求的 URI 地址;创建并运行该模块需要 PCRE 库支持
--without-http_userid_module 使得 Nginx 能够设置 cookies,用于客户标识;变量$uid_set$uid_got可以记录用户追踪
--without-http_access_module access 模块支持基于 IP 控制访问 location
--without-http_auth_basic_module 支持 Http 基本身份验证访问控制
--without-http_autoindex_module 如果一个目录中没有 index 文件,那么 autoindex 模块能够列出这个目录的文件
--without-http_map_module 能够让你映射一个变量到另一个变量
--without-http_geo_module 能够让你基于客户端 IP 地址设置配置变量,然后根据这些变量的值采取行动
--without-http_split_clients_module 能够创建基于 A/B 测试的变量
--without-http_referer_module 能够让 Nginx 阻止基于 http 中 referer 头的请求
--without-http_fastcgi_module FastCGI 模块能够让 Nginx 将请求传递给 FastCGI 服务器
--without-http_uwsgi_module uWSGI 模块能够让 Nginx 将请求传递给 uWSGI 服务器
--without-http_scgi_module SCGI 模块能够让 Nginx 将请求传递给 SCGI 服务器
--without-http_memcached_module 能够让 Nginx 与一个 memcachedf 服务器进行交互,将响应放置到变量查询中
--without-http_limit_conn_module 能够让 Nginx 基于某些键设置连接限制;通常是 IP 地址
--without-http_limit_req_module 能够让 Nginx 限制每个用户的请求率
--without-http_browser_module 允许基于 User-Agent 请求头配置,变量的设置基于在该头中发现的版本
--without-http_upstream_ip_module 该模块定义了一组可以与不同的代理模块结合使用的服务器

注:配置选项太多了,而且模块也非常多,建议参考英文的官方文档


2.4 第三方扩展模块

由于有多个开源项目,所有Nginx开发社区十分活跃,从而诞生出了很多第三方的扩展模块,补充了官方版本中不具有的新特性。如Tengine就是由淘宝在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。

  • 安装
    • 找到你想使用的第三方模块(Github或者3rdPartyModules)
    • 下载该模块并解压源代码包
    • 如果存在 README 文件,请仔细阅读并查看依赖安装
    • 通过/configure-add-modules=path选项配置使用该模块
  • 注意
    • 很多第三方模块都是实验性质的,不建议用在生产中去
    • Nginx 开发版中科院会有 API 发生变化,导致第三方模块无法使用
./configure
    # 常规配置
    --prefix=opt/nginx
    --user=www
    --group=www
    # 使用的模块
    --with-http_ssl_module
    --with-http_realip_module
    --with-http_sub_module
    --with-http_flv_module
    --with-http_mp4_module
    --with-http_gzip_static_module
    --with-http_gunzip_module
    --with-http_secure_link_module
    --with-http_stub_status_module
    # 不使用的模块
    --without-http_uwsgi_module
    --without-http_scgi_module
    --without-http_borwser_module
    # 临时目录
    --http-proxy-temp-path=/home/www/tmp/proxy_temp
    --http-fastcgi-temp-path=/home/www/tmp/fastcgi_temp
    --http-client-body-temp-path=/home/www/tmp/client_body_temp
    # 安装指定版本的工具
    --with-openssl=../openssl-1.0.1c
    --with-pcre=../pcre-8.32
    # 安装第三方模块
    --add-module=../ngx_devel_kit_0.2.17
    --add-module=../ngx_lua-0.7.9

3. 使用

使用方法还是非常简单,好用的!

Nginx 是由一个master进程和多个worker进程组成的。master进程主要负责读取配置文件以及管理worker进程,而worker进程才是实际的请求处理者。更多的信号量,可以参考官方 Controlling Nginx 文档。

3.1 起停服务

  • 基本使用方法
# 快速停止服务
$ nginx -s stop

# 优雅停止服务
$ nginx -s quit

# 重载配置文件
$ nginx -s reload

# 重新打开日志文件
$ nginx -s reopen
  • 特点纪要
# reload参数
使用reload重载配置文件时,master进程会先检查配置文件是否存在语法错误。
如果正常,则master进程会启动新的worker进程并且发送命令给老的worker进程让它们关闭。
老的worker进程接收到命令之后,停止接收新的客户端请求,处理完当前的请求之后自动终止服务

# kill命令
当然终止服务也可用通过kill工具接收信号量,一般会传递PID号。
通常PID号会存放在/usr/local/nginx/logs或者/var/run目录的nginx.pid文件中。
$ kill -s QUIT 1246

3.2 简单配置

  • 静态内容服务器
# HTML文件和图片文件静态分离
http {
    server {
        listen      80;
        server_name "";

        location / {
            root /data/www;
        }

        location /images/ {
            root /data;
        }
    }
}
  • 简单的代理服务器
http {
    server {
        listen      80;
        server_name "";

        location / {
            proxy_pass http://localhost:8080;
        }
    }

    server {
        listen 8080;
        root /data/up1;

        location ~ \.(gif|jpg|png)$ {
            root /data/images;
        }
    }
}
  • 连接 FastCGI 后端服务器
http {
    server {
        location / {
            fastcgi_pass  localhost:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param QUERY_STRING    $query_string;
        }

        location ~ \.(gif|jpg|png)$ {
            root /data/images;
        }
    }
}

3.3 配置文件实例

  • 网站将所有的请求都发给后端,除了图片和下载
user  www www;
worker_processes  2;
pid /var/run/nginx.pid;

# [debug|info|notice|warn|error|crit]
error_log  /var/log/nginx.error_log  info;


events {
    worker_connections   2000;
    # use [kqueue|epoll|/dev/poll|select|poll];
    use kqueue;
}


http {
    include       conf/mime.types;
    default_type  application/octet-stream;

    log_format main      '$remote_addr - $remote_user [$time_local] '
                         '"$request" $status $bytes_sent '
                         '"$http_referer" "$http_user_agent" '
                         '"$gzip_ratio"';

    log_format download  '$remote_addr - $remote_user [$time_local] '
                         '"$request" $status $bytes_sent '
                         '"$http_referer" "$http_user_agent" '
                         '"$http_range" "$sent_http_content_range"';

    client_header_timeout  3m;
    client_body_timeout    3m;
    send_timeout           3m;

    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    gzip on;
    gzip_min_length  1100;
    gzip_buffers     4 8k;
    gzip_types       text/plain;

    output_buffers   1 32k;
    postpone_output  1460;

    sendfile         on;
    tcp_nopush       on;
    tcp_nodelay      on;
    send_lowat       12000;

    keepalive_timeout  75 20;

    #lingering_time     30;
    #lingering_timeout  10;
    #reset_timedout_connection  on;


    server {
        listen        one.example.com;
        server_name   one.example.com  www.one.example.com;

        access_log   /var/log/nginx.access_log  main;

        location / {
            proxy_pass         http://127.0.0.1/;
            proxy_redirect     off;

            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            #proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;

            client_max_body_size       10m;
            client_body_buffer_size    128k;

            client_body_temp_path      /var/nginx/client_body_temp;

            proxy_connect_timeout      70;
            proxy_send_timeout         90;
            proxy_read_timeout         90;
            proxy_send_lowat           12000;

            proxy_buffer_size          4k;
            proxy_buffers              4 32k;
            proxy_busy_buffers_size    64k;
            proxy_temp_file_write_size 64k;

            proxy_temp_path            /var/nginx/proxy_temp;

            charset  koi8-r;
        }

        error_page  404  /404.html;

        location /404.html {
            root  /spool/www;
        }

        location /old_stuff/ {
            rewrite   ^/old_stuff/(.*)$  /new_stuff/$1  permanent;
        }

        location /download/ {
            valid_referers  none  blocked  server_names  *.example.com;

            if ($invalid_referer) {
                #rewrite   ^/   http://www.example.com/;
                return   403;
            }

            #rewrite_log  on;

            # rewrite /download/*/mp3/*.any_ext to /download/*/mp3/*.mp3
            rewrite ^/(download/.*)/mp3/(.*)\..*$
                    /$1/mp3/$2.mp3                   break;

            root         /spool/www;
            # autoindex    on;
            access_log   /var/log/nginx-download.access_log  download;
        }

        location ~* \.(jpg|jpeg|gif)$ {
            root         /spool/www;
            access_log   off;
            expires      30d;
        }
    }
}

4. 升级

建议直接参考官方的升级方法!

随着时间的推移,后续大量服务会存在安全漏洞问题,如果更新对应服务就是一个问题了。

4.1 Ubuntu

# Install the prerequisites
$ sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring

# Import an official nginx signing key
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# Verify the proper key
$ gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

# To set up the apt repository
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

# To install nginx
$ sudo apt update
$ sudo apt install nginx

4.2 RHEL/CentOS

# Install the prerequisites
$ sudo yum install yum-utils

# To set up the yum repository
$ sudo vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

# To install nginx
$ sudo yum install nginx

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录