1. Nginx 概述
Nginx 是一款轻量级的套接字服务,他的特点如下:
基本特点:
- 高性能:事件驱动架构,能够处理大量并发连接(epoll 网络 IO 模型)。
- 低内存消耗:相比传统服务器如Apache,内存占用更少。
- 高并发:单机可支持数万并发连接,官方测试能够支撑5万并发连接,在实际生产环境中可以支撑2到4万并发连接。
- 模块化设计:通过模块扩展功能。
- 热部署:支持不停止服务更新配置和二进制文件。
主要用途:
- Web服务器
- 反向代理服务器
- 负载均衡器
- HTTP缓存,Nginx能够存储来自上游服务器(如应用服务器、API服务器等)的响应内容,并在后续请求相同资源时直接返回缓存内容,而不必每次都向上游服务器请求。
- 邮件代理服务器
2. Nginx 安装
官网地址:https://nginx.org
官方文档:https://nginx.org/en/docs/
2.1. Linux 系统使用包管理器安装(如 yum、apt等)
安装 nginx 主体:
官方安装文档:https://nginx.org/en/linux_packages.html
yum 安装动态模块示例:
yum install -y nginx-mod-stream # 安装 stream 模块
yum install -y nginx-all-modules # 安装所有动态模块
Bash使用包管理器安装 Nginx 的主要文件路径:
Nginx主配置文件:
路径 | 类型 | 作用 |
/etc/nginx/nginx.conf | 配置文件 | nginx主配置文件 |
/etc/nginx/conf.d/default.conf | 配置文件 | 默认网站配置文件 |
Nginx代理相关参数文件:
路径 | 类型 | 作用 |
/etc/nginx/fastcgi_params | 配置文件 | Fastcgi代理配置文件 |
/etc/nginx/scgi_params | 配置文件 | scgi代理配置文件 |
/etc/nginx/uwsgi_params | 配置文件 | uwsgi代理配置文件 |
Nginx编码相关参数文件:
路径 | 类型 | 作用 |
/etc/nginx/win-utf | 配置文件 | 将 Windows-1251 转换为 UTF-8 |
/etc/nginx/koi-utf | 配置文件 | 将 KOI8-R (俄语编码)转换为 UTF-8 |
/etc/nginx/koi-win | 配置文件 | 将 KOI8-R 转换为 Windows-1251 (另一种俄语编码) |
/etc/nginx/mime.types | 配置文件 | 定义 HTTP 响应的 MIME 类型(文件扩展名与 Content-Type 的映射关系) |
koi-* 和 win-utf:除非处理特定语言的旧系统,否则可以忽略。
Nginx管理相关命令:
路径 | 类型 | 作用 |
/usr/sbin/nginx | 命令 | Nginxi命令行管理终端工具 |
/usr/sbin/nginx-debug | 命令 | Nginx命令行与终端调试工具 |
/usr/bin/nginx-upgrade | 命令 | 用于无缝升级 Nginx(热升级),在不中断服务的情况下替换旧版本 Nginx 进程 |
Nginx日志相关目录与文件:
路径 | 类型 | 作用 |
/var/log/nginx | 目录 | Nginx默认存放日志目录 |
/etc/logrotate.d/nginx | 配置文件 | Nginx的日志切割配置,由lograte工具管理 |
Nginx动态模块相关:
路径 | 类型 | 作用 |
/usr/lib64/nginx/modules/ | 目录 | 存放 Nginx 动态模块(.so 文件) |
/usr/share/nginx/modules/ | 目录 | 通常存放 模块的配置文件 或 模块的元数据(如 README 、LICENSE ),而不是 .so 文件本身。 |
2.2. 源码安装
源码安装参考文档:https://www.runoob.com/linux/nginx-install-setup.html
3. Nginx 常用命令
Nginx 命令参数:
# Nginx 默认端口号为 80。-v、-t、-s 参数最为常用
# 常用参数:
-h:命令帮助
-v:打印版本号
-V:打印已经安装的插件等信息
-t:测试配置正确性并退出
-q:测试配置时只显示错误
-s:向主进程发送信号(reload 重新加载配置文件、stop 停止服务)
-p:指定Nginx服务器路径前缀
-c:指定Nginx配置文件路径
Bash启动 Nginx:
# 默认启动(根据配置文件),等价于 systemctl start nginx
nginx
# 指定配置文件启动
nginx -c /path/to/nginx.conf
# 以特定用户启动(需权限)
nginx -u www-data
Bash停止 Nginx:
# 立即停止(强制终止),等价于 systemctl stop nginx
nginx -s stop
# 优雅停止(等待请求完成)
nginx -s quit
Bash重新加载配置(不重启服务):
# 重新加载配置文件(适用于修改配置后)
nginx -s reload
# 重新打开日志文件(日志切割后使用)
nginx -s reopen
Bash其他命令:
nginx -t # 检测配置文件是否有语法错误,然后退出
nginx -?,-h # 打开帮助信息
nginx -v # 显示版本信息并退出
nginx -V # 显示版本和配置选项信息,然后退出
nginx -V 2>&1 | sed "s/\s\+--/\n --/g" # 配置选项信息格式化输出
killall nginx # 杀死所有nginx进程
systemctl enable nginx # 加入开机自启
nginx -T # 检测配置文件是否有语法错误,并打印完整配置
nginx -q # 在检测配置文件期间屏蔽非错误信息
nginx -p prefix # 设置前缀路径(默认是:/usr/share/nginx/)
nginx -c filename # 设置配置文件(默认是:/etc/nginx/nginx.conf)
nginx -g "directive;" # 覆盖配置文件中的全局指令(如 nginx -g "daemon off;" 禁止后台运行)
Bash4. Nginx 配置文件
4.1. 配置文件 nginx.conf 结构
说明:
- main:全局配置,所有其他配置块都包含在其内部。
- events 块:Nginx 连接相关配置。
- http 块:Nginx 处理 http 请求的主要配置。
- upstream 块:配置负载均衡。
- server 块:Nginx 主机配置块,可用于配置多个虚拟主机。
- localtion 块:可以有多个,用于匹配 URI 路径。
- stream 块:stream 做四层负载均衡并不常用
- upstream块:配置负载均衡。
- server 块:四层的 server 块使用 TCP 协议,不能使用 localtion。
- http 块与 stream 块内的 upstream 及 server 均可以有多个。
- 在 Nginx 配置文件中,每一条指令配置都必须以“;”分号结束。
4.2. 全局配置
user nobody; # 运行用户
worker_processes auto; # worker 进程数,通常与cpu核数保持一致,设置为 auto 时 nginx 会自动根据核数启动 worker 进程。
# 全局错误日志:日志级别有:debug、info、notice、warn、error、crit、alert
error_log /var/log/nginx/error.log;
# error_log /var/log/nginx/error.log notice;
# error_log /var/log/nginx/error.log info;
# PID 文件
pid logs/nginx.pid;
# include 用来引入配置文件,下述指令表示 nginx 启动时会加载 dynamic 模块的所有配置,确保动态模块都加载到 nginx 中
include /usr/share/nginx/modules/*.conf;
events {
...
}
http {
...
}
Bash4.3. events 块配置
events
块是 Nginx 配置中用于设置事件处理模型和工作连接相关参数的指令块,它位于主配置文件中与 http
块同级的位置。
events 块配置示例:
events {
worker_connections 2048;
use epoll;
}
# epoll 仅用于 linux2.6 以上内核,
# worker_connections 单个 worker 进程的最大并发链接数,可以调大,但是文件描述也要一起调大(每个TCP连接对应一个文件描述符)
Bashnginx 实现高并发的原理:
- 多进程模型
- Master 进程:
- 负责管理 Worker 进程(启动、停止、重载配置)
- 不处理客户端请求,系统开销极小
- Worker 进程:
- 实际处理请求的进程(数量通常配置为 CPU 核心数)
- 完全独立,避免锁竞争和上下文切换开销
- 通过共享内存实现进程间通信
- Master 进程:
- 非阻塞 I/O + 事件驱动模型
- 事件驱动模型
- Linux 下使用 epoll 模型,相比
select/poll
的 O(n) 遍历,epoll 仅返回就绪的 FD(文件描述符)。
- Linux 下使用 epoll 模型,相比
- 非阻塞 I/O
- 所有操作(accept/read/write)均为非阻塞
- Worker 进程不会被单个慢请求阻塞
- 事件驱动模型
4.4. http 块配置
http 块全局配置:
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;
# http 模块错误日志配置,如果未单独定义则会继承全局配置中的错误日志配置
error_log /var/log/nginx/http_error.log;
# 网络io优化参数
# 1.开启 sendfile 特性可以显著提高静态文件(如图片、CSS、JavaScript文件等)传输的效率
# 原理如下:
# 开启 sendfile 后可以减少数据在操作系统内核和用户空间之间的拷贝次数。
# 没有 sendfile 的情况下,传输文件通常需要经历如下步骤,数据需要在用户空间和内核空间之间进行两次拷贝。
# (1)从硬盘读取文件到用户空间的缓冲区(内核→用户空间)
# (2)将读取的数据从用户空间缓冲区写入到操作系统的网络缓冲区(用户空间→内核)
# (3)操作系统网络缓冲区发送数据到网络(内核→网络)
# 当开启了 sendfile 之后,这个操作简化了,并且可以避免将数据从内核空间拷贝到用户空间。sendfile 系统调用可以直接在内核中传输数据:
# (1)内核会将数据从文件系统缓冲区直接发送到网络堆栈,无需先拷贝到用户空间,然后再从用户空间拷贝到内核的网络堆栈
# (2)数据可以直接在内核地址空间中移动,避免了额外的上下文切换和数据复制开销
# 所以,sendfile 能够减少 CPU 的使用,减少操作系统的上下文切换,并允许更快地传输文件数据,特别是对于大型文件的传输
sendfile on;
# 2.通常与 sendfile 一起使用用,当 tcp_nopush 设置为 on 时,Nginx 将尽可能发送较大的 TCP 数据包,减少 TCP 报文的数量,提高传输效率。这对于减少网络传输中的 TCP 慢启动阶段,减少网络延迟和提高网络吞吐量非常有用。这在传输大型文件或使用 HTTP/1.1 的 Keep-Alive 长连接时特别有效。
tcp_nopush on;
# 3.禁用 Nagle 算法,数据将会尽快发送出去,而不是等待缓冲区满或者接收到ACK。这会减少延迟,但可能会造成网络利用率低。这个选项在处理需要快速响应的短数据流(例如HTTP/1.1的 keep-alive 连接)时非常有用。
tcp_nodelay on;
# 4.控制长连接的两个参数:
keepalive_timeout 65;
# 开启长连接:如果客户端在65秒内没有再次发送新的请求,那么Nginx将关闭这个连接,反之如果在65秒内有新的请求到来,那么这个连接会保持开启,等待处理新的请求。
keepalive_requests 100;
# 默认情况下,Nginx 的 keepalive_requests 是设置为 100,这个设置针对的是每个长连接在关闭前能处理的最大请求数量。你可以根据需要调整这个值。
# keepalive_timeout 与 keepalive_requests 两个条件是"或"的关系,满足任一条件都会关闭连接
# 配置 keepalive_requests 的目的:
# 防止某些客户端长期占用连接导致负载不均
# 定期重建连接可以释放积累的内存碎片
# 限制单个连接的使用寿命,降低某些攻击的影响
# 5.开启 gzip 压缩,节省带块加速网络传输
gzip on;
# 控制客户端请求头的缓冲区大小和数量:应对请求头过大的情况
client_header_buffer_size 128k; # 设定用于保存客户端请求头的缓冲区的大小,当客户端发送的请求头超过这个大小时,Nginx 会使用 large_client_header_buffers 分配更大的缓冲区。如果请求头超过这个总容量,Nginx 会返回 414 (Request-URI Too Large) 错误,这可以防止恶意客户端发送大量数据来消耗服务器资源。
large_client_header_buffers 4 128k; # 如果请求头过大,可以使用多个缓冲区来保存。格式为 <数量> <大小>。<数量>代表缓冲区数量,<大小>代表每个缓冲区的大小。
# mime.types定义了nginx可以识别的网络资源类型,例如css、js、jpg等
include /etc/nginx/mime.types;
# http 响应头中,如果没有明确指定 Content-Type,则默认使用 default_type 指定的
default_type application/octet-stream; # application/octet-stream。这是一种二进制的数据类型,意味着这种内容不会被浏览器解析,而是作为一个下载文件来处理。这主要用于那些不适合以普通文本或者其他MIME类型表示的文件,例如可执行文件。
# 设定虚拟主机配置
server {
# 详细配置见下一小结
}
}
Bash4.5. server 块虚拟主机配置
server 块主要负责配置虚拟主机,每个 http 块可以包含多个 server 块,而每个server 块就相当于一个虚拟主机。
虚拟主机概念:
- 虚拟主机,在Web服务里就是一个独立的网站站点,这个站点对应独立的域名(也可能是IP或端口),具有独立的程序及资源,可以独立地对外提供服务供用户访问。
- 在Nginx中,使用一个 server{} 标签来标识一个虚拟主机,一个Web服务里可以有多个虚拟主机标签对,即可以同时支持多个虚拟主机站点。
- 虚拟主机有三种类型:基于域名的虚拟主机、基于端口的虚拟主机、基于 IP的虚拟主机。
基于域名的虚拟主机:
域名的虚拟主机是生产环境中最常用的,请求的时候必须使用域名,如果使用 IP 地址访问并且没有禁止通过 IP 直接访问,则会默认使用第一个监听该端口的 server 块处理 IP 访问。
工作原理:使用域名访问一个 URL 地址时,该请求中必然包含该域名;请求到达 nginx 后,nginx 会获取到该域名并根据域名匹配相应的 server 虚拟主机。
配置示例:
server {
listen 80;
server_name example.com; # 域名1
root /var/www/example;
# 其他配置...
}
server {
listen 80;
server_name test.com; # 域名2
root /var/www/test;
# 其他配置...
}
# 访问 http://example.com 和 http://test.com 会显示不同内容。
Bash禁用 IP 地址直接访问配置示例:
# 在HTTP(80端口)和HTTPS(443端口)都添加默认服务器拦截
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _; # 所有域名不匹配的请求
ssl_certificate /pingk.top.pem;
ssl_certificate_key /pingk.top.key;
return 444; # Nginx特有的直接关闭连接
}
Bash基于端口的虚拟主机:
配置示例:
server {
listen 8080; # 端口1
server_name localhost;
root /var/www/site1;
}
server {
listen 8081; # 端口2
server_name localhost;
root /var/www/site2;
}
# 访问 http://localhost:8080 和 http://localhost:8081 显示不同内容。
Bash基于 IP 的虚拟主机:
基于 IP 的虚拟主机在生产环境中不常使用,只需要将基于域名的虚拟主机中的域名修改为 IP 就可以了,前提是服务器配置有多个 IP 地址。
虚拟主机别名设置:
虚拟主机别名,就是为虚拟主机设置除了主域名以外的一个或多个域名,这样就能实现用户访问的多个域名对应同一个虚拟主机网站的功能。
server {
listen 80;
server_name example.com test.com;
location / {
root /usr/share/nginx/html/www;
index index.html index.htm;
}
}
Bash4.6. server 块 location 配置
location
用于匹配 URI 并定义处理规则。对于一个 URL 地址,location 只会匹配 URI 地址部分,? 号后的参数部分不匹配。即对 localtion 来说,/test 和 /test?a=1是一样的路径。
4.6.1. 基本语法
location [匹配模式] {
# 处理逻辑
}
Bash4.6.2. 匹配模式
- 前缀匹配:
- 匹配以指定字符串开头的 URI。
- 示例:
# 两种形式同时存在时匹配的路径不能相同,否则会报错
location /images
location ^~ /images
# 以 /images 开头的 URI 会被匹配到
Bash- 精确匹配:
- 只匹配完全相同的 URI(优先级最高)。
- 示例:
location = /login
# 只有 /login 会被匹配到
Bash- 正则匹配:
- 使用正则表达式匹配 URI
- location ~(区分大小写)
location ~*
(不区分大小写)- 示例:
location ~ \.php$
# 匹配以 .php 结尾的 URI 地址
Bash4.6.3. 匹配优先级规则
Nginx 按 从高到低 的顺序检查 location
,一旦匹配成功则停止搜索。优先级如下:
- = 精确匹配
location = /test { ... } # 仅匹配 /test
Bash- ^~ 前缀匹配(匹配成功则停止后续匹配)
location ^~ /static/ { ... } # 匹配 /static/ 开头的 URI,不检查后续正则
Bash- ~ 或 ~* 正则匹配(按配置文件中的顺序匹配)
location ~ \.php$ { ... } # 区分大小写匹配 .php 结尾
location ~* \.(jpg|png)$ { ... } # 不区分大小写匹配 .jpg 或 .png
Bash- 普通前缀匹配(按最长前缀优先)
location / { ... } # 默认匹配所有 URI
location /docs/ { ... } # 比 / 更具体,优先级更高
Bash4.7. server 块 listen 指令
4.7.1. listen 指令用法介绍
基础语法:
listen address[:port] [additional_parameters];
listen port [additional_parameters];
Bash基本用法示例:
# 监听指定端口(IPv4)
listen 80; # 监听所有IPv4地址的80端口
# 监听指定IP和端口
listen 192.168.1.100:8080; # 只监听192.168.1.100的8080端口
# 监听IPv6地址
listen [::]:80; # 监听所有IPv6地址的80端口
listen [fe80::1]:80; # 监听特定IPv6地址
Bash高级参数选项:
- 协议相关参数
default_server
设为默认服务器,示例:listen 80 default_server;
ssl
启用SSL/TLS,示例:listen 443 ssl;
http2
启用HTTP/2(需同时启用ssl),示例:listen 443 ssl http2;
proxy_protocol
启用PROXY协议,示例:listen 80 proxy_protocol;
- Nginx 将在 80 端口监听普通 HTTP 请求。
- 但期望接收到的连接使用 PROXY 协议(而不是原始 HTTP 请求)。
- Nginx 会先解析 PROXY 协议头,然后才处理后续的 HTTP 请求。
- 使用场景不多。
- 连接处理参数
backlog=
设置待处理连接队列的最大长度。rcvbuf=
设置接收缓冲区大小。sndbuf=
设置发送缓冲区大小。bind
单独绑定地址/端口。reuseport
启用SO_REUSEPORT(内核级负载均衡)。so_keepalive=
配置TCP keepalive参数
4.7.2. listen 指令 reuseport 参数详解
nginx 有两种工作模式:
- 1个 master 主进程 + 多个 worker 子进程(worker 进程禁用 reuseport 模式,默认模式)
- 特点:所有 worker 进程共享同一个监听套接字
- 优点:因为全连接队列是共享的,所以当某个 worker 进程繁忙时,它去全连接队列里 accpet 的能力会降低,但其他空闲的 worker 进程则不受影响,这会平衡所有 worker 进程的压力。
- 缺点:多个 worker 进程争抢会带来额外的损耗。
- 配置示例:
server {
listen 80; # 不添加 reuseport 参数
listen [::]:80;
# 其他配置...
}
Bash- 1个 master 主进程 + 多个 worker 子进程(worker 进程启用 reuseport 模式)
- 特点:每个 worker 进程有自己独立的监听套接字。
- 优点:多个进程不需要竞争某个公共资源,减少竞争的资源消耗,提高处理效率。
- 缺点:应为每个 worker 监听独立的连接队列,当某个 worker 进程繁忙时,其他空闲进程不能帮忙分摊压力。可能会导致个别连接的请求的延迟增大。
- 解决方案:引入线程池,但同时增大了出现 bug 的几率,例如锁竞争问题、单个线程 bug 导致整个进程退出的问题。
- 配置示例:
# 如果需要完整的多线程支持,编译时需要的模块,且需要 Nginx 1.7.11+
./configure --with-threads \
--with-file-aio \
--with-http_ssl_module
# 定义线程池
thread_pool default threads=32 max_queue=65536;
# threads:线程池中的线程数量(建议设置为CPU核心数的2-4倍)
# max_queue:等待队列的最大任务数(超过此值将返回错误)
http {
aio threads=thread_pool; # 启用线程池
# 启用线程池与reuseport并不冲突
server {
listen 8089 reuseport backlog=10240;
...
}
}
Bash4.8. server 块 return 指令
在 Nginx 中,return
指令用于立即终止请求处理并返回指定的 HTTP 状态码或重定向 URL。它通常用于重定向、快速响应或阻止某些请求。
基本语法:
return code [text];
return code URL;
return URL;
# code:HTTP 状态码(如 301, 302, 404, 200 等)。
# text:直接返回的响应内容(适用于 2xx 或 4xx 状态码)。
# URL:重定向目标地址(适用于 3xx 状态码)。
Bash使用示例:
直接返回状态码:
location /forbidden {
return 403 "Access Denied"; # 返回 403 并显示自定义文本
}
location /health {
return 200 "OK"; # 返回 200 状态码和 "OK"
}
# 访问 /forbidden → 返回 HTTP 403 和文本 "Access Denied"。
# 访问 /health → 返回 HTTP 200 和 "OK"。
Bash重定向(3xx):
location /old-url {
return 301 https://example.com/new-url; # 永久重定向
}
location /temporary {
return 302 /new-location; # 临时重定向(相对路径)
}
# 访问 /old-url → 浏览器跳转到 https://example.com/new-url(301 永久重定向)。
# 访问 /temporary → 跳转到 /new-location(302 临时重定向)。
Bash直接返回 URL(隐式 302):
location /go-to-home {
return https://example.com; # 默认 302 临时重定向
}
# 等同于
location /go-to-home {
return 302 https://example.com;
}
Bash阻止特定请求:
location /admin {
return 403; # 禁止访问 /admin
}
location ~* \.php$ {
return 444; # 静默关闭连接(Nginx 特有)
}
# 444 是 Nginx 的特殊状态码,直接关闭连接,不返回任何内容。
Bash结合变量:
location /check-ip {
return 200 "Your IP: $remote_addr"; # 返回客户端 IP
}
location /dynamic-redirect {
return 302 "https://example.com/user/$arg_id"; # 根据查询参数重定向
}
Bash4.9. server 块 rewrite 配置
基本语法:
rewrite regex replacement [flag];
# regex:正则表达式匹配原始 URI(PCRE 语法)。
# replacement:替换后的新 URI(可含变量)。
# flag:可选参数,控制重写行为(如 last, break, redirect, permanent)。
## last:停止当前 rewrite,用新 URI 重新匹配 location(类似新请求)。
## break:停止所有 rewrite,直接使用当前结果继续处理(不重新匹配 location)。
## redirect:返回 302 临时重定向(浏览器地址栏变化)。
## permanent:返回 301 永久重定向(SEO 友好)。
Bash使用示例:
简单重写(无 flag):
location /old {
rewrite ^/old/(.*)$ /new/$1; # /old/path → /new/path
}
# 默认行为:隐式 last,重写后重新匹配 location。
Bash强制重定向(301/302):
location /legacy {
rewrite ^/legacy/(.*)$ https://example.com/new/$1 permanent; # 301
}
location /temp {
rewrite ^/temp/(.*)$ /new/$1 redirect; # 302
}
Bash终止后续处理(break):
location /static {
rewrite ^/static/(.*)$ /data/$1 break; # 直接映射到文件系统
proxy_pass http://backend; # 这行不会执行
}
# break 会跳过后续的 rewrite 和 location 重新匹配。
Bash与 return
的区别:
rewrite | return | |
作用 | 修改 URI 内部重写或外部重定向 | 直接返回状态码或重定向 |
性能 | 略低(需正则匹配) | 更高(直接响应) |
适用场景 | 复杂 URL 规则、动态路径 | 简单重定向、快速拦截 |
是否重新匹配 location | 取决于 flag(last 会重新匹配) | 立即终止,不重新匹配 |
return
。4.10. server 块 root 与 alias 指令
4.10.1. root
指令
基本语法:
root path;
Bash工作原理:
root
指令会将 location 匹配的 URI 部分附加到指定的路径后面- 它是将完整的请求 URI 附加到 root 路径之后
示例:
location /images/ {
root /data/www;
}
# 对于请求 /images/example.jpg,Nginx 会查找 /data/www/images/example.jpg
Bash4.10.2. alias
指令
基本语法:
alias path;
Bash工作原理:
alias
指令会 用指定的路径替换 location 匹配的部分- 它只替换匹配的部分,而不是附加整个 URI
示例:
location /images/ {
alias /data/images/;
}
# 对于请求 /images/example.jpg,Nginx 会查找 /data/images/example.jpg(注意 /images/ 被替换为 /data/images/)
# alias 替换目录时结尾必须带斜线
Bash4.11. server 块代理指令
代理模式:
- 正向代理(Forward Proxy)
- 定义:正向代理是客户端的代理服务器,代表客户端向外部服务器发送请求。客户端需要显式配置代理服务器。
- 核心特点
- 代理对象:代理的是客户端。
- 隐藏客户端:外部服务器只能看到代理服务器的IP,无法识别真实客户端。
- 客户端控制:由客户端主动配置使用(如企业内网、科学上网工具)。
- 典型应用场景
- 访问限制资源:突破地域限制(如访问Google)。
- 企业内网安全:统一通过代理访问外部,便于监控和过滤。
- 匿名性:隐藏客户端真实IP。
- 典型工具:Shadowsocks、Squid
- 示例
用户(客户端) → 正向代理 → 互联网 → 目标服务器
目标服务器看到的请求来源是正向代理的IP。
TeX- 反向代理(Reverse Proxy)
- 定义:反向代理是服务端的代理服务器,代表服务器接收客户端请求,并将请求转发到内部服务器。客户端无需感知代理存在。
- 核心特点
- 代理对象:代理的是服务端。
- 隐藏服务器:客户端不知道真实服务器的IP或架构。
- 服务端控制:由服务器管理员配置,对客户端透明。
- 典型应用场景
- 负载均衡:将请求分发到多台后端服务器(如Nginx)。
- 安全防护:隐藏后端服务器,防御DDoS攻击(如Cloudflare)。
- 缓存加速:缓存静态内容,减轻服务器压力。
- SSL终结:统一处理HTTPS加密/解密,降低后端负担。
- 典型工具:Nginx、HAProxy、CDN
- 示例
用户(客户端) → 互联网 → 反向代理 → 内部服务器集群
客户端认为反向代理就是真实的服务器。
TeXNginx 常用的代理指令:
proxy_pass # 代理http协议
fastcgi_pass # 代理fastcgi协议,适用 PHP 语言程序
uwsgi_pass # 代理uwsgi协议,使用 Python 语言程序
grpc_pass # 代理gRPC协议,适用 go 语言程序
Bash代理指令优化:
以 proxy_pass 为例:
# nginx的配置文件如下
server {
listen 80;
server_name linux.lb.com;
location / {
proxy_pass xxxx;
include proxy_params;
}
}
# 优化参数可以单独写入一个文件proxy_params中,当然你也可以直接与proxy_pass并列放置。
vim /etc/nginx/proxy_params
#(1)转发原始请求的 host 头部
proxy_set_header X-Real-IP $remote_addr; # 设置真实/原始客户端的 IP 地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 追加原始客户端的 IP 地址到 X-Forwarded-For 头信息中。这样,在后端服务器中就可以通过读取 X-Forwarded-For 头信息来获取原始客户端的 IP 地址。
proxy_set_header Host $host;
#(2)代理到后端的TCP连接、响应、返回等超时时间
proxy_connect_timeout 10s; # nginx代理与后端服务器连接超时时间(代理连接超时)
proxy_read_timeout 10s; # nginx代理等待后端服务器的响应时间
proxy_send_timeout 10s; #后端服务器数据回传给nginx代理超时时间
#(3)proxy_buffer代理缓冲区:nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端
proxy_buffering on;
proxy_buffer_size 8k; # 设置nginx代理保存用户头信息的缓冲区大小
proxy_buffers 8 8k; #proxy_buffers 缓冲区
Bash4.12. upstream 块配置
upstream 在 http 或 stream 块内,与 server 块并列,用于配置负载均衡。虽然 upstream 模块需要与代理指令一起使用,但代理指令仅仅只是用于转发请求它本身并没有任 何负载均衡的功能,upstream 才是实现负载均衡的具体模块。
4.13. 一些资源分离配置示例
动态与静态请求分离:
server {
listen 80;
server_name www.example.com;
# 静态资源处理
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|ttf|svg|eot|mp4|webm)$ {
root /var/www/static;
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
# 文件不存在时不转发到后端
try_files $uri =404;
}
# 动态请求处理
location / {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Bash通过判断请求的资源类型进行分离:
upstream android {
server 10.0.0.7;
}
upstream iphone {
server 10.0.0.8;
}
upstream pc {
server 10.0.0.9;
}
server {
listen 80;
server_name linux.sj.com;
location / {
if ($http_user_agent ~* "Android") { #判断如果是安卓端
proxy_pass http://android; #代理到android虚拟主机池
}
if ($http_user_agent ~* "iPhone") { #判断如果是苹果端
proxy_pass http://iphone; #代理到iphone虚拟主机池
}
if ($http_user_agent ~* "WOW64") { #判断如果是IE浏览器
return 403; #直接返回403
}
proxy_pass http://pc; #如果没有匹配到以上内容,默认都代理到pc虚拟主机池
include proxy_params;
}
}
Bash4.14. 一个参考配置示例
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_accept on; # 启用multi_accept提高连接处理效率,允许worker一次性接受所有新连接请求,减少唤醒次数
}
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;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 100;
reset_timedout_connection on; # 超时连接直接重置而非缓慢关闭,释放资源更快
# 压缩与缓存
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
client_header_buffer_size 128k; # 设定用于保存客户端请求头的缓冲区的大小,当客户端发送的请求头超过这个大小时,Nginx 会使用 large_client_header_buffers 分配更大的缓冲区。如果请求头超过这个总容量,Nginx 会返回 414 (Request-URI Too Large) 错误,这可以防止恶意客户端发送大量数据来消耗服务器资源。
large_client_header_buffers 4 128k;
# SSL优化配置
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
# 安全头
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
include /etc/nginx/conf.d/*.conf;
}
# 在HTTP(80端口)和HTTPS(443端口)都添加默认服务器拦截
server {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/ssl_key/pingk.top.pem;
ssl_certificate_key /etc/nginx/ssl_key/pingk.top.key;
return 403; # 改为403比444更友好
}
# # HTTP重定向到HTTPS
server {
listen 80;
server_name pingk.top;
# 301永久重定向到HTTPS
return 301 https://$host$request_uri;
}
# 主服务器配置
server {
listen 443 ssl reuseport;
http2 on;
server_name pingk.top;
root /var/www/html/wordpress;
ssl_certificate /etc/nginx/ssl_key/pingk.top.pem;
ssl_certificate_key /etc/nginx/ssl_key/pingk.top.key;
index index.php index.html;
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|ttf|svg|eot)$ {
expires 30d;
access_log off;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
# 安全防护:禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 禁止访问敏感文件
location ~* ^/(wp-config\.php|license\.txt|readme\.html) {
deny all;
}
# 限制访问上传目录中的PHP文件
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
# 以 .php 结尾的请求,交给 php-fpm 程序处理
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 172.22.251.33:9000;
# 设置 FastCGI 参数 SCRIPT_FILENAME,告诉 PHP-FPM 要执行的脚本路径。
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 安全防护:限制PHP执行目录
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/tmp:/proc";
# 加载默认的 FastCGI 参数文件(通常位于 /etc/nginx/fastcgi_params)
include fastcgi_params;
}
location / {
# 按顺序尝试查找文件
# 先尝试直接访问 $uri(请求的原始文件路径)
# 如果不存在,尝试访问 $uri/(作为目录处理)
# 如果都不存在,最后转发到 /index.php,并保留原始查询参数 $args
try_files $uri $uri/ /index.php?$args;
}
}
Bash