应用场景
- 静态资源服务器:通过本地文件系统提供服务
- 反向代理服务器:Nginx 强大的性能,缓存,负载均衡
- API 接口服务:OpenResty
优势
- 高并发,高性能
- 可扩展性好
- 高可靠性
- 热部署
- 开源 BSD 许可证
Nginx 架构
Nginx 采用多进程(单线程)和多路 IO 复用模型
轻量
- 源代码只含核心模块
- 其他非核心功能都是通过模块实现,可以自由选择
组成
- Nginx 二进制可执行文件
- Nginx.conf 配置文件
- access.log 访问日志
- error.log 错误日志
版本
- nginx.org 开源
- nginx.com 商业
- openresty.org 开源
- openresty.com 商业
工作流程
- Nginx 启动后会有一个
master
进程和多个相互独立的worker
进程 - 接收来自外界的信号,向
worker
进程发送信号,每个进程都有可能来处理这个连接 master
进程能监控worker
进程的运行状态,当worker
进程退出后(异常情况),会自动启动新的worker
进程
- worker 进程数,一般会设置为机器的 CPU 核数,因为更多的 Worker 数,只会导致进程相互竞争 CPU,从而带来不必要的上下文切换
- 使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响其他进程
- 请求处理流程
Nginx 进程管理及通信
基础同步工具
- 信号
共享内存(跨 worker 进程通讯)
- Ngx_http_lua_api
- rbtree
- 单链表
高级通信方式
- 锁
Slab 内存管理器(Bestfit)
- 最多两倍内存消耗
- 适合小对象
- 避免碎片化
- 避免重复初始化
Master 进程
- 监控 worker 进程 CHLD
- 管理 worker 进程
接收信号
- TERM,INT
- QUIT
- HUP
- USR2
- WINCH
Worker 进程
接收信号- TERM,INT
- QUIT
- USR1
- WINCH
Nginx 命令行
- reload: HUP
- reopen: USR1
- stop: TERM
- quit: QUIT
Nginx 容器
- 数组
- 链表
- 队列
哈希表
- Bucket size (对齐)
- Max size
红黑树
自平衡二叉查找树- 高度不会超过 2 倍 log(n)
- 增删改查算法复杂度 O(log(n))
- 遍历复杂度 O(n)
- 基数树
网络收发与 Nginx 事件对应关系
- TCP 流与报文
TCP 协议与非阻塞接口
读事件
- Accept 建立连接
- Read 读消息
写事件
- Write 写事件
连接池
构成:- 对上游服务器的连接
- 对下游客户端的连接
Nginx 事件循环
epoll
前提:高并发连接中,每次处理的活跃连接数量占比很小
实现:红黑树、链表
使用:- 创建
- 操作:添加/修改/删除
- 获取句柄
- 关闭
内存池
- 连接内存池
- 请求内存池
IO 多路复用
异步阻塞 IO
- 多个文件描述符的 IO 操作都能在一个线程里并发交替顺序完成,复用线程
CPU 亲和
- 把 CPU 内核和 Nginx 的工作进程绑定在一起,让每个 worker 进程固定在一个 CPU 上执行,从而减少 CPU 的切换并提高缓存命中率,提高性能
sendfile
- sendfile 零拷贝传输模式
Nginx 模块
- 内聚
抽象
- 配置
- 启停回调方法
子模块抽象
- http
- event
- stream
- nginx 模块分类
编译
下载
wget http://nginx.org/download/nginx-1.14.0.tar.gz tar -xzf nginx-1.14.0.tar.gz cd nginx-1.14.0
编译
# 进入解压目录下 ./configure --prefix=/home/cellinlab/nginx # 指定安装目录 make # 编译 编译结果再 /objs 目录
安装
make install
安装
- 关闭防火墙
systemctl disable firewalld.service
- 安装依赖模块
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools 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
- 安装
yum install nginx
- 检查
nginx -v # 查看安装版本
nginx -V # 查看编译参数
目录说明
日志切割文件
/etc/logrotate.d/nginx
对访问日志进行切割/var/log/nginx/*.log { daily }
主配置文件
- 核心配置文件
/etc/nginx/nginx.conf
- 默认 http 服务器配置文件
/etc/nginx/conf.d/default.conf
- 核心配置文件
CGI 配置
- CGI(Common Gateway Interface) 通用网关接口
- Web Server 通过 cgi 协议可以把动态的请求传递给如 php、jsp、python 等应用程序
- FastCGI 是带有拓展功能的 CGI,描述了客户端和 Web 服务器程序之间传输数据的一种标准
- SCGI 协议是一个 CGI 协议的替代品,应用与 HTTP 服务器的接口标准,类似于 FastCGI,当设计更容易实现
- uwsgi 是一个 Web 服务器,实现了 WSGI 协议、uwsgi、http 等协议
路径 用途 /etc/nginx/fastcgi_params fastcgi 配置 /etc/nginx/scgi_params scgi 配置 /etc/nginx/uwsgi_params uwsgi 配置 编码转换映射转换文件
路径 用途 /etc/nginx/koi-utf koi8-r <-> utf-8 /etc/nginx/koi-win koi8-r <-> windows-1251 /etc/nginx/win-utf windows-1251 <-> utf-8 - 扩展名文件
/etc/nginx/mime.types
设置 http 协议的 Content-Type 与 扩展名对应关系 守护进程管理
用于配置系统守护进程管理器管理方式路径 用途 /usr/lib/systemd/system/nginx-debug.service /usr/lib/systemd/system/nginx.service /etc/sysconfig/nginx /etc/sysconfig/nginx-debug - nginx 模块目录
/etc/nginx/modules
最基本的共享库和内核模块 文档
手册和帮助文档路径 用途 /usr/share/doc/nginx-1.14.1 帮助文档 /usr/share/doc/nginx-1.14.0/COPYRIGHT 版权声明 /usr/share/man/man8/nginx.8.gz 手册 - 缓存目录
/var/cache/nginx
- 日志目录
/var/log/nginx
可执行命令
nginx 服务的启动管理的可执行文件路径 用途 /usr/sbin/nginx 可执行命令 /usr/sbin/nginx-debug 调试执行可执行命令
配置文件
/etc/nginx/nginx.conf
主配置文件/etc/nginx/cond.d/*.conf
/etc/nginx/conf.d/default.conf
配置语法
# 使用 # 可以添加注释,使用 $ 可以使用变量
# 配置文件由指令与指令块组成,指令块以 {} 将多条指令组织在一起
http {
# include 允许把多个配置文件组合起来以提升可维护性
include mime.types; # 每条指令以 ; 结尾,指令与参数之间以空格分割
default_type application/octet-stream; # 默认的 Content-Type
sendfile on; # 启用零拷贝模式
keepalive_timeout 65; # 活动连接超时时间 单位是 s
server { # 每个server 对应一个网站
listen 80;
server_name localhost; # 域名
# 有些指令可以支持正则表达式
location / { # 匹配所有路径
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
http 配置的指令块
- http
- server
- location
- upstream
Nginx 命令行
nginx -s reload
- -? -h 帮助
- -c 指定配置文件
- -g 指定配置命令
- -p 指定运行目录
-s 发送信号
- stop 立即通知服务
- quit 优雅停止
- reload 重载配置文件
- reopen 重新开始记录日志文件
- -t -T 测试配置文件是否有语法错误
- -v -V 版本信息 编译参数
日志
日志类型
/var/log/nginx/access.log
访问日志/var/log/nginx/error.log
错误日志
log_format
类型 用法 语法 log_format name [escape=default[json] string] 默认 log_format combined "" Context http 使用 GoAccess 实现 access 日志可视化及实时监控
参考goaccess access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html
用例
搭建静态资源 web 服务器
将静态资源放在 nginx 目录下指定目录中,如 /nginx/blog
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
#default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
gzip_min_length 1;
gzip_min_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
server {
listen 8080;
server_name blog.cellinlab.xyz;
access_log log/blog.access.log main;
location / {
alias blog/;
#autoindex on;
#set $limit_rate 1k;
#index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
SSL
- SSL, Secure Sockets Layers
- TLS, Transport Layer Security
- TLS 安全密码
- 对称加密
- 非对称加密
- PKI 公钥基础设施
CA 证书类型
- 域名验证证书,DV Domain Validated
- 组织验证证书,OV Organization Validated
- 扩展验证证书, EV Extended Validation
- TLS 通信过程
免费 SSL 实现 HTTPS
yum install python2-certbot-nginx
certbot --nginx --nginx-server-root=/usr/local/openresty/nginx/conf/ -d blog.cellinlab.xyz
HTTP 模块
指令冲突
配置块嵌套
main http { upstream {} split_clients {} map {} geo {} server { location { limit_except {} } location { location { } } } server { } }
指令合并
值指令 存储配置项的值
- 可以合并
- 如 root、access_log、gzip
- 继承规则:向上覆盖,子配置覆盖父配置
动作类指令 指定行为
- 不可以合并
- 如 rewrite、 proxy_pass
- 生效阶段 server_rewrite 阶段、rewrite 阶段、content 阶段
listen 指令
- 语法
listen address[:port]
如listen 127.0.0.1:8000
listen port
如listen 800;
listen unix:path
如listen unix:/var/run/nginx.sock;
- 默认
listen *:80|*:8000;
- Context server
接收请求及建立连接
- 接收请求事件模块
- 接收请求 HTTP 模块
HTTP 请求处理
HTTP 请求的 11 个阶段
阶段 | 描述 | 模块 |
---|---|---|
POST_READ | 获取到Header后的第一个阶段 | realip |
SERVER_REWRITE | 配置在server模块中的rewrite阶段 | rewrite |
FIND_CONFIG | 根据配置查找由谁处理请求的阶段 | |
REWRITE | 配置在location模块中的rewrite阶段 | rewrite |
POST_REWRITE | ||
PREACCESS | 向上游服务请求连接前的阶段 | limit_conn、limit_req |
ACCESS | 与上游服务器连接的验证阶段 | auth_basic、access、auth_request |
POST_ACCESS | ||
PRECONTENT | 发送data数据前的阶段 | try_files |
CONTENT | 发送数据阶段 | index、autoindex、concat |
LOG | 记录请求日志、错误日志阶段 | access_log |
11 个阶段的处理顺序
server 模块
server_name 指令
- 指令后可以跟多个域名,第一个是主域名
- *泛域名:仅支持在最前或者最后
server_name *.cellinlab.xyz
正则:在前面加 ~
server_name www.cellinlab.xyz ~^www\d+\.cellinlab\.xyz$;
用正则创建变量
# 匿名变量 server { server_name ~^(www\.)?(.+)$; location / { root /sites/$2; } } # 命名变量 server { server_name ~^(www\.)?(?<domain>.+)$; location / { root /sites/$domain; } }
- .cellinlab.xyz 可以匹配 cellinlab.xyz *.cellinlab.xyz
- _ 匹配所有
- "" 匹配没有传递 Host 头部
server 匹配顺序
- 精准匹配
- *在前的泛域名
- *在后的泛域名
- 按文件中的顺序匹配正则表达式域名
- default server