Nginx 知识点

中文文档

英文文档

官网相关教程和资料

参考书籍: <<Nginx 服务器架构初探>>, <<Nginx-高性能-Web-服务器详解>>, <<Nginx-高性能-Web-服务器实战教程>>, <<高性能 Linux 服务器 构建实战>>

ArchWiki 上相关资料

谷歌找到的文档

知乎查询资料

介绍

nginx (engine x) 是一个高性能的 HTTP 和反向代理服务器, 同时也提供 IMAP 和 SMTP 服务。其特点是占用内存少,并发能力强。

关键特性:

  • 高并发
  • 内存占用低
  • 高扩展性
  • 高可靠性, 快速开启新 worker

工作模式

两种工作模式.

master-worker 模式

有一个 master 进程和至少一个 worker 进程。

master 进程负责处理系统信号,管理 worker 进程, 检查 Nginx 配置 等.

worker 进程负责处理具体的业务逻辑。

常用于生产环境。

worker 的抢占机制

Nginx 异步非阻塞事件处理机制

单进程模式

只有一个进程.

方便使用 gdb 等工具进行调试。

一般用于开发阶段和调试。

Nginx 读作 engine X, 可以做 HTTP 服务器, 反向代理, IMAP/POP3 代理服务器.

模块化

Nginx 可以通过模块来扩展功能. 就像 vim 装插件.

一般分为:

  • 核心模块
  • 标准 HTTP 模块
  • 可选 HTTP 模块
  • 邮件服务模块
  • 第三方模块

添加的模块根据实际情况调整.

核心模块和标准 HTTP 模块在 Nginx 快速编译后就包含在 Nginx 中.

在我装得 docker 容器 (Ubuntu 18.04) 里, 模块位于 /usr/lib/nginx/modules 这个目录.

功能, 使用方向

正向代理和反向代理

正向代理, 代理客户端. 客户端的请求从代理处发给服务器.

反向代理, 代理服务端. 就如同向我们向 www.baidu.com 访问, 只有这一个域名, 实际上后面有很多服务器.

负载均衡

轮循, 一个一个分配请求.

加权轮循, 通过权重来分配请求.

iphash

来自一个 ip 的请求会始终传送到同一个服务器上 (解决会话无法共享导致的问题).

Redis

做缓存服务器以及 Session 共享.

静态资源服务器

安装

安装 nginx-mainline 包或 nginx 包.

nginx-mainline 的模块可以在 AUR 上找到.

可查阅 “我的第一本 Docker 书”.

使用

直接用:

1
$ nginx

来打开.

当 nginx 打开后, 可以用 -s 选项控制, 如:

1
nginx -s signal

这个 signal 有以下几种:

  • stop
  • quit
  • reload, 重新加载配置文件
  • reopen, 重新打开 log files

nginx -s reload 之后, 若配置文件正确, 其会创建一个新的 worker processes 然后向 old worker processes 发送信号, 要求其关闭, 但它不会立即关闭, 其会 stop accepting new connections and continue to service current requests until all such requests are serviced.

nginx master process 的 PID 记录在 /usr/local/nginx/logs//var/run/ 下的 nginx.pid 文件中. 可以使用 kill 命令和 nginx 交互.

和 control 相关的 网站

虚拟主机示例

server 关键字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server { 
listen 81;
server_name localhost;
root /var/www/html/nginx1;
index index.html;
}

server {
listen 82;
server_name localhost;
root /var/www/html/nginx2;
index index.html;
}

server {
listen 83;
server_name localhost;
root /var/www/html/nginx3;
index index.html;
}

轮询示例

upstream 关键字, 不添加 weight:

1
2
3
4
5
6
7
8
9
10
11
upstream www.test.com {
server localhost:81;
server localhost:82;
server localhost:83;
}

server {
location / {
proxy_pass http://www.test.com;
}
}

权重轮询示例

1
2
3
4
5
6
7
8
9
10
11
upstream www.test.com {
server localhost:81 weight=1;
server localhost:82 weight=2;
server localhost:83 weight=3;
}

server {
location / {
proxy_pass http://www.test.com;
}
}

负载均衡备份示例

1
2
3
4
5
6
7
8
9
10
11
upstream www.test.com {
server localhost:81 backup;
server localhost:82 weight=2;
server localhost:83 weight=3;
}

server {
location / {
proxy_pass http://www.test.com;
}
}

