Nginx学习笔记
本文最后更新于:2023年6月29日 晚上
Nginx 学习笔记
最近一阵子经常使用到 Nginx
,对其中的一些配置和原理有了充分的认识,并且踩了许多坑,所以才有这篇文章用来记录。
一、基本使用
1. 安装
Windows 安装
进入 nginx 官方网站的下载页进行下载,选择最新版本下载即可,解压之后双击 nginx.exe
即可启动 nginx
。
Linux 安装 (以 Ubuntu 为例)
使用 apt 安装:
1 |
|
源码编译安装:
手动编译安装 nginx
需要依赖某些类库,所以先安装需要的依赖类库。
1 |
|
解压下载好的 nginx
文件夹,然后进入解压后的目录,执行如下命令。
1 |
|
执行安装操作
1 |
|
2. 常用命令
下面是一些常用的 nginx 命令:
1 |
|
3. 升级与回滚
3.1. 升级
这里的升级只涉及到服务器环境中 (Linux) 升级的操作。
普通升级
如果只是普通的升级,那么可以在停止升级版本之前 nginx 的前提下,更新会方便很多。
停止原来的的 nginx:
1 |
|
编译新的 nginx ,编译之前,要查看旧的 nginx 是否有额外的编译参数并且备份旧的 nginx 执行文件,如果有则也需要一并复制过来。编译的时候尽量使用 make 而不是 make install ,make install 会执行安装命令,保险起见,使用 make 即可。
1 |
|
不停机升级
不停机的升级则稍微麻烦点,需要让 nginx 在不停止的情况下从旧版本过渡到新版本,但是好在 nginx 自身实现了平滑升级的操作。
下面是 nginx 支持 kill 的信号
nginx 主进程支持的信号:
- TERM, INT 作用和nginx -s stop一致;
- QUIT 作用和nginx -s quit一致;
- HUP 作用和nginx -s reload一致
- USR1 作用和nginx -s reopen一致;
- USR2 平滑升级nginx
- WINCH 平滑关闭工作进程;
nginx 工作进程支持的信号:
- TERM, INT 快速停止
- QUIT 优雅停止
- USR1 重新开启新的日志文件
- WINCH 异常终止调试(需要启用debug_points选项)
下面是一个 nginx 升级的步骤:
下载新版本 nginx 并解压,然后执行配置命令和编译命令。
1 |
|
备份旧的 nginx 和配置文件,这里可以直接使用 mv 命令,不影响目前 nginx 的运行。
1 |
|
复制新版本编译的 nginx 到之前的安装路径中;新版本编译后的 nginx 在解压后的 nginx 的 obj 文件夹下。
1 |
|
其实这里可以仔细看看新版本文件夹下的 Makefile 文件,会发现自带一个 upgrade 命令。
1 |
|
回到新版本的解压目录下,执行更新操作,即可完成 nginx 的不停机升级操作。
1 |
|
3.2. 回滚
什么时候会需要进行 nginx 的回滚,当新版本的 nginx 不稳定,可能需要;这里的升级只涉及到服务器环境中 (Linux) 升级的操作;
普通回滚
如果是进行普通的回滚,那么步骤很简单,下面是步骤。
如果是旧版本 nginx 还在,那么直接停掉新版本的 nginx ,启动旧版本的 nginx 即可。
1 |
|
不停机回滚
不停机的回滚如同不停机升级一样,需要使用到 nginx 的信号机制,这里需要提到前面nginx 的 make upgrade 操作;我们更新一般都是在服务器上进行更新于回滚,那么就可以不使用 make upgrade 命令,为什么呢,先看 make upgrade 命令做了什么。
1 |
|
前面的指令都是正常的,但是最后一步,由于 USR2
信号会启动新的进程,但是旧版本的主进程是还在的,如果最后使用 -QUIT
信号,那么将会把旧版本的主进程彻底停掉,这个时候如果想要进行版本回退,那么则无法进行平滑回退,因为旧版本的 nginx 进程已经被退出了,所以我们选择在进行更新时不退出旧版本的进程,方便新版本使用时出现问题及时回滚。
下面是回滚的步骤,假设在升级的过程中:
1 |
|
二、配置文件
1. 配置文件结构
Nginx 配置文件结构是由多个块(Block)组成的,每个块包含一组指令(Directive),指令用来配置 Nginx 的行为。Nginx 配置文件结构如下:
全局块(Global Block):全局块是配置文件的第一部分,它包含全局指令,对整个 Nginx 服务器都生效。全局块中可以设置一些全局参数,如 worker_processes、pid 等。
Events 块:Events 块用来配置 Nginx 如何处理连接、事件、工作进程等底层参数。Events 块以 events { … } 开始,以 } 结束。在 Events 块中可以设置一些事件相关的参数,如 worker_connections 等。
Http 块:Http 块用来配置 HTTP 服务相关的指令,包括 HTTP 服务器、代理、缓存、负载均衡、安全等。Http 块以 http { … } 开始,以 } 结束。在 Http 块中可以设置一些 HTTP 相关的参数,如 server、upstream、location 等。
Server 块:Server 块用来配置一个虚拟主机,指定监听端口、域名、访问日志、错误日志、默认网站等。一个 Http 块可以包含多个 Server 块。Server 块以 server { … } 开始,以 } 结束。在 Server 块中可以设置一些虚拟主机相关的参数,如 listen、server_name、access_log、error_log 等。
Location 块:Location 块用来配置虚拟主机下的具体 URL 路径,指定访问该路径时的处理方式,如反向代理、缓存、重定向等。一个 Server 块可以包含多个 Location 块。Location 块以 location { … } 开始,以 } 结束。在 Location 块中可以设置一些路径相关的参数,如 proxy_pass、root、try_files 等。
注:有些配置属性可以在多个作用域中配置
2. 全局块
下面介绍一下全局块常用的属性:
user
:指定 worker 的运行用户,默认是对应的用户名和用户组,可以重写此配置更改 nginx 执行的用户和用户组,举例:user root root;
在使用一些软件源安装时,此配置指定的用户和用户组是 nginx
。
work_processes
:指定 nginx 工作进程的个数,默认是1,通常设置为 cpu 的核心数一致即可。
pid
:nginx 进程 ID 文件的存放路径,如果是自己手动编译并且未指定安装位置的,默认位置是 /usr/local/nginx/logs/nginx.pid
,可以重写此配置更改存放路径。
error_log
:记录服务器请求处理中的错误日志,此配置可以在 http/server/location
等作用域中配置。该配置的语法是:error_log file_path log_level
,日志级别可以是 debug, info, notice, warn, error, crit, alert, emerg
,只有高于定义级别的错误日志才会被写入。
access_log
:记录客户端的请求日志,此配置可以在 http/server/location
等作用域中配置。配置语法是:access_log filepath
。
3. Event 块
Event 块中的属性都写在 Event 块内,下面是一些常用的配置:
use
:指定要使用的连接事件模型,nginx 默认根据系统使用最优的事件模型。当然也可以重写此配置指定事件模型。
work_connections
:工作进程的最大连接数,默认是每台 nginx 的 work_processes * work_connections
。
multi_accept
:是否允许每个工作进程接受多个网络连接,默认关闭 (off
),可重写此配置打开 (multi_accept on
) 。
4. Http 块
Http 块中的属性都写在 Http 块内,下面是一些常用的配置:
include
:将另一个文件引入到当前配置中,nginx 默认引入了 mime.types
,此文件设置了文件头对应的文件格式,如果没有则可以在 mime.types
中新增,除此之外,include
指令要注意的是只能引入符合 http
作用域的配置文件包含的配置属性,否则会报错。
default_type
:用来配置Nginx响应前端请求默认的MIME类型。
upstream
:用于指定一组服务器,以便用于负载均衡,并且还可以设置不同的负载均衡策略。upstream
指定名字后,server
块中的 proxy_pass
使用 upstream
的别名即可。
1 |
|
上面没配置负载均衡策略,则会使用默认的轮询策略进行负载均衡处理。下面是其他的负载均衡策略:
- 轮询(Round Robin):默认的负载均衡策略。Nginx 按照定义的后端服务器列表顺序依次分发请求,每个请求按顺序发送到下一个服务器。
- IP 哈希(IP Hash):根据客户端的 IP 地址对后端服务器进行哈希计算,将相同 IP 的请求发送到同一台服务器。这样可以确保同一客户端的请求都发送到同一个服务器,适用于需要保持会话一致性的场景。除了 IP Hash 之外,还有使用 URL Hash 的方式。
- 最少连接(Least Connections):将请求发送到当前连接数最少的服务器。这样可以确保将请求发送到负载较轻的服务器,以实现负载均衡。
- 加权轮询(Weighted Round Robin):为每个后端服务器分配一个权重值,根据权重值决定分发请求的比例。权重值越高的服务器将获得更多的请求。
- 加权最少连接(Weighted Least Connections):结合了加权和最少连接策略。根据服务器的权重值和当前连接数,动态计算每个服务器的有效权重,然后选择有效权重最高的服务器来处理请求。
5. Server 块
Server 块中的属性都写在 Server 块内,下面是一些常用的配置:
listen 监听指定的 IP 地址 + 端口
listen 8080 监听本机的8080
listen 127.0.0.1 监听本机的所有端口
listen *:8080 | *:80 监听所有IP的8080和80端口
server_name 指定客户端访问的域名
server_name 支持定义多个,如果匹配到第一个,那么则不会匹配后面的,否则进行逐个匹配。同时 server_name
还支持正则匹配;下面是例子。
1 |
|
error_page 针对特定的错误码,进行错误页面配置
下面是一些配置实例:
1 |
|
6. Location 块
location 块负责指定 用户访问的路径基于怎么样的匹配规则进行转发,下面是 location 的匹配规则与匹配顺序。越前优先级越高,优先匹配。
- 精确匹配:使用 = 前缀的 location 块会首先被匹配。例如:
1 |
|
如果请求的路径正好是 /path,那么将会使用配置 A 处理该请求。
- 前缀匹配:使用 / 作为前缀的 location 块会按照定义的顺序进行匹配。例如:
1 |
|
如果请求的路径是 /path1/foo,那么将会使用配置 B 处理该请求。如果请求的路径是 /path2/bar,那么将会使用配置 C 处理该请求。
- 正则表达式匹配:使用 ~ 或 ~* 前缀的 location 块会按照定义的顺序进行匹配。例如:
1 |
|
如果请求的路径是 /path/file.html,那么将会使用配置 D 处理该请求。如果请求的路径是 /path/file.txt,那么将会使用配置 E 处理该请求。
- 带修饰符的正则表达式匹配:带有 ~ 或 ~* 前缀和 ^ 或 ~^ 修饰符的 location 块会按照定义的顺序进行匹配。例如:
1 |
|
如果请求的路径是 /path/foo,那么将会使用配置 F 处理该请求。如果请求的路径是 /path/file.html,那么将会使用配置 G 处理该请求。
- 优先级匹配:如果存在多个匹配规则相同的 location 块,Nginx 将使用最先定义的 location 块。例如:
1 |
|
在上述示例中,无论请求的路径是什么,都将使用配置 H 处理该请求,因为配置 H 在配置 I 之前定义。
- location /:如果没有匹配到其他的 location 块,Nginx 将使用默认的 location / 块。例如:
1 |
|
这将匹配所有未被其他 location 块匹配到的请求。