目录
[一. 正向代理](#一. 正向代理)
[1. 编译安装Nginx](#1. 编译安装Nginx)
[2. 配置正向代理](#2. 配置正向代理)
[二. 反向代理](#二. 反向代理)
[1. 配置nginx七层代理](#1. 配置nginx七层代理)
[2. 配置nginx四层代理](#2. 配置nginx四层代理)
[三. Nginx 缓存](#三. Nginx 缓存)
[1. 缓存功能的核心原理和缓存类型](#1. 缓存功能的核心原理和缓存类型)
[2. 代理缓存功能设置](#2. 代理缓存功能设置)
[四. Nginx rewrite和正则](#四. Nginx rewrite和正则)
[1. Nginx正则](#1. Nginx正则)
[2. nginx location](#2. nginx location)
[3. Rewrite](#3. Rewrite)
[4. nginx中的set指令](#4. nginx中的set指令)
Nginx作为一款高性能的开源Web服务器和反向代理工具,凭借其轻量级、高并发处理能力和灵活的模块化设计,已成为现代Web架构的基石。从全球顶尖网站到微服务架构,Nginx在负载均衡、缓存加速、安全防护等场景中扮演着关键角色。
Nginx的四大核心功能--反向代理(七层/四层)、正向代理、缓存机制和正则表达式匹配,通过理论解析与场景化案例,掌握其设计思想与实践技巧,为构建高效、稳定的Web服务奠定坚实基础。
一. 正向代理
正向代理(Forward Proxy)是一种位于客户端和原始服务器之间的代理服务器,其主要作用是将客户端的请求转发给目标服务器,并将响应返回给客户端Nginx的正向代理 充当客户端的"中间人"',代表用户访问外部资源并隐藏真实 IP。它是企业内网管控、安全审计与加速访问的核心工具。用于场景一般是:
- 内网访问控制:限制员工访问特定网站(如社交媒体)
- 匿名访问:通过代理服务器隐藏用户真实身份
- 资源缓存加速:缓存公共资源(如软件包、镜像文件),减少外网带宽消耗

1. 编译安装Nginx
(1) 安装支持软件
Nginx的配置及运行需要pcre、zlib等软件包的支持,因此应预先安装这些软件的开发包(devel),以便提供相应的库和头文件,确保Nginx的安装顺利完成

(2) 创建运行用户、组和日志目录
Nginx服务程序默认以nobody身份运行,建议为其创建专门的用户账号,以便更准确地控制其访问权限,增加灵活性、降低安全风险。



(3) 编译安装Nginx

参数说明:
- --user=nginx 指定nginx运行用户
- --group=nginX 指定nginx运行组
- --with-http_ssl_module 支持https://
- --with-http_v2_module 支持http版本2
- --with-http_realip_module 支持ip透传
- --with-http_stub_status_module 支持状态页面
- --with-http_gzip_static_module 支持压缩
- --with-pcre 支持正则
- --with-stream 支持tcp反向代理
- --with-stream_ssl_module 支持tcp的ssl加密
- --with-stream_realip_module 支持tcp的透传ip
- --add-module=./ngx_http_proxy_connect_module 支持https转发(默认nginx不支持https转发,需要添加第三方模块)

为了使 Nginx 服务器的运行更加方便,可以为主程序 nginx 创建链接文件,以便管理员直接执行"nginx"命令就可以调用 Nginx 的主程序。

(4) 添加Nginx系统服务
为了使用Nginx服务的启动、停止、重载等操作更加方便,可以编写Nginx服务脚本,并使用chkconfig和systemctl工具来进行管理
参考上上一章的web技术与Nginx网站服务
cpp
root@localhost # vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target
[Service]
Type-forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/sbin/nginx -t
ExecStart=/usr/local/sbin/nginx
ExecReload=/usr/local/sbin/nginx-s reload
ExecStop=/bin/kill -s QUIT SMAINPID
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
User=root
Group=root
[Install]
WantedBy=multi-user.target
cpp
[root@localhost ~l# systemctl daemon-reload
[root@localhost ~]# systemctl start nginx
2. 配置正向代理


- listen 8080; 代理监听端口
- resolver 8.8.8.8 1.1.1.1; 解析域名使用的DNS 多个DNS用空格分隔
启用代理CONNECT方法(支持HTTPS)
- proxy connect;
- proxy_connect_allow 443 80; #允许代理到80和443端口
- proxy_connect_connect_timeout 10s;
- proxy_connect_read_timeout 10s;
- proxy_connect_send_timeout 10s;
处理HTTP/HTTPS请求
- location/ {
- proxy_pass scheme://http host$request uri; 动态协议
- proxy_set_header Host $http host;
优化缓冲区
- proxy_buffers 256 4k;
- proxy_max_temp_file_size 0;
保持连接
- proxy_http_version 1.1 设置http版本为1.1
- proxy_set_header Connection ""; 设置头部信息的连接数据为空

(2) 验证正向代理
linux验证

Windows验证
使用浏览器,设置http和https代理ip为192.168.10.101 端口为8080
通过实时查看nginx的访问日志,可以看到Windows下设置代理的ip和端口后,本地电脑访问的所有网页会通过代理服务器可进行访问网页,实现了正向代理的功能,并且隐藏了用户自己的真实ip
二. 反向代理
Nginx的七层(应用层)反向代理基于 HTTP/HTTPS 协议,深度解析应用层内容(如 URL、Header、Cookie),将客户端请求精准转发至后端服务器。作为企业级架构的"智能调度器",它实现了负载均衡、安全隔离与性能优化的核心能力
一般应用场景
- 负载均衡:将流量分发至多台后端服务器,避免单点故障。
- 动静分离:静态资源(图片、CSS/JS)由 Nginx 直接响应,动态请求(PHP、API)转发至Apache/Tomcat.
- SSL 终端:统一处理 HTTPS 加密/解密,降低后端服务器计算压力。
- 灰度发布:根据请求特征(如IP、Header)将部分流量导向新版本服务
Nginx 的四层(网络层)反向代理基于 TCP/UDP 协议,直接转发原始数据流,不解析应用层内容。它专为高性能、低延迟的传输层场景设计,是数据库、游戏服务器等非 HTTP 服务的理想选择。
一般应用场景
- 数据库代理:对外暴露统一端口,内部转发至 MySQL、Redis 集群。
- 游戏服务器:代理 UDP 协议,实现实时数据包负载均衡,
- SSH 跳板机:通过端口映射安全访问内网服务器
- 高可用服务:TCP服务(如 MQTT)的主备切换与健康检查。

反向代理,指的是浏览器/客户端并不知道自己要访问具体哪台目标服务器,只知道去访问代理服务器,代理服务器再通过反向代理 +负载均衡实现请求分发到应用服务器的一
种代理服务。反向代理服务的特点是代理服务器 代理的对象是应用服务器,也就是对于浏览器/客户端 来说应用服务器是隐藏的。
资源清单
实验需要两台主机
|-----------|----|----------------|-------|
| 操作系统 | 配置 | ip | 服务 |
| OpenEuler | 4G | 192.168.10.101 | Nginx |
| OpenEuler | 4G | 192.168.10.102 | Httpd |
1. 配置nginx七层代理
通过配置nginx七层代理实现转发nginx请求至后端的httpd服务,通过该转发也能实现nginx+httpd的动静分离
(1) 环境安装
192.168.10.102操作
[root@localhost~]#systemctl stop firewalld
[root@localhost~]#dnf -y install httpd
[root@localhost~]#echo "这是后端主机" > /var/www/html/index.html
[root@localhost ]#systemctl start httpd
(2) 配置nginx七层代理转发
192.168.10.101上操作:
[root@localhost~]# vim /usr/local/nginx/conf/nginx.conf
http {
upstream backend { #后端地址池设置
server 192.168.10.102:80; #后端主机设置
}
server {
listen 80;
server_name example.com;
location /{
proxy_pass http://backend; #请求转发
proxy set header Host $host;
proxy set header X-Real-IP $remote_addr;
}
}
}
[root@localhost~]# nginx-t
[root@localhost~]# nginx-s reload
上述配置中,使用upstream定义后端应用服务器的地址池"backend",在location块中,使用proxy_pass,转发请求至后端地址池,proxy_set_header Host host:将请求中的Host头部设置为客户端请求的主机名,proxy_set_header X-Real-IP remote_addr:将请求中的、X-Real-TP 头部设置为客户端的真实 IP 地址
(3) 验证转发效果
[root@localhost # curl 192.168.10.101 #这是后端主机
后端地址池中也可以定义多台主机,实现负载均衡
2. 配置nginx四层代理
SSH协议是基于TCP协议的,配置nginx的四层代理,实现代理ssh请求至后端服务器,用以登录内网服务器场景
(1) 配置四层代理
192.168.10.101上操作:
[root@localhost ~l#vi /usr/local/nginx/conf/nginx.conf
stream {
upstream ssh cluster { #定义后端地址池
server 192.168.10.102:22; #设置后端地址和服务端口
}
server {
listen 2222;
proxy_pass ssh_cluster;
proxy_connect_timeout 5s; #连接超时时间
proxy_timeout lh; #长连接保持时间
}
}
注意:
stream需要与http{ }模块平级,不能在http{}中嵌套
[root@localhost~]#nginx-t
[root@localhost~]#nginx-s reload
[root@localhost~]#ss -nlpt | grep 2222
(2) 验证四层代理
[root@localhost ~]# ssh [email protected] -p2222
[root@localhost ~]#ifconfig
通过上面的验证发现,通过202的2222端口登录后,实际上是登录到102服务器
三. Nginx 缓存
Nginx 的缓存功能是其核心能力之一,主要用于加速内容响应和降低后端服务器负载。它的缓存功能主要基于反向代理(Proxy Cache),但也可用于其他场景(如 FastCGI 缓存)
1. 缓存功能的核心原理和缓存类型
|---------------|----------------------------------------------------|
| 缓存类型 | 作用场景 |
| 代理缓存 | 反向代理模式下缓存后端服务器(如 Tomcat、Apache)的响应内容 |
| FastCGI 缓存 | 缓存 PHP/Python 等通过 FastCGI 协议处理的动态内容(需配合 PHP-FPM使用) |
| uWSGI/SCGI 缓存 | 类似 FastCGl,用于其他后端协议 |
| 静态资源缓存 | 通过:expires 指令设置客户端浏览器缓存(非服务端缓存 |

代理缓存原理:
- 第一步:客户端第一次向Nginx请求数据A;
- 第二步:当Nginx发现缓存中没有数据A时,会向服务端请求数据A;
- 第三步:服务端接收到Nginx发来的请求,则返回数据A到Nginx,并且缓存在Nginx;
- 第四步:Nginx返回数据A给客户端应用;
- 第五步:客户端第二次向Nginx请求数据A;
- 第六步:当Nginx发现缓存中存在数据A时,则不会请求服务端:第七步:Nginx把缓存中的数据A返回给客户端应用。
2. 代理缓存功能设置
因代理缓存功能需在反向代理模式下缓存后端服务器(如 Tomcat、Apache)的响应内容需要先配置七层反向代理
(1) 反向代理配置
[root@localhost]#/usr/local/nginx/conf/nginx.conf
http {
upstream backend { #后端地址池设置
server 192.168.10.102:80; #后端主机设置
}
server {
listen 80;
server_name example.com;
location /{
proxy_pass http://backend; #请求转发
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr ;
}
}
}
[root@localhost~]#nginx -t
[root@localhost#nginx-s reload
(2) 设置缓存功能
[root@localhost ~]#mkdir -p /data/nginx/cache
[root@localhost ~]#chown nginx:nginx /data/nginx/cache -R
[root@localhost ~]#vim /usr/local/nginx/conf/nginx.conf
http {
#定义缓存路径和参数
proxy_cache_path /data/nginx/cache levels=l:2 keys_zone=my_cache:10minactive=60m max_size=lg use_temp_path=off;
server {
listen 80;
server_name example.com;
location/
proxy_pass http://backend;
#启用缓存区
proxy_cache my_cache;
# 定义缓存键(URL + 请求方法 +协议)
proxy_cache_key "$scheme$request method$host$request uri"
#缓存有效期(不同状态码不同时间)
proxy_cache_valid 200 302 10m; # 200/302 状态码缓存10分钟
proxy_cache_valid 404 1m; #404 缓存1分钟lm
proxy_cache_valid any 5s; #其他状态码缓存5秒
#添加缓存状态头(调试用)
add_header X-Cache-Status $upstream_cache_status;
}
}
}
关键配置解析:
- proxy_cache_path:定义缓存文件的存储路径
- levels=1:2 :定义缓存目录的层级结构,levels=N:M,表示缓存文件路径的层级深度,
- keys_zone=my_cache:10m :定义共享内存区域,用于存储缓存键(key)和元数据(如过期时间),10m:共享内存区大小(通常每1MB可存储约8000个键)
- inactive=60m :定义缓存内容的闲置有效期。60分钟 内未被访问,将被自动删除
- max_size=1g:定义缓存目录的最大磁盘空间。当缓存量达到1GB时,Nginx 启动 LRU(最近最少使用)算法清理旧缓存。
- use_temp_path=off :控制临时文件的存储位置,推荐值:off(减少磁盘操作,提升性能)
(3) 验证缓存功能
[root@localhost ~]# curl -I 192.168.10.101
X-Cache-Status:MISS 表示MISS没有命中缓存
X-Cache-Status:HIT 再次请求发现已经命中,说明数据已经被缓存
[root@localhost~]#ls /data/nginx/cache
查看缓存目录发现已缓存数据
四. Nginx rewrite和正则
Rewrite模块作为Nginx的"规则引擎",扮演着至关重要的角色--它赋予开发者精准控制URL的能力,让请求的流转不再受限于物理路径,而是通过逻辑规则灵活适配业务需求。
Rewrite的应用场景
- 路径美化:将/product/123转换为/index.php?id=123
- 旧链接迁移:将过期URL永久重定向(301)到新地址
- 强制HTTPS/域名统一:自动跳转http://到https://,或合并www与非www域名
- 动态路由:适配单页应用(SPA)、RESTfu1API路由
- 灰度发布:按规则将部分流量导向新版本服务
1. Nginx正则
常用的正则表达式元字符
|------------|----------------------------------------------------------|
| 字符 | 描述 |
| ^ | 匹配输入字符串的起始位置 |
| $ | 匹配输入字符串的结束位置 |
| * | 匹配前面的字符零次或多次。如"o!*"能匹配"o"及"o!"、"ol!" |
| + | 匹配前面的字符一次或多次。如"ol+"能匹配"o1"及"ol"、"o"",但不能匹配"o" |
| ? | 匹配前面的字符零次或一次,例如"do(es)?"能匹配"do"或者"does","?"等效于"{0,1}" |
| . | 匹配除"""之外的任何单个字符,若要匹配包括"n"在内的任意字符,请使用诸如"[\n]"之类的模式 |
| \ | 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如"\n"匹配一个换行符,而"S"则匹配"S" |
| \d | 匹配纯数字 |
| {n} | 重复n次 |
| {n,} | 重复n次或更多次 |
| [c] | 匹配单个字符c |
| [a-z] | 匹配 a-z 小写字母的任意一个 |
| [a-zA-Z] | 匹配 a-z 小写字母或 A-Z 大写字母的任意一个 |
2. nginx location
在学习rewrite前还要了解下location,因为rewrite 通常会与 location 结合使用,但并非绝对。二者的协作能实现更精细的路径控制,location是Nginx中用于匹配请求URI(路径:只能对域名后边的除去传递的参数外的字符串起作用,例如http://www.kgc.com/index.php?id=1 只匹配/index.php)的核心指令,用于根据请求路径定义不同的处理逻辑(如静态资源服务、反向代理、重定向等)
(1) location 的语法:
location[匹配模式] {
#处理逻辑(如 root,proxy_pass,rewrite等)
}
匹配模式类型:
|----------------------|---------------------------|
| 模式 | 说明 |
| location /uri普通前缀匹配 | 匹配以指定路径开头的 URI |
| location =/ 精确匹配 | 仅匹配完全相同的 URI(优先级最高) |
| location ~ 正则匹配 | 区分大小写的正则表达式匹配 |
| location ~* 正则匹配 | 不区分大小写的正则表达式匹配 |
| location ^~ 精确前缀匹配 | 匹配前缀路径后,不再检查正则匹配(优先级高于正则) |
| location / 通用匹配 | 默认方式,优先级最低,其他方式匹配不到时匹配 |
location的优先级规则:
精确匹配 〉精确前缀匹配 〉 正则匹配(~和~*同时存在时,文件中物理位置靠上的优先,>普通前缀匹配 > 通用匹配。
(2) location 验证
[root@localhost ~]# vim /usr/local/nginx/conf/nginx. conf
location / {
return 200"通用匹配"; #其他方式匹配不到时匹配
}
location /abc {
return 200"普通前缀匹配"; #uri必须是/abc开头(和精确前缀匹配功能类似,但是优先级要低很多)
}
location ~ /test/abcdef {
return 200"区分大小写正则"; #uri中必须包含/abc
}
location ~* /test/abc
return 200"不区分大小写正则"; #uri中必须包含/abc或/ABC
}
location ^~ /abcdef {
return 200"精确前缀匹配"; #uri必须是/abc开头
}
location= /abc {
return 200"精确匹配"; #uri必须等于/abc
}
[root@localhost ~]# nginx -s reload
[root@localhost ~]# curl 192.168.10.101/abc
精确匹配
每次请求192.168.10.101/abc后,按优先级顺序依次注释配置文件中的1ocation,会发现每次的响应内容发生变更了。PS:使用正则模式时,URI部分可以使用正则表达式
3. Rewrite
(1) Rewrite 语法
rewrite <regex> <replacement> [flag];
regex:正则匹配URL字符串(只能对域名后边的除去传递的参数外的字符串起作用,例如http://www.kgc.com/index.php?id=l 只对/index.php重写)
replacement: 重写跳转后的地址
flag类型:
- last:重写后的 URI 会重新触发 location 匹配,并执行新匹配到的1ocation块中的指令,是默认类型
- break:重写后的 URI 不会重新匹配 location,直接在当前 location 中处理,且后续的 rewrite 指令不再执行
- redirect:返回302临时重定向,浏览器地址会显示跳转后的 URL 地址,爬虫不会更新url(因为是临时)
- permanent:返回301永久重定向,浏览器地址栏会显示跳转后的 URL地址,爬虫更新url
在实际工作的应用中,Nginx 跳转需求有三种方式可实现。可以直接用 rewrite 进行匹配跳转,也可以使用 if 匹配全局变量后跳转。另外,还可以使用1ocation 匹配再跳转。所以rewrite 只能放在 server}、if{}、location{}配置段中
1.servert 块中的 rewrite
执行顺序:在请求进入server块后、匹配1ocation前执行。
作用域:影响该server块下所有请求(全局生效)。
2.location{} 块中的 rewrite
执行顺序:在请求匹配到该 location 后执行。
作用域:仅对该 location 匹配的请求生效(局部生效)
- if{} 块中的 rewrite
执行顺序:在满足 if 条件时触发。
作用域:依赖 if 表达式所在的上下文(如在server中或location中)。
(2) rewrite flag验证
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
default_type text/plain; #使用浏览器验证时,为防止浏览器请求时直接下载return的内容,而不是在页面展示内容
location /abc {
rewrite ^/ /def last;
}
location /def {
return 200 "this is def";
}
[root@localhost ~]# nginx -s reload
使用浏览器请求,发现相应内容是:this is def.说明last标记后继续向下匹配location了
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
default_type text/plain; #防止浏览器请求时直接下载return的内容,而不是在页面展示内容
location /abc {
rewrite ^/ /def break;
}
location /def {
return 200 "this is def";
}
[root@localhost ~]# nginx -s reload
改成break标记,使用浏览器请求,发现请求页面未找到(因为网页代码目录确实不存在/def的内容)说明break标记使用当前结果不继续向下匹配了

[root@localhost# vim /usr/local/nginx/conf/nginx.conf
default type text/plain; #防止浏览器请求时直接下载return的内容,而不是在页面展示内容
location /abc {
rewrite ^/ /def redirect;
}
location /def {
return 200 "this is def";
}
[root@localhost l# nginx -s reload
改成break标记,使用浏览器请求,发现请求页面302跳转,并且地址栏显示的是跳转后的地址
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
default_type text/plain; #防止浏览器请求时直接下载return的内容,而不是在页面展示内容
location /abc {
rewrite ^/ /def permanent;
}
location /def {
return 200 "this is def";
}
[root@localhost ~]# nginx -s reload
改成break标记,使用浏览器请求,发现请求页面302跳转,并且地址栏显示的是跳转后的地址
(3) rewrite中的捕获组
在Nginx的rewrite 指令中,小括号()用于定义正则表达式的捕获组(CaptureGroup),捕获的文本可以通过1,2,$3等变量在重写后的 URI中引用
捕获组 "()"
在正则表达式中,(pattern)会匹配pattern 并捕获内容,按顺序存入1,2,$3 等变量中。
引用方式
在 rewrite 的替换字符串中,通过 1 表示第一个捕获组,2 表示第二个,依此类推。
[root@localhost ~]# vim /usr/local/nginx/conf/nginx. conf
location /category/ {
#匹配 /category/tech/123,捕获 tech到$1,123 到 $2
rewrite ^/category/(.+)/(\d+)$ /archive/$1/$2 last;
}
location /archive/ {
#返回捕获的分类和 ID
return 200 "Category:$l,ID:$2";
}
测试访问
[root@localhost]# curl http://localhost/category/tech/456
Category:tech, ID:456
4. nginx中的set指令
在 Nginx 中,set 指令用于定义变量并赋值,这些变量可以用于后续的条件判断、日志记录、重写规则等场景。它提供了灵活的动态配置能力,尤其在处理复杂的请求逻辑时非常有用。
语法:
set $variable value;
[root@localhost ~]# vim /usr/local/nginx/conf/nginx. conf
location /demo {
set $name "Nginx"; #定义变量 $name
return 200 "Hello, $name!" #输出:Hello, Nginx!
}
测试访问
[root@localhost ~]# curl http://localhost/demo
Hello, Nginx!