负载均衡关闭 server 示例

1
2
3
4
5
6
7
8
9
10
11
upstream www.test.com {
server localhost:81 backup;
server localhost:82 down;
server localhost:83 down;
}

server {
location / {
proxy_pass http://www.test.com;
}
}

配置

配置文件位置

nginx 的配置文件为 nginx.conf, 路径为:

  • /usr/local/nginx/conf
  • /etc/nginx/
  • /usr/local/etc/nginx

整体结构

Nginx 配置文件结构

组成 Nginx 的模块由配置文件中的 directive 控制. directives 被分成 simple directives 和 block directives.

一个 simple directive 由 name 和 parameters, 且用 ; 分隔组成.

一个 block directive 和 simple directive 有相同的结构, 但是用 {} 包裹.

一个 block directive 里面可以有其他的 directive, 叫做 context, 如 events, http, server, location.

如果有的 directives 放在任何 context 外面, 就叫做 main context.

# 表明注释.

Nginx 配置文件主要分成四个部分: main (全局设置), server (主机设置), upstream (负载均衡服务器设置) 和 location (URL 匹配特定位置的设置). 这些是设置的块区域.

main 部分 (也就是在所有的块之外的部分) 设置的命令将影响其他所有设置.

server 部分的命令主要用于指定主机和端口.
长这样:

1
2
3
4
server {
listen xx;
server_name xxx
}

location 部分用于匹配网页位置. 一般放在 server 块里面:

1
2
3
4
5
6
7
8
server {
listen xx;
server_name xxx

location / {

}
}

upstream 命令主要用于负载均衡, 设置一系列的后端服务器, 一般放在 server 块之后, 和 location 中的 proxy_pass 配合使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen xx;
server_name xxx

location / {
proxy_pass [server];
}
}

upstream [server] {
server xxx;
server xxx;
server xxx;
}

server 继承 main, location 继承 server, upstream 既不会继承其他设置, 也不会被继承.

细分每一个 block 的配置和常用选项

main 也就是所有 block 之外

整体一般写这些, 后面有单个讲解:

1
2
3
4
5
6
7
user user [group];
worker_processes 4;
worker_rlimit_nofile 51200;
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;
pid /run/nginx.pid;
daemon on;

设置 worker_processes 的权限.

1
user user [group];

Nginx 服务器中主进程 (master process) 是以 root 权限运行的.

这里设置用户和组是针对工作进程 (worker process).

Nginx 提供两种设置用户和组的方式:

  • 安装时通过编译选项进行设置
  • 修改配置文件

主进程接受客户端的请求, 转交给工作进程处理.

group 忽略不写时, 用和 user 相同的名字代替.

nginx 似乎是属于 www-data 这个用户组的.

设置开启的进程数

1
worker_processes 4;

worker_processes, 其值决定了 nginx 接受多少连接和它会使用多少处理器, 若设置为 auto, 它会自动检测最优值.

设置最多文件描述符打开数目

1
worker_rlimit_nofile 51200;

这个值和 ulimit -n 的输出最好保持一致.

设置全局的 access_logerror_log

1
2
access_log      /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;

后面跟的是路径.

设置 pid 存放位置

1
pid /run/nginx.pid;

设置是否开启守护进程模式

1
daemon on;

daemon off; 表示以非守护进程模式运行. 阻止 nginx 进入后台. 其可以保持 Docker 容器的活跃状态.

events 块

其设置 Nginx 的工作模式以及连接数上限.

长这样:

1
2
3
4
5
events {
use epoll;
worker_connections 51200;
multi_accept off;
}

设置 Nginx 的工作模式

1
use epoll;

对于 Linux 系统, epoll 工作模式是首选.

设置 worker process 进程的最大并发链接数

1
worker_connections 51200;

woker_connection 定义的是 Nginx 每个进程的最大连接数.

设置是串行还是并行

1
multi_accept off;

off 就是串行, 也就是默认值.

http 块

整体观感, 这个部分的设置就有很多选择了, 这一部分就参考别人的讲解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access_log;
error_log /var/log/nginx/error_log;

server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 50m;

gzip on;
gzip_disable "msie6";

