Nginx 入门
介绍
Nginx 有什么用?
HTTP服务器 Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。
FTP服务器 FTP服务器,通常会提供一个上传的功能,其他应用如果需要静态资源就从该静态服务器中获取。
反向代理 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
负载均衡 负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
优点有什么?
高并发支持 单机能够支持10W+的并发连接(取决于内存大小,极限能够到百万),那么在实际生产中也是非常能接近这个数字的,这主要得益于nginx在linux环境下使用了epoll和多路复用模型。
内存消耗低 在同类型web服务中,nginx比apache占用的内存资源更少,在一般情况下10K非活跃的HTTP Keep-Alive连接在nginx中仅消耗2.5M内存。
高扩展性 低耦合的模块设计,并且有丰富的第三方模块支持。
高可靠性 经过十几年的各种复杂场景和各大公司的生产环境验证,并且nginx的架构是由master进程和worker进程组成的,如果worker进程出现问题,那么master进程可以快速开启一个新的worker进程提供服务。
安装与启动
在 Ubuntu 系统中,使用下面的命令安装 Nginx:
sudo apt update
sudo apt install nginx -y
安装成功后,可以使用 systemctl status nginx
验证 Nginx 的启动状态。
可以看到,Nginx 有一个 master 进程和若干个 worker 进程,其中 worker 进程是由操作系统核心数决定的,也可以在配置文件中更改。
若想让 Nginx 开机自启动,可以使用 systemctl enable nginx
命令开启。
Nginx 的配置文件位于 /etc/nginx
文件夹下,其中的主配置文件就是 nginx.conf
文件。
接下来我们创建一个简单的配置文件,反向代理 81 端口。
$ cd /etc/nginx/conf.d
$ code myconf.conf
server {
listen 81;
location / {
root /home/qi1;
index index.html;
}
}
如果想要验证 nginx 配置文件是否正确,可以使用 nginx -t
命令。
当配置文件修改以后,不需要重新启动 Nginx,使用 nginx -s reload
命令即可重载配置。
Nginx 配置
以 Ubuntu 系统为例,Nginx 的配置文件位于 /etc/nginx/nginx.conf
中,此文件中的 include
语法还会导入其他配置文件。
Nginx 配置的语法与其他面向对象的编程语言语法类似,也有顶层作用域和子作用域。
# 全局设置
http {
# 服务器
upstream { # 负载均衡设置
}
server {
# 主机设置
location {
# URL 匹配规则
}
}
}
全局配置块
全局配置块位于配置文件的最顶部,通常只包含在 nginx.conf
文件中,用于规定 Nginx 运行的一些参数,比如进程数量、运行用户等。
配置 | 作用 |
---|---|
work_processes | 指定启动的工作进程数量 |
error_log | 定义错误日志文件的位置和日志级别 |
pid | 指定存储 Nginx 进程 ID 的文件路径 |
worker_connections | 指定每个工作进程能同时处理的最大连接数 |
示例:
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
事件配置块
事件配置块通常紧随全局配置块之后。该配置块控制 Nginx 如何处理网络连接、事件驱动机制、连接的最大数量等。
配置 | 作用 |
---|---|
worker_connections | 指定每个工作进程可以同时打开的最大连接数 |
use | 指定使用的事件驱动模型(如 epoll 、kqueue 等)。 |
events {
worker_connections 1024;
use epoll;
}
HTTP 配置块
HTTP 配置块是 Nginx 中最常见的配置块之一,它用于配置与 HTTP 服务相关的所有内容。HTTP 配置块包含服务器的 HTTP 级别的配置,如请求处理、反向代理、负载均衡、缓存、SSL 等。
配置 | 作用 |
---|---|
server | 定义虚拟主机(即独立的 Web 服务器实例) |
gzip | 配置 HTTP 响应压缩 |
include | 引入其他配置文件 |
log_format | 定义日志格式 |
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 /var/log/nginx/access.log main;
}
服务器配置块(Server Block)
在 HTTP 配置块内,server
配置块定义了一个虚拟主机的配置。每个 server
配置块通常对应一个域名或 IP 地址,用来处理指定域名或 IP 地址的请求。
配置 | 作用 |
---|---|
server_name | 定义服务器的域名或 IP 地址 |
listen | 指定服务器监听的端口 |
location | 定义特定 URI 的处理规则 |
root | 定义该虚拟主机的根目录 |
index | 定义默认的索引文件 |
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
index index.html;
}
}
位置配置块(Location Block)
位置配置块是 server
配置块的一个子集,用于匹配请求的 URI 并指定该 URI 的具体处理方式。location
配置块通常用于指定静态文件位置、重定向规则、代理设置等。
配置 | 作用 |
---|---|
root | 指定该 location 的根目录 |
proxy_pass | 定义请求转发到的后台服务器 |
rewrite | URL 重写规则 |
fastcgi_pass | 定义 FastCGI 请求的处理 |
location /images/ {
root /var/www/static;
}
location /api/ {
proxy_pass http://backend-server;
}
位置匹配规则
location
配置块可以使用不同的匹配方式来选择处理请求。匹配规则的顺序如下:
- 精确匹配(
= /path
) - 前缀匹配(
/path
) - 正则表达式匹配(
~
或~*
,~
是大小写敏感,~*
是大小写不敏感)
location = /about {
# 精确匹配 /about 路径
}
location /images/ {
# 匹配以 /images/ 开头的路径
}
location ~* \.jpg$ {
# 匹配 .jpg 文件,忽略大小写
}
其他配置块(如 Mail、Stream)
除了 http
配置块,Nginx 还可以配置其他服务,如邮件代理服务(mail
)和 TCP/UDP 流量代理服务(stream
)。这些配置块在 Nginx 支持的特定功能中使用,通常涉及到负载均衡和代理设置。
常用配置示例
1. 反向代理配置
这是 Nginx 用作反向代理服务器的常见配置,通常用于将客户端请求转发到后端应用服务器(如 Node.js、Python、Java 等)。
# 定义一个 HTTP 服务块
http {
# 启用反向代理功能,将所有请求转发给后端应用服务器
server {
listen 80; # 监听 HTTP 请求的 80 端口
server_name example.com; # 配置服务器域名
# 配置访问日志格式和路径
access_log /var/log/nginx/access.log;
# 定义反向代理规则
location / {
proxy_pass http://127.0.0.1:3000; # 将所有请求转发到本地 3000 端口的应用服务器
proxy_set_header Host $host; # 保留原始的主机头信息
proxy_set_header X-Real-IP $remote_addr; # 将客户端的真实 IP 传递给后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 转发客户端的真实 IP
proxy_set_header X-Forwarded-Proto $scheme; # 保持请求的协议类型(HTTP/HTTPS)
}
}
}
适用情况:
- 反向代理:将客户端请求转发到后端服务器。
- 负载均衡:Nginx 作为反向代理服务器时,可以实现负载均衡,将请求分发给多台后端服务器。
- 客户端与后端隔离:通过反向代理,隐藏后端服务器的细节。
2. 负载均衡配置
使用 Nginx 实现简单的负载均衡,将流量分配给多台后端应用服务器。
# 定义 HTTP 服务块
http {
upstream backend_servers { # 配置上游服务器组
server 192.168.1.100:8080; # 第一个后端服务器
server 192.168.1.101:8080; # 第二个后端服务器
server 192.168.1.102:8080; # 第三个后端服务器
}
# 配置负载均衡的 HTTP 服务
server {
listen 80; # 监听 HTTP 请求的 80 端口
server_name example.com; # 配置服务器域名
location / {
proxy_pass http://backend_servers; # 转发请求到 upstream 定义的服务器组
proxy_set_header Host $host; # 保留原始的主机头信息
proxy_set_header X-Real-IP $remote_addr; # 转发客户端的真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递原始的 X-Forwarded-For 头部
proxy_set_header X-Forwarded-Proto $scheme; # 保留请求的协议类型
}
}
}
适用情况:
- 负载均衡:将流量均衡地分发到多台后端应用服务器,提升性能和可用性。
- 高可用性:通过多个后端服务器和负载均衡机制,即使某一台服务器宕机,Nginx 也能自动将流量切换到其他服务器。
3. SSL 配置(HTTPS)
为网站启用 SSL 以加密客户端和服务器之间的通信,确保数据传输的安全性。
server {
listen 443 ssl; # 启用 HTTPS,监听 443 端口
server_name example.com; # 配置服务器域名
# SSL 配置
ssl_certificate /etc/nginx/ssl/example.com.crt; # 证书文件路径
ssl_certificate_key /etc/nginx/ssl/example.com.key; # 私钥文件路径
ssl_protocols TLSv1.2 TLSv1.3; # 启用 TLS 协议版本
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384'; # 配置支持的加密套件
# 配置 HTTPS 访问的首页和静态文件
location / {
root /var/www/html; # 配置根目录
index index.html; # 默认首页
}
# 强制 HTTP 请求重定向到 HTTPS
error_page 497 https://$host$request_uri; # 如果客户端访问的是 HTTP 协议,则重定向到 HTTPS
}
适用情况:
- HTTPS 加密:确保所有通信通过加密的 HTTPS 协议传输,增强数据安全性。
- 强制 HTTPS:强制所有 HTTP 请求都被重定向到 HTTPS,确保网站始终通过加密连接访问。
4. 缓存配置
使用 Nginx 进行静态文件的缓存,可以大大提高性能和响应速度。
server {
listen 80; # 监听 HTTP 请求
server_name example.com; # 配置服务器域名
location /images/ {
root /var/www/html; # 静态文件的根目录
expires 30d; # 设置文件缓存时间为 30 天
add_header Cache-Control "public, max-age=2592000"; # 强制浏览器缓存静态资源
}
location /css/ {
root /var/www/html; # 静态文件的根目录
expires 7d; # 设置文件缓存时间为 7 天
add_header Cache-Control "public, max-age=604800"; # 强制浏览器缓存静态资源
}
}
适用情况:
- 静态资源缓存:为图片、CSS、JavaScript 等静态资源配置缓存,减轻服务器负担并提升加载速度。
- 提高性能:通过缓存机制减少静态文件的重复加载,提升用户体验。
5. URL 重写(Redirects)
将旧的网址重定向到新的网址,常用于网站迁移、SEO 或 URL 优化。
server {
listen 80; # 监听 HTTP 请求
server_name oldsite.com; # 配置旧域名
# 配置 301 永久重定向
location / {
rewrite ^/(.*)$ https://newsite.com/$1 permanent; # 将所有请求重定向到新网站,保持路径不变
}
}
适用情况:
- 网站迁移:将旧网站的请求重定向到新网站,确保用户访问旧域名时自动跳转。
- SEO 优化:使用 301 重定向将过时的 URL 指向新的优化 URL,确保搜索引擎能够更新索引。
6. 限流配置
为防止流量过大导致服务器崩溃,可以使用 Nginx 的限流功能,控制每秒的请求数量。
http {
# 配置限流
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s; # 每个 IP 每秒最多允许 1 次请求
server {
listen 80;
server_name example.com;
location / {
limit_req zone=req_limit_per_ip burst=5 nodelay; # 允许突发请求数为 5,但超过 1 次请求/秒的会被拒绝
root /var/www/html;
index index.html;
}
}
}
适用情况:
- 防止恶意攻击:防止 DDoS 攻击或暴力破解等恶意请求。
- 控制流量:确保服务器不会因为过多的并发请求而崩溃,保障正常服务。
7. 访问控制配置
限制某些 IP 地址或者用户访问特定的资源或路径。
server {
listen 80;
server_name example.com;
# 限制某些 IP 地址访问
location /admin {
allow 192.168.1.100; # 允许指定 IP 地址访问
deny all; # 拒绝其他所有 IP 地址访问
root /var/www/html;
}
}
适用情况:
- 后台管理保护:限制管理员后台的访问,只允许特定 IP 地址访问,提高安全性。
- 防止暴力破解:控制对某些敏感页面的访问,减少恶意访问的风险。
Nginx 变量
在上方的实例中,以及下方的防盗链示例中,使用到了单词前面加 $
符号的语法,这实际上是 Nginx 提供的变量语法。
Nginx 提供了多种全局变量,可以在配置文件中使用。这些全局变量通常用于获取请求的相关信息,进行条件判断、访问控制等。
- 请求相关变量
$arg_<name>
:获取请求 URL 中的查询参数值。例如,$arg_id
获取 URL 中?id=xxx
的值。$body_bytes_sent
:响应正文的字节数,不包括响应头。$remote_addr
:客户端的 IP 地址。$remote_port
:客户端连接的端口号。$remote_user
:HTTP 请求头中的Authorization
用户名。$request_method
:HTTP 请求的方法(如GET
,POST
等)。$request_uri
:原始请求的 URI(包括查询参数)。$query_string
:请求 URL 中的查询字符串部分(不包括?
)。$uri
:去掉查询参数后的 URI 部分。$document_uri
:请求的 URI,与$uri
相同。$scheme
:请求的协议(如http
或https
)。$host
:请求中的Host
头部。$http_<header>
:请求头中的字段,例如$http_user_agent
用于获取User-Agent
头部的值,$http_referer
用于获取Referer
头部的值。
2. 响应相关变量
$status
:响应的 HTTP 状态码。$sent_http_<header>
:响应头中的字段。例如,$sent_http_content_type
获取响应的Content-Type
。$response_time
:生成响应的时间(秒)。$upstream_response_time
:上游服务器响应的时间(秒)。$upstream_cache_status
:上游缓存状态(如HIT
或MISS
)。$body_bytes_sent
:响应主体的字节数(不包括头部)。
3. 服务器相关变量
$server_addr
:服务器的 IP 地址。$server_name
:当前请求的服务器名称。$server_port
:服务器监听的端口号。
4. 位置相关变量
$document_root
:当前请求的根目录路径。$realpath_root
:实际文件系统的根路径(如果不同)。$root
:当前请求配置的根目录路径。
5. 连接相关变量
$connection
:当前连接的唯一标识符。$connection_requests
:当前连接的请求次数。$ssl_cipher
:用于加密的 SSL/TLS 密码套件。$ssl_protocol
:SSL/TLS 协议版本。
6. Nginx 内部处理相关变量
$nginx_version
:Nginx 的版本号。$pid
:Nginx 的进程 ID。$hostname
:服务器的主机名。
7. 文件相关变量
$document_root
:指向当前请求的文件系统根目录路径。$filename
:当前请求对应的文件的路径。
8. 日志相关变量
$log_file
:Nginx 配置中定义的日志文件路径。$log_format
:日志格式。
9. 时间和日期变量
$time_local
:本地时间,格式为DD/Mon/YYYY:HH:MM:SS +0000
。$msec
:当前时间的秒级别时间戳(带小数部分)。$epoch_time
:当前时间的 Unix 时间戳(秒)。
10. 请求体和代理相关变量
$request_time
:处理请求的时间。$upstream_addr
:上游服务器的地址。$upstream_status
:上游服务器的响应状态。$proxy_protocol_addr
:通过PROXY
协议传递的远程地址。
11. 代理和负载均衡相关变量
$upstream_addr
:上游服务器的 IP 地址和端口。$upstream_status
:上游服务器返回的状态码。$upstream_response_time
:上游服务器的响应时间。
12. 自定义变量
Nginx 允许用户定义和使用自定义变量。自定义变量通常是在配置文件中使用 set
指令来设置的。例如:
set $my_var "value";
然后可以在其他配置中使用 $my_var
变量。
防盗链配置
盗链:盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其他有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其他服务提供商的服务内容,骗取最终用户的浏览和点击率。受益者不提供资源或提供很少的资源,而真正的服务提供商却得不到任何的收益。
在访问 https://www.baidu.com
时,百度内的图片所在域名却不是 baidu.com
,而是 bdstatic.com
域名。这个域名内的资源只允许 baidu.com
有关域名访问,而不允许其他域名访问,靠的是请求时传递过去的 referer
参数值判断。
在 Nginx 中,最常使用的是通过 Referer 参数判断。在上面的例子中,如果 referer 字段的值为 https://www.baidu.com
,Nginx 就可以返回正常的资源,否则返回错误的资源,即提示用户你无权访问。
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html/80;
index index.html;
}
}
server {
listen 81;
server_name localhost;
root /usr/share/nginx/html/81;
# 如果请求的是 error.png,直接返回该文件,不触发重定向
location = /error.png {
try_files $uri =404;
}
location ~*\.(png)$ {
valid_referers none blocked taobao.com;
if ($invalid_referer) {
# 如果请求的是 error.png,就不再进行重定向,直接返回
rewrite ^ /error.png break;
}
}
}
然后编辑 hosts 文件(Ubuntu 的 hosts 文件在 /etc/hosts 中),添加一条 127.0.0.1 taobao.com
,它的意思是将域名 taobao.com
解析至 127.0.0.1
中。
在浏览器中依次输入 localhost
,会返回错误的图片,而访问 taobao.com
,返回的是正确的图片。
压缩
Gzip 是一种常用的文件压缩格式,它通过压缩文本文件来减少数据的体积,从而加快数据的传输速度。在 Web 开发中,Gzip 通常用于压缩 HTTP 请求和响应体,特别是 HTML、CSS、JavaScript 等文本资源。Gzip 可以将网页文件(如 HTML、CSS、JavaScript 等)压缩至原文件的 30% 至 80% 左右。这样,浏览器加载这些文件时就会减少数据传输量,提升加载速度。
Gzip 压缩
gzip 的作用域有三块,分别是 http、server、location。
我们打开 nginx.conf 文件。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
可以看到 gzip 是被禁用的,我们启用。
同时我们还需要配置一下 gzip 压缩的类型,因为 nginx 默认只会给 application/x-script 类型压缩。
我们新增一行:
gzip_types application/javascript;
我将网页默认文档设为 index.html,同时在此 html 文件内引入一个约 40KB 的 js 文件。
这是开启了 gzip 压缩的传输大小。
这是没有开启 gzip 压缩的传输大小。
Gzip 的功能配置有很多。
server {
gzip on;
gzip_types application/javascript application/json;
gzip_static on;
gzip_vary on;
gzip_comp_level 5;
gzip_buffers 16 8k;
gzip_min_length 1k;
gzip_http_version 1.1;
location / {
root /opt/xxx/;
}
}
参数 | 参考参数 | 作用 |
---|---|---|
gzip | on | 是否开启 gzip 压缩 |
gzip_min_length | 1k | 最小压缩单位,小于 1k 压缩意义就不大了 |
gzip_comp_level | 6 | 压缩级别,1-9可选,数字越大压缩效果越好,同时对 CPU 小号越大,高并发时不可调节过高 |
gzip_types | js、css等 | 压缩类型,取值自 application/type,文本文件压缩效果最好 |
gzip_vary | on | 用于在响应头添加 vary: accept-encoding 让代理服务器根据请求头判断是否开启了 Gzip 压缩 |
gzip_http_version | 1.1 | 启用 gzip 压缩的最低 http 协议版本 |
gzip_buffers | 2 4k | 设置压缩需要的缓冲区大小,以 4k 为大小,若文件为7k则申请2*4k的缓冲区 |
gzip_static | on | 静态压缩,也就是提前已经准备好了压缩文件在同目录下会有一个 .gz 文档压缩包,避免了动态压缩,可以提升性能 |
gzip_disable | MSIE [1-6]. | 设置禁用浏览器进行 gzip 压缩 |
Brotli 压缩
Brotli 是一种通用的无损压缩算法。它结合使用 LZ77 算法的一个现代变体(Lempel-Ziv 编码)、霍夫曼编码和二阶上下文建模来压缩数据,提供了与当前最佳通用压缩方法相媲美的压缩比。
Brotli 提供比 gzip 更好的压缩率,压缩速率也与 deflate 相当。但 brotli 压缩速度比 gzip 慢,因此 gzip 可能更适合于压缩不可缓存的内容。
Brotli 与大多数现代浏览器兼容,但同时仍需考虑回落机制。
Brotli 算法只支持 https 协议。
反向代理
反向代理(Reverse Proxy)是指代理服务器接收客户端的请求后,不是直接将请求转发到目标服务器,而是将请求转发到后端的一个或多个服务器上处理,并将响应结果返回给客户端。在 Nginx 中,反向代理通常用于分发流量到不同的后端应用服务器、负载均衡、缓存静态文件等场景。
Nginx 作为反向代理服务器的优势在于它能够高效地处理大量并发请求、负载均衡、SSL/TLS 加密、缓存、以及实现复杂的访问控制策略。
示例:
我的 nginx 安装在 docker 中。
获取宿主机 ip。
ip addr show docker0
得到宿主机的 ip 为 172.17.0.1
。
修改 nginx.conf 的 server 语句块:
server {
listen 80;
server_name taobao.com;
location / {
proxy_pass http://172.17.0.1:9000;
}
}
它代表将 taobao.com 反代到 http://172.17.0.1:9000
中。
hosts 文件:
127.0.0.1 taobao.com
配置 SSL 证书
HTTPS (HyperText Transfer Protocol Secure) 是 HTTP 协议的安全版本,它在 HTTP 和传输层之间添加了一层加密,通过加密的 SSL/TLS 协议传输数据,确保通信的安全性。
SSL(Secure Sockets Layer)和 TLS(Transport Layer Security)是用于在网络上实现加密通信的安全协议。TLS 是 SSL 的升级版本,目前普遍使用的是 TLS 协议。
这里举两个例子,第一个是在本地自签发一个证书,部署到本地,实现 https 的访问。第二个则是模拟生产环境,其中模拟生产环境的仅给出配置步骤和效果,申请证书过程不演示。
本地配置
生成私钥:
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
在生成过程中需要填写以下信息:
- 国家代码(如
CN
) - 省份
- 城市
- 组织名称
- 组织部门
- 公用名称(填
localhost
,因为是本地访问) - 邮箱地址
生成自签名证书:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
在 Nginx 中配置:
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
location / {
root /path/to/your/site;
index index.html;
}
}
让系统信任证书
sudo mv server.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
不信任证书时:
生产环境
如我的通配符证书 *.imqi1.com
,申请后,将证书文件下载到本地,有 .key
文件、.pem
文件、.crt
文件。
将这些文件复制到相关路径,然后按照上方步骤配置即可。
由于我手头没有可以用于演示的服务器,这部分就不进行实操了。
限流
限流(Rate Limiting)是指对某一资源的访问频率进行限制的技术,常用于防止滥用、保证系统的稳定性、提升用户体验以及防止DDoS(分布式拒绝服务)攻击。通过限流,可以控制客户端对服务的请求次数,避免过高的并发请求压垮服务器或导致服务性能下降。
Nginx 为我们提供了两种限流的方式,一种是请求限流,另一种是连接限流。
请求限流
请求限流主要是通过限制客户端请求的频率来避免服务器过载。Nginx 使用 limit_req
模块来实现请求限流,允许你控制单位时间内允许的请求次数。请求限流限制的是每个客户端在一定时间内可以发送的请求次数。如果请求超过了限流的速率,Nginx 会返回一个 503 Service Unavailable
错误或按配置延迟处理。
语法:
limit_req zone=name [burst=number] [nodelay | delay=number];
默认值:-
上下文:http、server、location。
limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=1r/s;
$binary_remote_addr
参数表示通过 remote_addr
这个标识做限制,限制的是同一客户端 IP 地址。它的大小可以从 7 到 15 个字节不等。它占用的空间因平台位数和 IP 类型不定。
zone=ip_limit:10m
表示生成 10M 大小的名字为 ip_limit
的内存区域,用于存储访问的频次信息。
rate=1r/s
表示允许相同标识客户端的一个访问频次,即一秒访问一次。1r
的意思是一次。
limit_req zone=ip_limit burst=5 nodelay;
zone
表示使用哪个区域做限制。
burst
设置爆发访问量,当有超过访问频次限制的请求就将超出的部分暂时放到这个访问区里。
nodelay
表示超过访问频次且缓冲区满了的时候直接返回 503.如果没有设置,则所有请求会依次排队。
limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=1r/s;
server {
listen 80;
location / {
# 限制请求速率
limit_req zone=ip_limit burst=5 nodelay;
proxy_pass http://backend;
}
}
连接限流
连接限流主要是通过限制每个客户端与服务器的连接数来控制客户端并发连接数。Nginx 使用 limit_conn
模块来实现连接数限制,可以限制每个客户端的最大连接数,避免单一客户端占用过多的连接资源。连接限流限制的是每个客户端在同一时间内可以与服务器建立的连接数。如果客户端的连接数超过了限制,Nginx 会返回一个 503 Service Unavailable
错误。
limit_conn_zone $binary_remote_addr zone=addr:10m;
$binary_remote_addr
表示通过 remote_addr 这个标识来做限制,限制的是同一客户端 IP 地址。
zone=ip_limit:10m
表示生成 10M 大小的名字为 ip_limit
的内存区域,用于存储访问的频次信息。
limit_conn zone number;
默认值:-
上下文:http、server、location。
如:
limit_conn addr 1;
zone
表示使用什么区域来做限制,number
代表每次允许每个相同的客户端 IP 连接数。
http {
# 定义连接限制区域,基于客户端 IP 地址
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
server {
listen 80;
location / {
# 启用连接数限制
limit_conn conn_limit_per_ip 1;
# 正常处理请求
proxy_pass http://backend;
}
}
}
实际效果
配置:
limit_req_zone $binary_remote_addr zone=addr:10m rate=1r/s;
server {
listen 80;
server_name localhost;
limit_req zone=addr burst=2 nodelay;
location / {
root /usr/share/nginx/html/80;
index index.html;
}
}
几秒内多次刷新页面,时不时出现 503 服务不可用状态,就是配置成功了。