Nginx服务之安装和使用
纸上得来终觉浅,绝知此事要躬行。
1. 简介
Nginx 是异步框架的网页服务器,也可以用作反向代理、负载平衡器和 HTTP 缓存。
Nginx最初设计是为了解决HTTP服务器C10K问题的,为了实现这个目的,Nginx通过基于事件的处理机制并且操作系统也要使用对应得事件机制。
1.1 HTTP 服务特性
- 基础特性
- 提供静态(static)和索引(index、autoindex)文件;同时支持文件描述符缓存
- 支持更快的反向代理缓存;同时支持负载平衡和容错
- 支持更快的FastCGI、uwsgi、SCGI和memcached缓存;同时支持负载平衡和容错
- 模块化的机构体系;过滤器包含gzip、XSLT、SSI、分块响应(chunk)和图像转换;如果它们运行在代理或者FastCGI等应用程序,则支持多个SSI包含在单个页面可以并行处理
- 支持SSL/TLS加密协议
- 支持加权和基于依赖关系的优先级的HTTP/2协议
- 扩展特性
- 支持基于名称(Name-based)和 IP 地址(IP-based)的虚拟主机
- 支持Keep-alive和管道(pipline)连接机制
- 访问日志格式、缓存日志写入、日志轮转和syslog日志
- 3xx-5xx错误代码重定向
- 重写模块(rewrite):基于正则表达式修改URI
- 基于客户端地址执行不同操作(geo、http_user_agent等)
- 支持基于客户端 IP 地址的访问控制,通过用户名/密码(basic)认证
- 验证HTTP referer来源(invalid_referer)
- 支持PUT、DELETE、MKCOL、COPY和MOVE方法
- 支持FLV和MP4流媒体
- 响应速度限制(limit_rate)
- 限制的并发连接数(limit_conn)或请求来自一个地址(limit_req)
- 基于 IP 地址的地理位置
- A/B压力测试
- 请求镜像(mirror)
- 嵌入Perl
- nginScript
1.2 邮件代理服务特性
- 使用外部HTTP身份认证服务器重定向用户到IMAP和POP3
- 用户身份验证使用外部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加密协议
- 支持STARTTLS和STLS协议
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/poll、poll、event、select等事件驱动模型
- 支持多种kqueue特性,如EV_CLEAR、EV_DISABLE、NOTE_LOWAT、EV_EOF、,可用数据的数量、错误代码
- 支持多种epoll特性,如EPOLLRDHUP、EPOLLEXCLUSIVE
- 支持文件的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