include /etc/nginx/conf.d/*.conf;
}

参考1
参考2

一部分解释:

include 指令用来包含另外的配置文件.

default_type 当文件类型未定义时使用这个类型, 默认值为二进制流.

sendfile on 表示开启高效文件传输模式, 默认为 off.

tcp_nopush ontcp_nodelay on 用来防止网络堵塞.

keepalive_timeout + 数字 设置连接超时限制.

server 代码块

这个一般放在 http block 里面, 而且一般不放在 nginx.conf 这个主配置文件中, 而是用 include 指令包含进来.

server 块: 配置虚拟主机的相关参数.
比如:

两个目录 (也可以在其他地方):

  • /etc/nginx/sites-available
  • /etc/nginx/sites-enabled

可以在 sites-available 目录下创建文件, 并写入 server 模块.

可以在 nginx.conf 文件中某个 block 下写入:

1
include site-enabled/*

需要添加某个 server 的时候, 创建一个 symbolic link 就可以了.

server 块的作用就是设置虚拟主机 (用来匹配的域名).

大概:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
server {
listen xx; # 本机的监听端口
server_name xxx; # 虚拟主机名
root xxx; # 资源所处的根目录
index xxx; # 默认打开的界面
autoindex [on/off]; # 以列表形式显示而不是直接打开
autoindex_localtime on; # 列表中显示时间
autoindex_exact_size off; # 列表中显示大小, 以 KB, MB, GB 形式


location / {
return xxx;
}

location / {
proxy_pass xxx;
}

location / {
index xxx;
allow xxx;
deny xxx;
}

error_page 500 502 503 504 /50x.html; # 设置错误页
}

server {
...
...
...
}

server {
...
...
...
}

server {
...
...
...
}

有几个 server 模块, 就可以设置几个虚拟主机.

nginx 会决定哪个 server 来处理哪个 request.

location 部分

location 块 (URL 匹配特定位置的设置): 配置请求路由, 以及各种页面的处理情况.
一般这个形式:

1
2
3
location xxx {
xxx;
}

location 块的前缀:
location 块的前缀

出现任何问题都可以查看 /usr/local/nginx/logs/var/log/nginx 处的日志文件.

不同端口代理不同页面

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 8080;
server_name xxx xxx xxx;

location xxx {
proxy_pass https://localhost:8885/;
}

location xxx {
proxy_pass https://localhost:8886/;
}

location xxx {
proxy_pass https://localhost:8886/;
}
}

显示一个页面

1
2
3
4
5
6
7
8
server {
listen 8080;
server_name xxx xxx xxx;

location xxx {
index xxx;
}
}

网页跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 8080;
server_name xxx xxx xxx;

location xxx {
return https://www.baidu.com/;
}

location xxx {
return https://github.com/;
}

location xxx {
return https://www.google.com/;
}
}

upstream 块

upstream 块 (负载均衡服务器设置): 指令主要用于负载均衡, 设置一系列的后端服务器, upstream 后的名称和后面 proxy_pass 要对应起来.
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 0.0.0.0:80;
server_name _;

root /var/www/html;
index /index.nginx-debian.html;

access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;

location ~ /h {
proxy_pass http://webthreepages;
}
}

upstream webthreepages {
server 172.17.0.3:80 weight=1;
server 172.17.0.3:81 weight=2;
server 172.17.0.3:82 weight=3;
}

正则表达式

Nginx 的正则表达式支持的特殊字符:

  • *
  • +
  • ?
  • ^$
  • .
  • []
  • {}
  • ()
  • |
  • \d, \D, \w, \W
    匹配模式是非贪婪的.

一些理论概念

同步和异步,阻塞和非阻塞

同步和异步

  • 同步, 当一个同步调用发出去后,调用者要一直等待调用的结果通知后,才能进行后续的执行
  • 异步,当一个异步调用发出去后,调用者不需要一直等待调用结果的返回,其想要获取调用结果一般采取两种方式
    1. 主动轮询异步调用结果
    2. 被调用方通过 callback 来通知

阻塞和非阻塞

  • 阻塞,调用在发出后,在消息返回前,当前线/进程会被挂起,直到有消息返回,当前线/进程才会被激活
  • 非阻塞,调用在发出去后,不会阻塞当前线/进程,而会立即返回

nginx 采用异步非阻塞方式工作。

epoll

当连接有 I/O 产生时,epoll 就会告诉进程哪个连接有 I/O 事件,然后进程就会去处理这个事件。其让 nginx 有高并发, 即同时处理多个连接.


Nginx 知识点
http://example.com/2022/08/28/Nginx-知识点/
作者
Jie
发布于
2022年8月28日
许可协议