Nginx学习笔记
1. 基础回顾
Nginx主要命令
./nginx 启动nginx
./nginx -s stop 终⽌nginx(当然也可以找到nginx进程号,然后使⽤kill -9 杀掉nginx进程)
./nginx -s reload (重新加载nginx.conf配置⽂件)
2. 配置文件
Nginx 核心配置文件 conf/nginx.conf 包含三块内容:全局块、events块、http块
# 从配置文件开始到 events 块之间的内容,此处的配置影响 nginx 服务器整体的运行
#user nobody;
# worker进程数量,通常设置为何CPU数量相等
worker_processes 1;
# 全局错误日志及pidwe文件位置
#error_log logs/error.log; #
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
#=================================================================
# events 块主要影响 nginx 服务器与用户的网络连接
events {
# 单个worker_processes 最大并发连接数
worker_connections 1024;
}
#=================================================================
# https 块是配置变更最频繁的部分,有虚拟主机、监听端口、请求转发、反向代理、负载均衡等配置
http {
# 引入 mime 类型定义文件
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;
# 虚拟主机
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;
}
}
}
location 语法,由可选符 + 路径 和配置块组成
location [=|~|~*|^~] /uri/ { … }
主要有以下几种形式的配置,优先级从高到低:
- 精确匹配 location = /hello { … }
- 匹配路径的前缀 location ^~ /hello { … }
- 不区分大小写的正则匹配 location ~* /hello { … }
- 正则匹配 location ~ /hello { … }
- 普通路径匹配 location /hello { … }
3. 反向代理
正向代理:客户端通过代理服务器访问目标服务器,目标服务器并不知道是谁在访问,如VPN
反向代理:客服端访问代理服务器,再由代理服务器选择原始服务器,客户端并不知道在访问谁,如访问www.baidu.com
# 访问 http://localhost:9003,反向代理,请求转发到 http://127.0.0.1:8080
server {
listen 9003;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
4. 负载均衡
示例配置
# 多次访问 http://localhost:9003,请求转发到 http://127.0.0.1:8082、http://127.0.0.1:8082
http {
...
# 负载均衡配置
upstream cluster_name {
server 127.0.0.1:8080;
server 127.0.0.1:8082;
}
server {
listen 9003;
server_name localhost;
location / {
# 使用集群的名称
proxy_pass http://cluster_name;
}
}
}
负载均衡策略
-
轮询
默认策略,每个请求按时间顺序逐一分配到不同的服务器,如果某个服务器下线,能自动剔除
-
权重
upstream lagouServer{ # weight 权重越高那么被分配的请求越多,适用于服务器性能不均衡的场景 server 111.229.248.243:8080 weight=1; server 111.229.248.243:8082 weight=2; }
-
ip_hash
upstream lagouServer{ # 每个请求按照 ip 的 hash 结果分配,客户端的请求会固定分配到同一个目标服务器,可以规避session共享问题 ip_hash; server 111.229.248.243:8080; server 111.229.248.243:8082; }
5. 动静分离
# 静态资源处理,直接去 nginx 服务器目录中加载
location /static/ {
root staticData;
}
6. 底层机制
6.1 进程模型
Nginx 启动后,以 daemon 多进程方式在后台运行
-
Master进程
接收外界信号向各 Worker 进行发送信号,如 ./nginx -s reload
监控 Worker 进程的运行状态,当 Worker 进程异常退出后 Master 进程会自动重新启动新的 Worker
-
Worker进程
处理网络请求,各 Worker 进程之间平等、相互独立,共同竞争客户端的请求
客户端与 nginx 一次通信占用两个连接,nginx 与 目前服务器通信又占用两个连接,总共是4个连接
因此,计算 nginx 最大并发数 = worker_processes * worker_connections / 4
6.2 热加载机制
以 ./nginx -s reload 为例
- Master 进程对配置文件进行语法检查
- 尝试配置(如修改了监听端口,那就尝试分配新的监听端口)
- 尝试成功则使用新的配置,新建 Worker 进程
- 新建成功,给旧的 Worker 进程发送关闭消息
- 旧的 Worker 进程收到信号会继续服务,直到把当前进程接收到的请求处理完成后才关闭
因此,reload 之后 Worker 进程的 pid 是发生了变化的
6.3 Worker 进程处理请求
-
Master 进程创建之后,会建立好需要监听的 socket,然后从 Master 进程 fork 出多个 Worker 进程
所以,所有 Worker 进程的监听描述符 listenfd 在新连接到来时都变得可读
-
Nginx 使用互斥锁来保证只有一个 Worker 进程能够处理请求
拿到互斥锁的 Worker 进程注册 listenfd 读事件,在读事件里调用 accept 接收该链接,然后解析、处理、返回
6.4 Nginx 多进程的好处
- 每个 Worker 进程都是独立的,不需要加锁,节省开销
- 每个 Worker 进程都是独立的,互不影响,一个异常结束,其他的还能服务
- 多进程模型为 reload 热加载机制提供了支撑