Nginx与OpenResty资料整理
Contents
编译所需依赖库
GCC
: 编译器PCRE
: 用于正则表达式处理zlib
: 用于 gzip 处理openssl
: 用于HTTPS, MD5 等处理sudo apt-get update build-essential libtool gcc automake autoconf make sudo apt-get install openssl libssl-dev sudo apt-get install zlib1g-dev sudo apt-get install libpcre3 libpcre3-dev
系统常用参数配置
查看原来的值
sysctl fs.file-max
sysctl net.ipv4.tcp_tw_reuse
sysctl net.ipv4.tcp_keepalive_time
sysctl net.ipv4.tcp_fin_timeout
sysctl net.ipv4.tcp_max_tw_buckets
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem
sysctl net.core.netdev_max_backlog
sysctl net.core.rmem_default
sysctl net.core.wmem_default
sysctl net.core.rmem_max
sysctl net.core.wmem_max
sysctl net.ipv4.tcp_syncookies
sysctl net.ipv4.tcp_max_syn_backlog
/etc/sysctl.conf
fs.file-max=999999
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_keepalive_time=600
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_max_tw_buckets=5000
net.ipv4.ip_local_port_range=1024 65535
net.ipv4.tcp_rmem=4096 32768 262142
net.ipv4.tcp_wmem=4096 32768 262142
net.core.netdev_max_backlog=8096
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=2097152
net.core.wmem_max=2097152
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_max_syn_backlog=1024
查看某个值: sysctl net.ipv4.ip_local_port_range
之后执行 sudo sysctl -p 命令来生效
陶辉 著. 深入理解Nginx:模块开发与架构解析(第2版) (Linux/Unix技术丛书) (Chinese Edition) (Kindle Locations 427-430). Kindle Edition.
编译/控制命令
查看编译参数 ./configure --help
./configure
make -j8
make install
常用命令
# 启动
nginx
# 指定配置文件
nginx -c path/to/nginx.conf
# 显示版本
nginx -v
# 显示编译参数
nginx -V
# 快速停止. 注意, 这种是不会等处理完请求的...
nginx -s stop
等效于
kill -s SIGTERM pid
kill -s SIGINT pid
# 优雅停止
nginx -s quit
等效于
kill -s SIGQUIT pid
停止 worker 的话则
kill -s SIGWINCH workerPid
# 重新读取配置文件
nginx -s reload
# 日志文件回滚
nginx -s reopen
等效于
kill -s SIGUSR1 pid
Nginx配置
- 配置项的单位.
K 或 k
表示 KB,M 或 m
表示 MB - 时间的单位:
ms
,s
,m
,h
,d
,w
,M
,y
核心功能配置 http://nginx.org/en/docs/ngx_core_module.html
注意, 如果想要 debug 信息, 需要在编译时, 加上
--with-debug
配置项
include
指令, 可以是绝对路径, 也可以相对路径(即相对于nginx.conf
所在的目录)
性能配置项
worker_processes
worker_cpu_affinity
worker_rlimit_nofile
# ssl 硬件加速
ssl_engine
# 系统调用 gettimeofday 的执行频率
timer_resolution
# worker 进程的 nice 优先级. -20 ~ 19 . 越小表示优先级越高
worker_priority
事件配置项
# 负载均衡锁. 它可让多个 worker 轮流地, 序列化地与新客户建立 TCP. 当某个 woker 达到 worker_connections 配置的最大连接数的 7/8 时, 会大大减小该 woker 试图建立连接的机会
accept_mutex
# accept_mutex 可能需要. 只有在开启 accept_mutex , 并且系统不支持原子锁, 才会用文件锁来实现
lock_file
# 使用锁后到真正建立连接之间的延迟时间. 即如果 worker 试图获取 accept 锁而没有取到, 则至少等待该时间间隔后才能再次试图获取
accept_mutex_delay
# 批量建立连接. 即尽可能地对本次调度中客户端发起的所有 TCP 请求都建立连接
multi_accept
虚拟主机
每个 server
块就是一个虚拟主机. 可显式通过 default
指定整个 Web 服务的默认虚拟主机.
如果没有指定 default
, 则会在 nginx.conf
中找到的第一个 server
作为默认的虚拟主机.
deferred
指令. 只有连接真正有数据时, 才会唤醒 worker 来处理这个连接, 而不是建立连接时就唤醒.
server_name
指令匹配
- 从
header
中获取Host
, 然后与每个server
中的server_name
匹配 - 首先完全匹配
server_name
. 如www.qq.com
- 其次通配符在前端的
server_name
. 如*.qq.com
- 再次通配符在后面的. 如
www.qq.*
- 最后使用正则才匹配的.
- 如果以上都不匹配. 则再按以下顺序处理
- 优先 listen 后加上 default 的 server
- 找到匹配 listen 的第一个 server
- 如果
server_name
后是字字符串, 那么表示匹配没有 Host 这个 HTTP 头部
的请求
server_name_hash_bucket_size
, nginx 使用散列表来存储 server name . 该参数表示每个散列桶占用的内存大小.
server_name_hash_max_size
: 它会影响散列表的冲突率. 越大, 冲突越小, 检索速度也越快.
location
指令. 匹配规则
=
表示把 URI 作为字符串, 以便与参数中的 uri 做完全匹配~
表示匹配 URI 时是大小写敏感的~*
表示 URI 大小写不敏感^~
表示只需要前半部分与 uri 参数匹配即可@
仅用于 nginx 内部请求之间的重定向, 不直接处理用户请求.- uri 参数可以用正则表达式
- 它是有顺序的, 请求会被第一个匹配到的 location 处理
root
指令 . 路径配置
- 它定义的是相对于 HTTP 请求的根目录.
- 例如
root /opt/html/;
则请求的 URI 是/res/hello.html
, 则文件完整的路径为/opt/html/res/hello.html
alias
指令.
- 它不同于 root. 它是解读紧跟在 location 后的 uri 参数的.
- 一个请求
/res/hello.html
, 而实际想访问的是/opt/html/res/hello.html
- 则配置为
location /res { alias /opt/html/res/; }
- 如果为 root 则是
/opt/html/
index
指令: 访问首页. 可跟多个文件参数. 按顺序优先访问.
error_page code
: 根据错误码重定向新 URI
内存及磁盘分配
# 请求 body 只存储到文件. on 表示请求完后不删除. clean 表示请求完后删除
client_body_in_file_only
# 请求头保存时分配的 buffer 大小. 有时会超过该大小, 这时 large_client_header_buffers 将会生效
client_header_buffer_size
# 超大请求头. 如果请求行大小超过单个 buffer 大小, 则返回 Request URI too large 414. (注意, 是请求行, 即请求头的每一行)
# 请求行和请求头的总和, 不可以超过 buffer 个数 * buffer 大小
large_client_header_buffers
# 存储请求 body 的内存 buffer 大小
client_body_buffer_size
# 请求 body 临时存放目录. 如果 body 大小超过 client_body_buffer_size, 则会以一个递增的整数命名并存放到 client_body_temp_path 指定的目录中. 后面的 level1, level2, level3 是为了防止一个目录下的文件数量太多, 从而导致性能下降, 因此使用了 level 参数.
client_body_temp_path
# 每个建立成功的 TCP 会预先分配一个内存池, 这个参数将指定内存池的初始大小. TCP 连接关闭时会销毁.
connection_pool_size
# 为每个请求都分配一个内存池. 该参数指定初始大小.http 请求结束时会销毁. 注意, 一条连接, 可能被复用于多个请求
request_pool_size
网络连接配置
# 读取 header 时超时
client_header_timeout
# 读取 body 时超时
client_body_timeout
# 发送响应超时. 即服务器向 client 发送了数据, 但客户端一直没接收
send_timeout
# 连接超时后, 向客户端发送 RST 包来重置连接
reset_timedout_connection
# nginx 关闭用户连接的方式.
## always 表示无条件处理连接上所有用户发送的数据.
## off 表示不管连接是否有数据
## on 中间值. 一般会处理完数据.
lingering_close
# 经过 lingering_time 后, nginx 将不管用户是否仍在发送数据, 都会将连接关闭
lingering_time
# lingering_close 生效后, 在关闭之前, 会检测是否有用户数据到达. 超过 lingering_timeout 时间后还没有数据, 则直接关闭连接. 否则在读取完连接缓冲区上的数据并丢弃后才会关闭连接
lingering_timeout
keepalive_timeout
# 一个 keepalive 长连接上允许承载的请求最大数(注意, 是按每条)
keepalive_requests
tcp_nodelay
tcp_nopush
core module 的变量
http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
变量 | 描述 |
---|---|
$arg_name |
请求参数中的某个值 |
$args 或 $query_string |
请求中的完整参数 |
$binary_remote_addr |
二进制客户端IP地址 |
$body_bytes_sent |
发送给 client 的 body 大小没包含 header |
$bytes_sent |
发送给 client 的总大小 |
$connection |
连接序列号 |
$connection_requests |
连接中的请求数 |
$content_length |
请求中的 content_length |
$content_type |
请求中的 content_type |
$cookie_name |
获取 cookie 中的 name 的值 |
$document_root |
当前请求的 root 或 alias 值 |
$document_uri 或 $uri |
当前请求的 URI |
$host |
请求的 Host |
$hostname |
|
$http_name |
获取 http header 中指定的 name 的值 |
$https |
是否是 https |
$is_args |
如果有请求参数, 则返回 ? , 否则为空字符串 |
$limit_rate |
当前限速 |
$msec |
当前时间, 秒, 精度到毫秒 |
$nginx_version |
Nginx 版本 |
$pid |
Worker 的 pid |
$pipe |
请求是否 pipeline. 是的话为 p , 否则为 . |
$proxy_protocol_addr |
从代理协议中获取客户端地址 |
$proxy_protocol_port |
从代理协议中获取客户端端口 |
$proxy_protocol_server_addr |
从代理协议中获取服务器地址 |
$proxy_protocol_server_port |
从代理协议中获取服务器端口 |
$realpath_root |
请求的真实资源路径. 从 root 或 alias 中解析 |
$remote_addr |
Client 地址 |
$remote_port |
client 端口 |
$remote_user |
从 Basic 认证中获取的用户名 |
$request |
完整的请求行 |
$request_body |
请求 body. 只有在传给 proxy_pass, fastcgi_pass, uwsgi_pass, and scgi_pass 指令时, 该参数才有值 |
$request_body_file |
保存请求 body 的临时文件 |
$request_completion |
请求是否完成. OK 表示完成. 否则返回空字符串 |
$request_filename |
当前请求的文件路径 |
$request_id |
当前请求的唯一 ID 标识 |
$request_length |
当前请求的大小. 包含请求行, header, body, |
$request_method |
当前请求的方法类型 |
$request_time |
当前请求的处理时间. 它是从读取 client 的第一个字节算起. |
$request_uri |
完整的 URI, 包含参数 |
$scheme |
协议名. 如 http 或 https |
$sent_http_name |
发送指定的响应头 name |
$sent_trailer_name |
发送指定响应字段 name |
$server_addr |
服务器地址 |
$server_name |
|
$server_port |
|
$server_protocol |
请求协议. 如 HTTP/1.1 |
$status |
响应状态码 |
$tcpinfo_rtt , $tcpinfo_rttvar , $tcpinfo_snd_cwnd , $tcpinfo_rcv_space |
在所有支持 tcp_info 系统上的 socket 选项有效 |
$time_iso8601 |
ISO 8601 时间格式 |
$time_local |
Common Log Format 时间格式 |
反向代理
- Nginx 是在接收完 client 的请求后缓存数据, 然后再向上游服务器发起连接
- Squid 则是一边接收, 一边传到上游服务器
负载均衡
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
注意, backup 参数不能用在
hash
,ip_hash
, andrandom
均衡算法中.
Upstream 的变量. 支持记录到日志中.
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables
变量 | 描述 |
---|---|
$upstream_addr |
处理请求的 upstream 的地址 |
$upstream_bytes_received |
从 upstream server 中接收到的字节数 |
$upstream_bytes_sent |
发送到 upstream server 的字节数 |
$upstream_cache_status |
访问响应缓存状态 |
$upstream_connect_time |
与 upstream server 建立连接消耗的时间. 如果是 SSL, 则包括handshake时间. |
$upstream_cookie_ *name* |
Upstream server 中set-cookie 中指定 name 的 cookie 值 |
$upstream_header_time |
从 upstream server 中获取响应的 header 的耗时 |
$upstream_http_name |
从 upstream server 中获取响应的指定 header |
$upstream_queue_time |
在 upstream queue 中消耗的时间 |
$upstream_response_length |
从 upstream server 中获取响应的长度 |
$upstream_response_time |
从 upstream 获取响应的耗时 |
$upstream_status |
从 upstream server 中获取状态码 |
$upstream_trailer_name |
从 upstream server 响应中获取指定字段 |
Nginx 处理 HTTP 的11 个阶段
NGX_HTTP_POST_READ_PHASE
: 接收到客户发送的完整 HTTP 请求头时执行NGX_HTTP_SERVER_REWRITE_PHASE
: 将 URI 转换为虚拟主机 ( server )NGX_HTTP_FIND_CONFIG_PHASE
: 根据上一阶段重写后的 URI 检索出匹配的 location 块.NGX_HTTP_REWRITE_PHASE
: 相应的 location 块可能再次利用 rewrite 重写 URLNGX_HTTP_POST_REWRITE_PHASE
: 检查 rewrite 次数不可超过 10 次, 以防 rewrite 死循环NGX_HTTP_PREACCESS_PHASE
: 访问控制预处理NGX_HTTP_ACCESS_PHASE
: 访问验证NGX_HTTP_POST_ACCESS_PHASE
: 访问验证结果处理NGX_HTTP_TRY_FILES_PHASE
:try_files
处理NGX_HTTP_CONTENT_PHASE
: 响应生成阶段NGX_HTTP_LOG_PHASE
: 日志记录