八股文
先放一段八股文镇贴。
nginx 的架构
轻量
- 源代码只包含核心模块
- 其他非核心功能都是通过模块实现,可以自由选择
工作流程
- Nginx 在启动后,会有一个 master 进程和多个独立的 woeker 进程。
- 接收来自外界的信号,向各 worker 进程发送信号,每个进程都有可能来处理这个连接。
- master 进程能监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会启动新的 worker 进程。
- worker 进程数,一般会设置成机器 cpu 核数。因为更多的 worker 数,只会导致进程相互竞争 cpu,从而带来不必要的上下文切换。
- 使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响到其他 worker 进程。
IO 多路复用
- 多个文件描述符的 IO 操作都能在一个进程里并发交替顺序完成,复用线程。
CPU 亲和
- 把 CPU 内核和工作进程绑定在一起,让每个 worker 进程固定在一个 CPU 上执行,从而减少 CPU 的切换并提高缓存命中率,提高性能。
sendfile
- sendfile 零拷贝传输模式
安装
这个在网上教程很多,我这边用的阿里云服务器,使用 yum 安装。大家自己安装了。
yum install nginx -y // 安装 nginx
nginx -v // 查看版本
nginx -V // 查看编译时的参数
目录
安装目录
查看 nginx 安装的配置文件和目录
rpm -ql nginx // 查看 nginx 安装的配置文件和目录
日志切割文件
/etc/logrotate.d/nginx
对访问日志进行切割
/var/log/nginx/*.log {
daily
}
主配置文件
| 路径 | 用途 |
|---|---|
| /etc/nginx/nginx.conf | 核心配置文件 |
| /etc/nginx/conf.d/default.conf | 默认http服务器配置文件 |
user nginx; // 启动 nginx 的用户
worker_processes auto; // worker 进程数,一般和 cpu 核数相等
error_log /var/log/nginx/error.log; // 错误日志的路径,日志的格式
pid /run/nginx.pid; // 进程 ID 写入的文件
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024; // 工作进程的最大连接数
}
http {
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 /var/log/nginx/access.log main;
sendfile on; // 打开零拷贝
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65; // 保持连接的超时时间
types_hash_max_size 4096;
include /etc/nginx/mime.types; // 包含 mime 文件
default_type application/octet-stream; // 默认类型是二进制文件
include /etc/nginx/conf.d/*.conf; // 引入 /etc/nginx/conf.d/ 下所有配置
server { // 配置服务的,是最核心的配置文件
listen 80; // 监听端口
listen [::]:80;
server_name _; // 服务名字或者是域名;或者IP
root /usr/share/nginx/html; // 根目录文件
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
// location = 表示完全匹配 没有 = 表示匹配前缀
// 当两个前缀匹配成功时,取最长的
location / {
root /usr/share/nginx/html; // 文件根路径 根目录
index index.html index.htm; // 索引文件 默认文件
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
常用命令
systemctl restart nginx.service // 重启nginx服务
systemctl reload nginx.service // 重新加载
nginx -t // 检查nginx配置
nginx 核心模块
监听nginx客户端的状态
模块名
- --with-http_stub_status_module 监控nginx客户端的状态
代码
server {
location /status {
stub_status on;
}
}
通过 /status 路径访问(http://127.0.0.1/status)
Active connections: 2 当前nginx正在处理的活动连接数
server accepts handled requests
3 3 10
Reading: 0 Writing: 1 Waiting: 1
| 参数 | 含义 |
|---|---|
| Active connections | 当前nginx正在处理的活动连接数 |
| acceptss | 总共处理的连接数 |
| handled | 总共创建的握手数 |
| requests | 总共处理的请求数 |
| Reading | 读取到客户端Header信息 |
| Writing | 正在返回给客户端Header信息 |
| Waiting | 等待 如果开启了keep-alive = active - (raading+writing) |
模块名
- --with-http_random_index_module 在根目录里随机选择一个主页显示
代码
server {
location /status {
random_index on;
}
}
内容替换
- --with-http_sub_module 内容替换
代码
server {
location /status {
sub_filter 'name' 'aaa';
}
}
请求限制
- --with-limit_conn_module 连接频率限制
- --with-limit_req_module 请求频率限制
- limit_conn_zone 共享内存空间
- limit_req_zone 共享内存空间
代码
limit_conn_zone $binary_remote_addr zone=conn_zone: 10m;
limit_req_zone $binary_remote_addr zone=req_zone: 10m rate=1r/s;
server {
location / {
root /usr/share/nginx/html;
index index.html index.htm;
# 并发连接配置
limit_conn conn_zone 1;
limit_conn_status 500;
limit_conn_log_level warn;
limit_rate 50;
# 并发请求配置
limit_req zone=req_zone burst=3; # 漏斗算法缓存的数量
}
}
访问控制
- 基于IP的访问控制 -http_access_module
代码
server {
location / {
deny 192.171.207.100;
allow all;
}
}