在学习java后端开发的路上,Nginx是我们必须要学的中间件,本文将带宝子们全面的了解nginx从基础配置到企业级开发案例的全过程!
目录
一、Nginx概述

Nginx是一款高性能的轻量级Web服务器和反向代理服务器。它以极低的内存占用、快速启动速度以及出色的高并发处理能力著称,因此在互联网项目中得到广泛应用。Nginx采用异步非阻塞事件驱动架构,专为性能优化而设计。
二、Nginx 四大应用场景
1、HTTP服务器
Nginx本身具备静态资源托管能力,对于纯静态网站而言,可直接使用Nginx作为服务器进行部署。这种方案既能满足静态资源的访问需求,又能简化部署流程
2、反向代理
反向代理是Nginx最常用的功能之一。反向代理(Reverse Proxy)是指代理服务器接收来自互联网的连接请求,然后将这些请求转发给内网服务器,并将服务器返回的结果再传回给请求的客户端。在此过程中,代理服务器对外表现为一个反向代理服务器
3、负载均衡
Nginx的负载均衡功能是其核心特性之一。该功能将请求流量合理分发到多个后端服务器上,包括Web服务器、FTP服务器以及企业关键应用服务器等,通过多台服务器的协同工作来提升整体处理能力。
4、动静分离
动静分离是将动态网站中的资源按变化频率进行区分,将静态资源和动态资源有效隔离。通过这种拆分,我们可以针对静态资源的特点实施缓存策略,这正是网站静态化处理的核心所在
三、使用Nginx的好处
单机架构

Tomcat默认配置的最大并发请求数为150。实际并发承载能力主要取决于硬件配置:CPU核心数越多、分配给JVM的内存越大,性能表现越好。不过需要注意的是,增加内存可能加重垃圾回收(GC)的负担
引入反向代理实现负载均衡
负载均衡通过将流量分散到多台Web服务器来解决单台服务器处理能力不足的问题。它将并发请求均匀分配给后端服务器群组,有效分解系统压力
总结
1.它具有出色的高并发处理能力,官方测试支持5万并发连接,实际生产环境下可稳定承载2- 4万并发连接。
2.内存占用极低,资源消耗小。
3.相比购买F5 BIG-IP或NetScaler等动辄数十万的硬件负载均衡设备,Nginx作为开源软件 可免费使用并合法商用。
4.具备智能健康检查机制,当后端服务器出现故障时,不会影响前端用户的正常访问。
5.支持gzip压缩,有效节省带宽资源。
6.运行稳定可靠,作为反向代理(负载均衡)方案时几乎不会出现宕机情况。
7.支持热部署功能,可在不中断服务的情况下进行软件升级
四、 环境准备
四项确认

一项安装
yum -y install gcc make automake pcre-devel zlib zlib-devel openssl openssl-devel
参数:
gcc:需要安装GCC编译环境
pcre:PCRE(Perl兼容正则表达式)是一个提供Perl风格正则表达式功能的库
zlib:提供多种压缩/解压方法,Nginx用它来gzip压缩HTTP内容,需预先安装
OpenSSL:功能全面的安全套接层密码库,包含主流加密算法、密钥证书管理和SSL协议实现。
- A
- A
五、Nginx下载与安装
下载Nginx源码
官网下载Nginx软件官方网站http://Nginx.org
Nginx 官方提供三种版本类型:
- Mainline Version:主线版本,是最新发布但尚未经过充分生产环境测试的版本
- Stable Version:稳定版本,经过充分测试,推荐用于生产环境
- Legacy Version:历史版本,已不再维护
1.创建存放源文件的文件夹
首先在目录/opt下创建apps目录,用于存放源文件以及解压后的文件
2.上传Nginx到步骤1创建的目录下
3.解压 Nginx
[root@node1 apps]# pwd
/opt/apps
[root@node1 apps]# ls
Nginx-1.20.1.tar.gz
[root@node1 apps]# tar -zxvf Nginx-
1.20.1.tar.gz
[root@node1 apps]# cd Nginx-1.20.1
进入到 Nginx 解压包目录/opt/apps/Nginx-1.20.1 目录中,查看Nginx 的目录。
其中各个目录中存放的文件作用为:
auto:包含 Nginx 自动安装的相关文件
conf:存储 Nginx 服务器配置文件
configure:用于配置即将安装的软件,生成 makefile 编译文件
contrib:收录由第三方机构提供的文档资料
html:存放 Nginx 默认欢迎页面
man:包含 Nginx 使用手册文档
src:存放 Nginx 源代
4.生成 makefile
在 Nginx 解压目录下运行 make 命令,用于完成编译。但此时会给出提示:没有指定目标,并且没有发现编译文件 makefile。
[root@node1 Nginx-1.20.1]# make
make: *** 没有指明目标并且找不到 makefile。 停止。
要使用 make 命令编译程序,首先需要生成编译文件 Makefile。可以通过运行 configure 命令来生成这个文件。关于 configure 命令的具体配置参数,可以查看其帮助文档:使用 --help 选项即可显示所有可用参数及其说明
configure 参数说明:
--prefix
:指定 Nginx 的安装目录(注意与解压目录区分)--sbin-path
:设置 Nginx 可执行文件的路径--modules-path
:指定 Nginx 模块的存放位置--conf-prefix
:定义 Nginx 配置文件的存储路径--pid-path
:设置 Nginx 进程 ID 文件的存放路径--error-log-path
:配置错误日志文件的存储位置--http-log-path
:设置 HTTP 访问日志的存储路径
5.安装编译参数
6.配置参数
[root@node1 Nginx-1.20.1]# mkdir -p /var/temp/nginx/client
[root@node1 Nginx-1.20.1]# pwd
/opt/apps/nginx-1.20.1
[root@node1 Nginx-1.20.1]#
./configure \
--prefix=/usr/local/nginx \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--with-http_ssl_module \
--with-http_gzip_static_module \
--http-client-body-temp-path=/usr/local/nginx/temp/client_body_temp \
--http-proxy-temp-path=/usr/local/nginx/temp/proxy_temp \
--http-fastcgi-temp-path=/usr/local/nginx/temp/fastcgi_temp \
--http-uwsgi-temp-path=/usr/local/nginx/temp/uwsgi_temp
#注意:
/var/temp/Nginx/client目录需要手动创建。
案例参数详解
1.
--prefix
指定 Nginx 安装的根目录。所有文件将被安装到此目录下,除非其他参数另行指定路径1。
例如:--prefix=/usr/local/nginx
表示将 Nginx 安装到/usr/local/nginx
目录。2.
--pid-path
设置 Nginx 主进程 PID 文件的存放路径。PID 文件记录了主进程的进程 ID,用于管理 Nginx 的启动、停止和重启操作2。
例如:--pid-path=logs/nginx.pid
表示 PID 文件将存储在logs/nginx.pid
路径下。3.
--error-log-path
指定错误日志的存放路径。错误日志记录了 Nginx 运行过程中发生的错误信息,便于排查问题4。
例如:--error-log-path=logs/error.log
表示错误日志将存储在logs/error.log
路径下。4.
--http-log-path
指定 HTTP 访问日志的存放路径。访问日志记录了客户端对 Nginx 的每次请求信息,包括请求时间、IP 地址、请求 URL 等1。
例如:--http-log-path=logs/access.log
表示访问日志将存储在logs/access.log
路径下。5.
--with-http_ssl_module
启用 HTTP SSL 模块,支持 HTTPS 协议。该模块允许 Nginx 使用 SSL/TLS 加密通信,确保数据传输的安全性2。
例如:--with-http_ssl_module
启用了 SSL 支持。6.
--with-http_gzip_static_module
启用静态文件压缩模块。该模块允许 Nginx 自动检测并提供预压缩的
.gz
文件,从而减少带宽消耗并提高页面加载速度3。
例如:--with-http_gzip_static_module
启用了静态文件压缩功能。7.
--http-client-body-temp-path
指定客户端请求体临时文件的存放路径。当客户端上传大文件时,Nginx 可能需要将请求体保存到临时文件中。
例如:--http-client-body-temp-path=temp/client_body_temp
表示临时文件将存储在temp/client_body_temp
路径下。8.
--http-proxy-temp-path
指定代理服务器临时文件的存放路径。当 Nginx 作为反向代理时,可能会生成临时文件以处理代理请求2。
例如:--http-proxy-temp-path=temp/proxy_temp
表示代理临时文件将存储在temp/proxy_temp
路径下。9.
--http-fastcgi-temp-path
指定 FastCGI 临时文件的存放路径。当 Nginx 使用 FastCGI 处理动态内容时,可能会生成临时文件1。
例如:--http-fastcgi-temp-path=temp/fastcgi_temp
表示 FastCGI 临时文件将存储在temp/fastcgi_temp
路径下。10.
--http-uwsgi-temp-path
指定 uWSGI 临时文件的存放路径。当 Nginx 使用 uWSGI 协议与后端应用通信时,可能会生成临时文件4。
例如:--http-uwsgi-temp-path=temp/uwsgi_temp
表示 uWSGI 临时文件将存储在temp/uwsgi_temp
路径下。
7.编译安装
make && make install
这是两个命令:
make
用于编译,make install
用于安装。它们可以分别执行。使用&&
连接这两个命令时,只有在第一个命令成功执行后才会执行第二个命令
六、Nginx目录详解
#安装目录由--prefix=/usr/local/Nginx
[root@node1 ~]# cd /usr/local/Nginx/
[root@node1 Nginx]# ll
总用量 0
drwxr-xr-x 2 root root 333 8月 27 15:37 conf
drwxr-xr-x 2 root root 40 8月 27 15:37 html
drwxr-xr-x 2 root root 6 8月 27 15:37 logs
drwxr-xr-x 2 root root 19 8月 27 15:37 sbin
注意事项:
如需查看/application/Nginx
目录结构,请执行命令:tree /application/Nginx
若提示未找到tree命令,请先安装该工具:yum install tree -y
conf目录
Nginx 核心配置文件目录存放着所有关键配置,其中最重要的 nginx.conf
主配置文件就位于此目录中。
[root@node1 Nginx]# ll conf/
总用量 68
-rw-r--r-- 1 root root 1077 8月 27 15:37
fastcgi.conf
-rw-r--r-- 1 root root 1077 8月 27 15:37
fastcgi.conf.default
-rw-r--r-- 1 root root 1007 8月 27 15:37
fastcgi_params
-rw-r--r-- 1 root root 1007 8月 27 15:37
fastcgi_params.default
-rw-r--r-- 1 root root 2837 8月 27 15:37
koi-utf
-rw-r--r-- 1 root root 2223 8月 27 15:37
koi-win
-rw-r--r-- 1 root root 5231 8月 27 15:37
mime.types
-rw-r--r-- 1 root root 5231 8月 27 15:37
mime.types.default
-rw-r--r-- 1 root root 2656 8月 27 15:37
Nginx.conf
-rw-r--r-- 1 root root 2656 8月 27 15:37
Nginx.conf.default
-rw-r--r-- 1 root root 636 8月 27 15:37
scgi_params
-rw-r--r-- 1 root root 636 8月 27 15:37
scgi_params.default
-rw-r--r-- 1 root root 664 8月 27 15:37
uwsgi_params
html目录
[root@node1 Nginx]# ll html/
总用量 8
-rw-r--r-- 1 root root 494 8月 27 15:37
50x.html #错误提示页面
-rw-r--r-- 1 root root 612 8月 27 15:37
index.html #访问Nginx时的首页
logs目录
存放Nginx的日志文件。 access.log error.log
#刚安装完Nginx,从未启动过的话logs目录下什么都没有,
只有启动Nginx后,才会出现以下三个文件
[root@node1 Nginx]# ll logs/
总用量 4
-rw-r--r-- 1 root root 0 8月 27 16:29
access.log #记录正常访问的日志
-rw-r--r-- 1 root root 0 8月 27 16:29
error.log #错误日志
-rw-r--r-- 1 root root 6 8月 27 16:29
Nginx.pid #Nginx进程id
[root@node1 Nginx]# cat logs/Nginx.pid
24514 #当前启动Nginx的master进程的id
sbin目录
Nginx命令的目录,如Nginx的启动命令。
[root@node1 Nginx]# ll sbin/
总用量 5884
-rwxr-xr-x 1 root root 6023208 8月 27 15:37
Nginx #启动关闭等操作的脚本
[root@node1 Nginx]# ./sbin/Nginx #启动Nginx
[root@node1 Nginx]# ps aux|grep Nginx #查看
Nginx的进程
root 24514 0.0 0.1 45996 1136 ?
Ss 16:29 0:00 Nginx: master process
./sbin/Nginx
nobody 24515 0.0 0.1 46444 1876 ?
S 16:29 0:00 Nginx: worker process
七 Nginx服务启停控制
启动Nginx服务
在Linux系统中,只需执行安装目录sbin文件夹下的二进制文件即可启动Nginx服务器。
./Nginx -h
参数说明
-v
:显示版本号
-h
:显示帮助信息主要选项
-V
:显示版本号及配置信息
-t
:测试配置文件语法并退出
-q
:测试配置时仅显示错误信息
-s
:向主进程发送信号
-p
:指定Nginx安装路径前缀
-c
:指定主配置文件路径
-g
:指定附加配置文件路径
Nginx服务的停止
两种方式:
# 快速停止,快速停止是指立即停止当前Nginx服务正在处理的所有网络请求,马上丢弃连接,停止工作。
Nginx -s stop # 快速关闭
# 平缓停止,平缓停止是指允许Nginx服务将当前正在处理的网络请求处理完成,但不再接收新的请求,之后关闭连接,停止工作。
Nginx -s quit # 等待工作进程处理完成后关闭
Nginx服务的重启
修改 Nginx 服务器配置或添加新模块后,要使变更生效,需要重启 Nginx 服务。操作步骤可以是先停止服务,然后使用新的配置文件重新启动
Nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启
Nginx -s reopen # 重启 Nginx
八、Nginx配置指令详解_全局块
1. 全局块概述
全局块是 Nginx 配置文件中的顶层配置部分,主要用于定义整个 Nginx 实例的全局参数。这些参数影响 Nginx 的整体运行环境和行为
2. 常见全局块指令详解
2.1 user
和 group
user
和 group
指令用于指定 Nginx 工作进程运行时的用户和用户组。这有助于限制 Nginx 的权限,提高系统的安全性。
user nginx nginx;
上述配置表示 Nginx 的工作进程将以 nginx
用户和 nginx
用户组的身份运行
2.2 worker_processes
worker_processes
指令用于设置 Nginx 的工作进程数量。通常建议将其设置为 CPU 核心数以实现最佳性能。
worker_processes auto;
auto
参数会自动检测服务器的 CPU 核心数并设置相应的工作进程数量
2.3 error_log
error_log
指令用于指定错误日志的路径和日志级别。常见的日志级别包括 debug
、info
、notice
、warn
、error
等。
error_log /var/log/nginx/error.log error;
上述配置将错误日志存储在 /var/log/nginx/error.log
中,并设置日志级别为 error
。
2.4 pid
pid
指令用于指定 Nginx 主进程 PID 文件的存放路径。PID 文件记录了主进程的进程 ID,便于通过脚本或命令管理 Nginx 的启动、停止和重启操作。
pid /var/run/nginx.pid;
上述配置将 PID 文件存储在 /var/run/nginx.pid
路径下。
2.5 worker_rlimit_nofile
worker_rlimit_nofile
指令用于设置每个工作进程的最大文件描述符数量。这对于处理大量并发连接的场景非常重要。
worker_rlimit_nofile 65535;
2.6 include
在某些场景下,我们需要在当前主配置文件中引用其他Nginx配置或第三方模块配置。Nginx提供的include
指令可以实现配置文件的引入。
include file;
其中,file是要引入的配置文件,它支持相对路径。
九、Nginx配置指令详解_events块
格式化
虽然 events
块不属于严格意义上的全局块,但它是全局配置的一部分,用于定义事件驱动模型的相关参数。
events {
worker_connections 1024;
use epoll;
}
worker_connections
指令设置每个工作进程可以同时处理的最大连接数。use
指令指定使用的事件模型(如epoll
、kqueue
等)。
示例配置
user nginx nginx;
worker_processes auto;
error_log /var/log/nginx/error.log error;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535;
events {
worker_connections 1024;
use epoll;
}
十、Nginx配置指令详解_HTTP块
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name 192.168.71.167;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
配置文件结构
这是一个典型的Nginx配置文件片段,定义了一个HTTP服务器块(http
)及其子配置。以下逐段解析其功能:
HTTP全局配置
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
-
include mime.types
加载外部文件mime.types
,该文件定义了文件扩展名与MIME类型的映射关系(如.html
对应text/html
)。 -
default_type application/octet-stream
默认MIME类型为application/octet-stream
(二进制流),当无法识别文件类型时使用。 -
sendfile on
启用高效文件传输模式,减少用户态与内核态之间的数据拷贝。 -
keepalive_timeout 65
设置保持连接的超时时间为65秒。
服务器块配置
server {
listen 80;
server_name 192.168.71.167;
-
listen 80
监听80端口(HTTP默认端口)。 -
server_name 192.168.71.167
指定服务器名为IP地址192.168.71.167
,匹配该IP的请求将由该服务器块处理。
根路径配置
location / {
root html;
index index.html index.htm;
}
-
root html
设置根目录为相对路径html
(通常为Nginx安装目录下的html
文件夹)。 -
index index.html index.htm
定义默认索引文件,当请求路径为目录时,按顺序尝试返回index.html
或index.htm
。
错误页面配置
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
-
error_page
当发生500、502、503或504错误时,返回/50x.html
页面。 -
location = /50x.html
精确匹配/50x.html
请求,并指定其文件位于html
目录下。
配置逻辑总结
- 全局设置:定义MIME类型、传输优化和连接超时。
- 虚拟主机:响应IP为
192.168.71.167
的80端口请求。 - 请求处理:
- 静态文件从
html
目录提供。 - 错误状态码返回定制页面。
- 静态文件从
- 路径匹配:
/
匹配所有请求。=/50x.html
仅匹配精确路径。
Nginx虚拟主机配置顺序
Nginx在处理基于名称的虚拟主机配置时遵循特定匹配顺序,确保请求能够被正确路由。当多个server_name
模式匹配同一个请求时,Nginx会按照以下优先级顺序选择配置:
- 精准匹配:完全匹配请求的
Host
头部的配置,例如server_name www.example.com;
。 - 左侧通配符:以
*
开头的通配符模式,例如server_name *.example.com;
。 - 右侧通配符:以
*
结尾的通配符模式,例如server_name www.example.*;
。 - 正则表达式:使用正则表达式定义的复杂模式,例如
server_name ~^www\.example\..*$;
。
如果以上均未匹配,Nginx会使用默认的server
块(通常是配置文件中第一个定义的server
块或标记为default_server
的块)。
配置示例说明
以下代码片段展示了Nginx虚拟主机的典型配置结构,重点关注server_name
的匹配逻辑:
server {
listen 80;
server_name www.nginx.cn; # 精准匹配
root /html;
}
server {
listen 80;
server_name *.nginx.cn; # 左侧通配符
root /wildcard_left;
}
server {
listen 80;
server_name www.nginx.*; # 右侧通配符
root /wildcard_right;
}
server {
listen 80;
server_name ~^www\.nginx\..*$; # 正则表达式
root /regex;
}
问题答案
根据上述规则,Nginx虚拟主机的配置顺序为:
C 精准匹配,左侧通配符、右侧通配符、正则表达式
关键配置项解析
-
精准匹配
Nginx优先选择与请求完全一致的server_name
,例如请求Host: www.nginx.cn
会匹配server_name www.nginx.cn;
。 -
通配符优先级
左侧通配符(如*.nginx.cn
)优先级高于右侧通配符(如www.nginx.*
),因为左侧通配符通常用于子域名路由,更具明确性。 -
正则表达式
正则表达式用于复杂匹配场景,但优先级最低。例如~^www\.nginx\..*$
会匹配类似www.nginx.test
的域名。
性能优化建议
- 避免过度使用正则表达式,因其匹配开销较大。
- 对于高频访问的域名,优先使用精准匹配提升效率。
- 使用
default_server
明确标记默认处理块,避免意外路由。
完整案例
#运行用户
user nobody;
#启动进程,通常设置成和cpu的数量相等
worker_processes 1;
#全局错误日志及PID文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/Nginx.pid;
#工作模式及连接数上限
events {
#epoll是多路复用IO(I/O Multiplexing)中的一
种方式,
#仅用于linux2.6以上内核,可以大大提高Nginx的性
能
use epoll;
#单个worker进程的最大并发链接数 worker_connections 1024;
# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围
#之内
# 所以,worker_connections 的值需根据worker_processes 进程数目和系统可以打开的最大文件总数 # 进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
# ulimit -SHn 65535
}
http {
#设定mime类型,类型由mime.type文件定义
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 logs/access.log main;
#sendfile 指令指定 Nginx 是否调用 sendfile函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
#开启gzip压缩
gzip on;
gzip_disable "MSIE [1-6].";
#设定请求缓冲
client_header_buffer_size 128k;
large_client_header_buffers 4 128k;
#设定虚拟主机配置
server {
#侦听80端口
listen 80;
#定义使用 www.Nginx.cn访问
server_name www.Nginx.cn;
#定义服务器的默认网站根目录位置(编译的时候--prefix是整个Nginx的根目录,这里的html文件夹是相对--#prefix的路径)
root html;
#设定本虚拟主机的访问日志
access_log logs/Nginx.access.log
main;
#默认请求
location / {
#定义首页索引文件的名称
index index.php index.html
index.htm;
}
# 定义错误提示页面
error_page 500 502 503 504
/50x.html;
location = /50x.html {
}
# 静态文件,Nginx自己处理
location ~
^/(images|javascript|js|css|flash|media|sta
tic)/ {
#过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
expires 30d;
}
# PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
# 禁止访问 .htxxx 文件
location ~ /.ht {
deny all;
}
}
}
十一、Nginx配置指令详解_location指令
1. location 指令的作用
location
指令用于匹配用户请求的 URI,并对特定的请求进行处理。它提供了灵活的匹配规则,支持精确匹配、前缀匹配、正则表达式匹配等。
2. 常见的匹配类型
2.1 精确匹配
使用 =
符号可以实现精确匹配,只有当请求的 URI 完全匹配时才会触发该规则。
nginx
location = /50x.html {
root /nginx/html;
}
上述配置表示只有当请求的 URI 是 /50x.html
时,才会匹配到这个规则。
2.2 前缀匹配
默认情况下,location
使用前缀匹配,即匹配以指定字符串开头的 URI。
nginx
location /images/ {
root /var/www/html;
}
上述配置表示所有以 /images/
开头的请求都会被匹配到这个规则。
2.3 正则表达式匹配
使用 ~
(区分大小写)或 ~*
(不区分大小写)可以进行正则表达式匹配。
nginx
location ~* \.(css|js|jpg|jpeg|png|gif|ico)$ {
root /var/www/html; expires 30d;
}
上述配置表示匹配所有以 .css
、.js
、.jpg
等后缀结尾的静态文件,并设置缓存时间为 30 天1。
2.4 使用 ^~
忽略正则表达式
如果某个前缀匹配规则需要优先于正则表达式匹配,则可以使用 ^~
。
nginx
location ^~ /static/ {
root /usr/local/nginx/html;
}
上述配置表示只要 URI 以 /static/
开头,就会直接匹配此规则,而不再检查正则表达式匹配规则。
3. 匹配优先级
Nginx 的 location
匹配遵循以下优先级:
- 精确匹配 (
=
) 具有最高优先级。 - 前缀匹配会按照定义顺序从上到下匹配,最后一个匹配的规则会被选中。
- 正则表达式匹配会在所有前缀匹配完成后进行,且只选择第一个匹配的规则。
- 如果没有匹配到任何规则,则使用默认的
location /
。
Location匹配规则详解
符号 | 匹配类型 | 含义 | 示例 |
---|---|---|---|
= | 精确匹配 | 仅匹配完全相同的路径,优先级最高 | location = /images/ { ... } |
~ | 正则匹配(区分大小写) | 使用正则表达式匹配路径,区分大小写 | location ~ \.(jpg|gif)$ { ... } |
~* | 正则匹配(不区分大小写) | 使用正则表达式匹配路径,不区分大小写 | location ~* \.(jpg|jif)$ { ... } |
^~ | 前缀匹配(停止搜索) | 匹配以指定路径开头的内容,匹配成功后不再检查其他正则规则(优先级高于正则) | location ^~ /images/ { ... } |
(无符号) | 普通前缀匹配 | 匹配以指定路径开头的内容,但优先级低于正则和精确匹配 | location / { ... } |
- 优先级顺序:
=
>^~
>~
/~*
> 无符号前缀匹配。 - 正则匹配:
~
和~*
需注意正则表达式的语法(如转义字符\.
)。 - 性能影响:频繁的正则匹配可能影响性能,建议合理使用
^~
或=
优化。
# 示例配置片段
location = /logo.png {
# 仅匹配 /logo.png
}
location ^~ /static/ {
# 匹配以 /static/ 开头的路径,停止后续正则检查
}
location ~* \.(png\|jpg)$ {
# 匹配所有 .png 或 .jpg(不区分大小写)
}
4. root
和 alias
的区别
root
指令用于指定文件的根目录,然后在根目录下拼接请求的 URI 来定位文件。alias
指令用于将请求的 URI 映射到服务器上的另一个路径。
# 使用 root
location /images/ {
root /var/www/html;
}
# 访问 /images/1.jpg 时,实际路径为 /var/www/html/images/1.jpg
# 使用 alias
location /images/ {
alias /var/www/pictures/;
}
# 访问 /images/1.jpg 时,实际路径为 /var/www/pictures/1.jpg
5. 示例配置
以下是一个综合示例,展示了多种匹配规则的使用:
server {
listen 80;
server_name example.com;
# 精确匹配
location = /50x.html {
root /nginx/html;
}
# 前缀匹配
location /images/ {
root /var/www/html;
}
# 正则表达式匹配
location ~* \.(css|js|jpg|jpeg|png|gif|ico)$ {
root /var/www/html;
expires 30d;
}
# 默认匹配
location / {
root /var/www/html;
index index.html index.htm;
}
}
十二、虚拟主机的分类
概述
虚拟主机是一种先进的软硬件技术解决方案。它能够在单一物理服务器上创建多个独立的虚拟环境,每个虚拟环境都可作为完整的主机运行,单独提供WWW服务。通过这种技术,一台物理服务器就能同时承载多个网站,且各个虚拟主机之间完全隔离,互不干扰
Nginx支持三种类型的虚拟主机配置
基于IP的虚拟主机
基于端口的虚拟主机
基于域名的虚拟主机
十三、Nginx核心指令
以下整理Nginx的location
块核心指令及实际案例,按功能分类说明:
root与alias的区别
root:将匹配的URI附加到指定路径后
location /images/ {
root /data/static;
}
# 访问/images/a.jpg 实际文件路径:/data/static/images/a.jpg
alias:用指定路径完全替换匹配的URI
location /img/ {
alias /data/media/;
}
# 访问/img/a.jpg 实际文件路径:/data/media/a.jpg
return与rewrite
return:直接返回响应码或重定向
location /old {
return 301 https://example.com/new;
}
rewrite:修改URI并继续处理
location /blog {
rewrite ^/blog/(.*)$ /posts/$1 last;
}
# /blog/2024 → /posts/2024
if与set
if:条件判断(谨慎使用,可能引发性能问题)
location /admin {
if ($remote_addr != "192.168.1.1") {
return 403;
}
}
set:定义变量
location / {
set $cache_key "$host$request_uri";
proxy_cache_key $cache_key;
}
break与last
break:停止当前脚本阶段的rewrite处理
location /static {
rewrite ^ /assets/$uri break;
proxy_pass http://backend;
}
last:结束当前location并重新匹配
location / {
rewrite ^/old /new last;
try_files $uri $uri/ =404;
}
Gzip压缩配置
gzip on;
gzip_types text/plain application/json;
gzip_min_length 1000;
gzip_proxied any;
综合案例:静态资源处理
location ~* \.(jpg|css|js)$ {
root /data/assets;
expires 30d;
gzip_static on;
add_header Cache-Control "public";
}
location /api {
rewrite ^/api/v1/(.*) /$1 break;
proxy_pass http://backend;
}
Nginx 中变量的类型及解释
Nginx 变量分为内置变量(系统变量)和用户自定义变量。以下是这些变量的详细分类及解释:
1. 内置变量(系统变量)
内置变量由 Nginx 核心或模块提供,用于获取请求、响应或服务器的相关信息。
-
请求相关变量:
$uri
:当前请求的 URI,经过解码且不包含请求参数。$request_uri
:原始请求的 URI,未经解码且包含请求参数。$args
:请求中的查询字符串参数。$host
:请求头中的主机名。$http_user_agent
:客户端的 User-Agent 字段。$remote_addr
:客户端的 IP 地址。
-
文件路径相关变量:
$document_root
:当前请求的文档根目录。$realpath_root
:实际的文件系统路径。
-
响应相关变量:
$status
:HTTP 响应状态码。$sent_http_content_type
:响应的 Content-Type 头部字段。
-
其他变量:
$time_iso8601
:ISO 8601 格式的当前时间。$scheme
:请求的协议(如http
或https
)。
2. 用户自定义变量
用户自定义变量通过 set
指令创建并赋值,主要用于动态控制请求处理逻辑。
-
创建与赋值:
nginx
set $backend "http://127.0.0.1:8080"; # 创建并赋值一个变量
-
用户自定义变量只能在 Nginx 配置加载时声明,而赋值操作则发生在请求处理阶段。
-
使用场景:
- 动态代理目标地址:
nginx location /api/ { set $target "http://backend.example.com"; proxy_pass $target; }
- 条件判断结合
if
:nginx set $flag "true"; if ($flag = "true") { return 200 "Flag is true"; }
- 动态代理目标地址:
3. 变量的生命周期与作用域
-
生命周期: Nginx 变量的生命周期与当前请求绑定,一旦请求结束,变量也会被销毁。
-
作用域: 变量的作用域不限于特定的
location
块,可以在整个请求处理过程中跨块使用。
4. 示例代码
以下是一个综合使用内置变量和用户自定义变量的示例配置:
server {
listen 80;
server_name example.com;
# 使用内置变量
access_log /var/log/nginx/access.log main buffer=32k flush=5s if=$loggable;
location / {
set $loggable "1"; # 自定义变量
if ($request_uri ~* "/no-log/") {
set $loggable ""; # 禁用日志记录
}
echo "Host: $host";
echo "URI: $uri";
echo "Args: $args";
echo "Custom Log Flag: $loggable";
}
}
Nginx场景实践
1.浏览器缓存
概述
浏览器缓存是浏览器为提高浏览速度而采用的一种技术机制。其原理是将用户最近访问过的网页文件存储在本地磁盘中。当用户再次请求相同页面时,浏览器可以直接从本地加载内容,从而显著提升页面加载速度。这种缓存机制不仅优化了用户体验,还减少了网络资源消耗,提高了整体网络效率。
实现浏览器缓存步骤
1. 配置静态资源的浏览器缓存
对于常见的静态资源(如图片、CSS、JavaScript 文件),可以通过设置 expires
和 Cache-Control
头信息来实现浏览器缓存。
nginx
location ~* \.(jpg|jpeg|png|gif|css|js)$ {
expires 7d; # 设置缓存过期时间为 7 天
add_header Cache-Control "public, must-revalidate"; # 添加缓存控制头
access_log off; # 禁用访问日志以优化性能
}
2. 动态内容的缓存控制
对于动态生成的内容(如 HTML 页面或 API 响应),可以使用 add_header
指令来指定不同的缓存策略。
location / {
add_header Cache-Control "no-store, no-cache, must-revalidate"; # 禁止缓存动态内容
proxy_pass http://backend_server;
}
3. 使用 Nginx 缓存与浏览器缓存结合
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g;
server {
listen 80;
server_name example.com;
location /static/ {
proxy_cache my_cache; # 启用 Nginx 缓存
proxy_cache_valid 200 302 1h; # 对于状态码 200 和 302,缓存有效期为 1 小时
proxy_cache_valid 404 1m; # 对于 404 错误,缓存有效期为 1 分钟
add_header X-Proxy-Cache $upstream_cache_status; # 输出缓存状态到响应头
expires 1h; # 设置浏览器缓存时间为 1 小时
}
}
2.防盗链
防盗链的概念
内容不在自己的服务器上,通过技术手段将其他网站的内容(比如 一些音乐、图片、软件的下载地址)放置在自己的网站中,通过这 种方法盗取其他网站的空间和流量。
防盗链技术背景
防止第三方引用链接访问我们的图片,消耗服务器资源和网络流量,我们可以在服务器上做防盗链限制
防盗链设置思路
首要方式:区别那些请求是非正常的用户请求。

基于http_refer防盗链配置模块
HTTP Referer是HTTP请求头的一部分。当浏览器向Web服务器发送请求时,通常会自动携带Referer字段,用于告知服务器请求的来源页面。服务器可以利用这些信息进行相关处理。例如,当用户从我的主页点击链接访问朋友网站时,对方的服务器就能通过HTTP Referer统计出每天有多少用户通过我的主页跳转访问其网站
valid_referers none blocked 192.168.66.100;
if ($invalid_referer) {
return 403;
}
参数说明:
none
:允许无 HTTP 来源(http_refer)的请求访问资源blocked
:允许非标准协议(非http://开头)或无协议的请求访问资源192.168.66.100
:仅允许来自该指定 IP 的请求访问资源
以下是一个完整的 Nginx 配置示例,展示如何实现 valid_referers
和 IP 限制的逻辑:
配置示例
server {
listen 80;
server_name example.com;
location /protected/ {
valid_referers none blocked 192.168.66.100;
if ($invalid_referer) {
return 403;
}
# 允许特定IP访问(可选叠加)
allow 192.168.66.100;
deny all;
# 实际处理逻辑
root /var/www/protected;
index index.html;
}
}
关键点说明
-
valid_referers
规则none
: 允许直接通过URL访问(无Referer头)blocked
: 允许被防火墙/代理修改过的Referer192.168.66.100
: 允许来自该IP的Referer
-
IP白名单
allow/deny
指令进一步限制只允许特定IP访问(与Referer检查独立) -
测试方法
# 有效访问(无Referer)
curl http://example.com/proprotected/
# 有效访问(来自白名单IP的Referer)
curl -H "Referer: http://192.168.66.100" http://example.com/proprotected/
# 无效访问(触发403)
curl -H "Referer: http://attacker.com" http://example.com/proprotected/
典型应用场景
- 防止盗链图片/文件
- 限制API只能通过特定前端调用
- 保护管理后台的静态资源
3.代理服务
正向代理
正向代理,是在用户端的。比如需要访问某些国外网站,我们可能需要购买vpn。
正向代理的主要特性:
- 客户端明确知晓目标服务器的地址
- 服务器仅能识别请求来自代理服务器,无法追踪具体客户端
- 该模式有效保护了真实客户端的隐私信息
反向代理
当客户端向服务器发送请求时,nginx服务器接收该请求并根据预设规则将请求分发至后端业务处理服务器。在这个流程中,虽然请求来源(客户端)是明确的,但具体由哪台后端服务器处理则被隐藏了,此时nginx就充当了反向代理的角色。
反向代理主要应用于服务器集群的分布式部署场景,其核心作用在于隐藏后端服务器的具体信息。
4.反向代理
单体架构
单体架构问题
- 复杂度高:模块数量多且边界模糊,代码质量参差不齐,开发过程中频繁修改代码存在较大风险
- 技术债务累积:随着需求变更和人员更替,技术债务不断积累且难以消化
- 部署效率低:代码规模增长导致构建和部署时间延长,每次发布都需要全量部署整个应用
- 稳定性风险:单个模块的缺陷可能引发整个系统崩溃
- 扩展性不足:只能进行整体扩展,无法针对特定业务模块独立伸缩
反向代理设置指令
掌握Nginx服务器的反向代理服务配置,特别是与后端代理服务器相关的关键配置指令,是确保Web服务正常运行的基础。其中,proxy_pass指令尤为重要,在实际应用中需特别注意其配置细节。
proxy_pass指令: 用于指定被代理服务器的地址,支持域名、IP地址加端口号等多种形式。
参数: proxy_pass URL;
URL指定被代理服务器的地址,需包含以下要素:
- 传输协议(通常为"http://"或"https://")
- 主机名或IP地址
- 端口号(可选)
- URI路径
server{
....
listen 80;
server_name *.*;
location / {
proxy_pass http://192.168.66.101:8080;
}
}
以下是关于 proxy_pass
的具体案例及说明:
基本语法格式
location /path {
proxy_pass URL;
}
其中 URL
需包含传输协议、主机名/IP地址、端口号(可选)和 URI 路径。
案例 1:完整 URL 代理
将请求代理到后端 HTTP 服务,包含协议、主机、端口和路径:
location /api {
proxy_pass http://backend.example.com:8080/v1;
}
当访问 /api/users
时,实际代理到 http://backend.example.com:8080/v1/users
。
案例 2:省略端口(默认 80)
若后端服务使用默认 HTTP 端口 80:
location /static {
proxy_pass http://cdn.example.com/res;
}
访问 /static/img.png
将被转发到 http://cdn.example.com/res/img.png
。
案例 3:HTTPS 协议代理
代理到 HTTPS 后端服务:
location /secure {
proxy_pass https://api.example.com:443/data;
}
案例 4:本地 Unix 套接字
通过 Unix 域套接字代理:
location /internal {
proxy_pass http://unix:/tmp/backend.sock:/;
}
路径替换逻辑解析
在Nginx的proxy_pass
配置中,路径末尾是否包含/
会直接影响请求URI的传递方式。以下是两种情况的对比及示例:
情况1:proxy_pass
末尾带/
location /foo {
proxy_pass http://backend:8080/bar/;
}
行为:
当访问/foo/test
时,/foo
会被替换为/bar/
,最终传递给后端服务器的URI是/bar/test
。路径中的/foo
前缀被完全移除。
适用场景:
需要将特定前缀路径完全替换为新路径时使用,例如API网关的路径重写。
情况2:proxy_pass
末尾不带/
location /foo {
proxy_pass http://backend:8080/bar;
}
行为:
当访问/foo/test
时,Nginx会将/foo
替换为/bar
,但保留原始路径的其余部分,最终URI为/bar/foo/test
。此时/foo
成为/bar
的子路径。
适用场景:
需要保留原始路径结构时使用,例如反向代理到不同服务的子目录。
关键区别总结
- 带
/
:原路径前缀(/foo
)被完全丢弃,后续路径直接拼接。 - 不带
/
:原路径前缀(/foo
)被保留,成为目标路径的子路径。
实际案例
案例1:完整路径替换
location /api {
proxy_pass http://backend:8080/v2/;
}
访问/api/users
→ 后端收到/v2/users
案例2:路径追加
location /static {
proxy_pass http://cdn:80;
}
访问/static/img.png
→ 后端收到/static/img.png
(路径未截断)
进阶用法:正则路径匹配
location ~ ^/old/(.*) {
proxy_pass http://backend:8080/new/$1;
}
使用正则捕获组实现动态路径替换,访问/old/page
→ 后端收到/new/page
5.负载均衡
负载均衡是一种关键的网络基础设施技术,其核心作用是将工作任务智能分配到多个服务器上。这种机制可以有效提升网站、应用程序、数据库等各种服务的运行效率与系统稳定性。
没有负载均衡的 web 架构
有负载均衡web架构:
上游指令
upstream
块不属于虚拟主机配置,必须放置在http
块内。该指令用于定义反向代理时Nginx需要连接的后端服务器集群及其负载均衡策略
上游服务器参数说明:
- max_conns:单个节点的最大并发连接数
- slow_start:节点加入负载均衡后的缓慢启动时间
- down:标记节点为不可用状态
- backup:将节点设置为备用服务器
- max_fails:允许的最大失败请求次数
- fail_timeout:超过最大失败次数后的暂停服务时间
配置解析:Nginx upstream与server模块
upstream back_end {
ip_hash; # 会话保持(按客户端IP分配)
server 192.168.66.100 max_conns=2 max_fails=3 fail_timeout=10s;
server 192.168.66.101 weight=2; # 权重更高
server 192.168.66.102;
}
server {
listen 80;
server_name example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://back_end;
}
}
upstream块定义后端服务器集群
upstream back_end {
server 192.168.66.100 max_conns=2 fail_timeout=1s;
server 192.168.66.101 weight=1;
server 192.168.66.102 weight=1;
}
back_end
为自定义的upstream名称,用于后续proxy_pass引用。server
指令定义3台后端服务器:192.168.66.100
:限制最大连接数为2(max_conns
),故障超时1秒(fail_timeout
)。192.168.66.101
和192.168.66.102
:权重均为1(默认轮询负载均衡)。
- 未指定负载均衡算法时,默认使用加权轮询(weighted round-robin)。
server块处理客户端请求
server {
listen 80;
server_name *.*;
location / {
proxy_set_header Host $host;
proxy_pass http://back_end;
}
}
listen 80
:监听80端口。server_name *.*
:匹配所有域名(实际建议明确域名)。location /
:将所有路径请求转发到upstream。proxy_set_header Host $host
:保留原始请求的Host头。proxy_pass http://back_end
:请求代理到back_end
集群。
关键参数说明
max_conns
:限制单台服务器最大并发连接数,防止过载。fail_timeout
:标记服务器不可用的超时时间(需配合max_fails
使用,但此处未设置)。weight
:权重越高,分配的请求比例越大(本例均为1,请求均匀分配)。
注意事项
- 实际部署时应明确
server_name
而非使用通配符*.*
。 - 建议添加健康检查机制(如
health_check
模块或第三方方案)。 - 若需会话保持,可加入
ip_hash
或sticky
指令。
负载均衡算法
以下是Nginx负载均衡算法的场景实践分析,涵盖常见算法原理、配置示例及适用场景:
轮询(Round Robin)
默认算法,按顺序分配请求到后端服务器,适合服务器性能相近的场景。
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
加权轮询(Weighted Round Robin)
通过权重分配流量,适合服务器配置不均衡的环境。
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=1;
}
IP哈希(IP Hash)
根据客户端IP分配固定服务器,保持会话一致性。
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
最少连接(Least Connections)
优先选择当前连接数最少的服务器,适合长连接场景。
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
响应时间优先(Fair)
根据后端响应时间动态分配(需第三方模块)。
upstream backend {
fair;
server backend1.example.com;
server backend2.example.com;
}
关键场景选择建议:
- 会话保持需求优先IP哈希
- 动态负载适应选最少连接
- 文件服务建议URL哈希
- 默认测试用轮询或加权轮询
6.故障转移
当上游服务器(即实际处理请求的服务器)出现故障或未能及时响应时,系统应自动轮询切换至备用服务器,以确保服务的高可用性。
server {
listen 80;
server_name www.itmayiedu.com;
location / {
# 指定上游服务器负载均衡服务器
proxy_pass http://backServer;
#故障转移的条件:如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均
#衡池中的另一台服务器,实现故障转移。
proxy_next_upstream http_502 http_504 error timeout invalid_header;
#nginx与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_connect_timeout 1s;
#nginx发送给上游服务器(真实访问的服务器)超时时间
proxy_send_timeout 1s;
#nginx接受上游服务器(真实访问的服务器)超时时间
proxy_read_timeout 1s;
index index.html index.htm;
}
}
Nginx故障转移配置解析
Nginx的故障转移技术主要通过proxy_next_upstream
指令实现,当后端服务器响应异常时自动切换到其他可用服务器。以下是相关配置的详细说明:
server {
listen 80;
server_name www.itmayiedu.com;
location / {
proxy_pass http://backServer;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_connect_timeout 1s;
proxy_send_timeout 1s;
proxy_read_timeout 1s;
index index.html index.htm;
}
}
关键指令说明
proxy_next_upstream
:定义触发故障转移的条件,常见参数包括:
http_502
:后端返回502错误码http_504
:后端返回504错误码error
:与服务器建立连接/发送请求/读取响应时出错timeout
:发生超时invalid_header
:服务器返回空或无效响应
超时控制参数:
proxy_connect_timeout 1s; # 与后端服务器建立连接的超时时间
proxy_send_timeout 1s; # 发送请求到后端的超时时间
proxy_read_timeout 1s; # 读取后端响应的超时时间
实现原理
当Nginx检测到以下情况时会触发故障转移:
- 连接后端服务器失败
- 发送请求到后端超时
- 读取响应头部超时
- 后端返回特定错误码(如502/504)
- 后端返回无效响应
此时请求会自动转发到upstream中的其他服务器,直到尝试完所有可用服务器或收到正常响应。
7.跨域问题
跨域问题的产生源于浏览器的同源策略限制。同源策略是浏览器最基本的安全机制,旨在维护网络安全。如果缺乏这一策略,浏览器的正常运行将受到严重影响。可以说,现代Web生态正是建立在同源策略的基础之上,而浏览器只是这一安全标准的具体实现者。
跨域的定义是:当请求 URL 的协议、域名或端口中任意一项与当前页面 URL 不同时,即构成跨域。
以下是跨域请求的常见场景及原因分析表格:
当前页面 URL | 被请求页面 URL | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口号不同(8080/7001) |
跨域判定标准由浏览器同源策略(Same-Origin Policy)定义,需同时满足以下三点:
- 协议相同(如
http
/https
) - 域名相同(包括子域名)
- 端口号相同(默认端口需一致)
跨域问题示例
跨域问题是由于浏览器同源策略限制导致的一种常见现象。当从一个域名的网页去请求另一个域名的资源时,如果没有正确的CORS设置,就会出现跨域错误。
// 前端示例代码(假设运行在http://localhost:3000)
fetch('http://api.example.com/data', {
method: 'GET'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
常见跨域报错
浏览器控制台可能出现的错误信息:
Access to fetch at 'http://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Nginx代理解决方案
通过Nginx反向代理解决跨域:
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
}
配置说明
Access-Control-Allow-Origin *
: 允许所有来源的请求访问资源。如果仅需允许特定域名,可以将 *
替换为域名,例如 https://example.com
。
Access-Control-Allow-Methods
: 定义允许的 HTTP 方法,如 GET
、POST
和 OPTIONS
。可根据需求扩展为 PUT
、DELETE
等。
Access-Control-Allow-Headers
: 列出允许的请求头,包括 Content-Type
、Authorization
等自定义头。
OPTIONS
预处理请求: 对于 OPTIONS
请求(预检请求),直接返回 204 No Content
状态码,避免不必要的处理。
应用场景
该配置适用于需要跨域访问的 API 或静态资源,例如:
- 前端应用与后端 API 分离部署。
- 允许第三方网站调用开放接口。
- 提供跨域静态资源(如字体、图片)。
安全性建议
允许所有来源(*
)适用于开放 API,但在生产环境中建议限制为特定域名以提高安全性。例如:
add_header Access-Control-Allow-Origin https://example.com;
8.动静分离
Nginx动静分离的核心是将动态请求与静态请求进行区分处理。具体而言,它并非简单地分离动态页面和静态页面的物理存储位置,而是通过Nginx处理静态资源请求,同时将动态请求转发给Tomcat等后端服务进行处理
动静分离概念解释
动静分离是指将动态请求和静态资源请求分开处理,通常通过Nginx将静态资源(如HTML、CSS、JS、图片等)直接返回,而动态请求(如API、数据库查询)则转发给后端服务器(如Tomcat、PHP-FPM)。这种架构能显著提升服务器性能,降低后端压力。
核心优势:
- 静态资源由Nginx直接处理,响应速度快
- 动态请求交由专业后端处理,分工明确
- 减少后端服务器的I/O负载
- 更高效的缓存策略实施
upstream webservers {
server 192.168.66.101:8080 weight=5;
server 192.168.66.102:8080 weight=5;
}
server {
listen 80;
server_name *.*;
location / {
root html;
index index.html index.htm;
proxy_set_header Host $host;
proxy_pass http://webservers;
}
location ~ .*.(jpg|png|gif|css|js)$
{
root static;
}
}
}
配置结构解析
该配置是一个Nginx的负载均衡和反向代理示例,主要分为两部分:upstream
模块和server
模块。
upstream模块
upstream webservers {
server 192.168.66.101:8080 weight=5;
server 192.168.66.102:8080 weight=5;
}
- 定义了一个名为
webservers
的负载均衡组。 - 包含两台后端服务器:
192.168.66.101:8080
和192.168.66.102:8080
。 weight=5
表示两台服务器的权重相同,流量将均分。
server模块
server {
listen 80;
server_name *.*;
location / {
root html;
index index.html index.htm;
proxy_set_header Host $host;
proxy_pass http://webservers;
}
location ~ .*.(jpg|png|gif|css|js)$ {
root static;
}
}
- 监听80端口,匹配所有域名(
server_name *.*
)。 - 包含两个
location
块:- 第一个
location /
处理所有请求:root html
指定静态文件根目录。index
定义默认索引文件。proxy_set_header Host $host
保留原始请求的Host头。proxy_pass http://webservers
将请求转发到upstream webservers
组。
- 第二个
location
用正则匹配静态文件(图片、CSS、JS等):root static
表示这些文件从static
目录直接读取,不经过后端服务器。
- 第一个
Nginx配置动静分离案例
基础目录结构
假设项目目录结构如下:
/data/www/
├── static/ # 静态资源
│ ├── css/
│ ├── js/
│ └── images/
└── index.php # 动态脚本
典型配置示例
server {
listen 80;
server_name example.com;
root /data/www;
location / {
index index.html index.php;
}
# 静态资源处理
location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
expires 30d;
access_log off;
add_header Cache-Control "public";
try_files $uri =404;
}
# 动态请求处理
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
进阶优化配置
# 静态资源压缩
gzip_static on;
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 动态请求超时设置
location ~ \.php$ {
fastcgi_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
}
性能调优参数
# 静态文件缓存控制
location ~* \.(woff2?|ttf|eot|svg|otf)$ {
expires 365d;
access_log off;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
# 启用sendfile提高性能
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
常见问题解决方案
跨域处理
location /api/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
}
防盗链配置
location ~* \.(jpg|png|gif)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
通过以上配置可实现高效的动静分离架构,静态资源响应时间可缩短至毫秒级,同时保证动态请求的正常处理。实际部署时应根据具体业务需求调整缓存时间和路径匹配规则。
9.缓存机制
核心:
响应速度一直是评估Web应用和服务性能的关键指标,尤其在当前动态网站盛行的网络环境下。除了优化发布内容外,另一个有效解决方案是将无需实时更新的动态页面输出结果缓存为静态网页,从而提高访问效率。
proxy Cache缓存机制
Proxy Cache缓存机制详解
Proxy Cache是一种常见的网络缓存技术,主要用于减轻服务器负载、提高访问速度和节省带宽。以下是详细的案例说明。
缓存基本原理
Proxy Cache通过存储客户端请求的资源副本,当后续有相同请求时直接返回缓存内容,避免重复向源服务器请求。主要适用于静态资源如HTML、CSS、JS、图片等。
缓存配置案例(Nginx为例)
在nginx.conf文件中添加以下缓存配置:
http {
......
proxy_cache_path /data/nginx/tmp-test
levels=1:2
keys_zone=tmp-test:100m
inactive=7d
max_size=1000g;
}
配置参数说明:
proxy_cache_path
:指定缓存文件存储路径levels
:设置缓存目录层级(1:2表示两级目录结构)keys_zone
:定义缓存名称和共享内存大小inactive
:设置缓存文件的自动清理时间(7天内未被访问将被删除)max_size
:限定最大缓存容量(达到上限后将自动清理最旧缓存)配置完成后重启Nginx服务,若无报错则缓存功能即生效。可通过检查
/data/nginx/
目录确认,系统将自动生成tmp-test
缓存文件夹。
location /tmp-test/ {
proxy_cache tmp-test;
proxy_cache_valid 200 206 304 301 302 10d;
proxy_cache_key $uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_pass
http://127.0.0.1:8081/media_store.php/tmptest/;
}
参数说明:
Proxy_cache tmp-test
指定使用名为"tmp-test"的缓存配置
proxy_cache_valid 200 206 304 301 302 10d
对HTTP状态码为200、206、304、301、302的响应设置10天缓存有效期
proxy_cache_key $uri
定义缓存唯一键值,通过URI进行哈希存储和访问
proxy_set_header
自定义HTTP请求头,用于传递给后端服务器
proxy_pass
设置代理转发路径,需注意末尾是否需要保留斜杠
需要主动清理缓存文件
location /tmp-test/ {
allow 127.0.0.1; //只允许本机访问
deny all; //禁止其他所有ip
proxy_cache_purge tmp-test $uri; //清
理缓存
}
10.限流实战
Nginx限流概述
Nginx限流通过控制请求速率或并发连接数,保护后端服务免受突发流量冲击。常见限流算法包括漏桶算法和令牌桶算法,实现方式主要依赖
limit_req_zone 用于控制单位时间内的请求频率和速率。
limit_req_conn 则用于限制并发连接数量。
限流配置方法
基于请求速率的限流
使用limit_req_zone
和limit_req
指令限制单位时间内的请求数。以下配置限制同一IP每秒最多10个请求:
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=req_limit burst=20 nodelay;
proxy_pass http://backend;
}
}
}
- $binary_remote_addr: 限制同一客户端IP地址
- zone=mylimit:10m: 存储访问频次信息(分配10MB内存空间)
- rate=1r/s: 控制客户端访问频率(每秒1次,可调整为如30r/m等形式
zone=one
指定使用哪个限流配置区域,需与limit_req_zone中定义的name保持一致。burst=5
定义突发请求缓冲容量为5。当请求量超过限流阈值时,超出的请求可暂存至该缓冲区。nodelay
该参数开启时:
- 若请求超过限流阈值且缓冲区已满,立即返回503错误
- 未开启时:所有请求将进入排队等待状态
基于连接数的限流
使用limit_conn_zone
和limit_conn
限制同一IP的并发连接数:
http {
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location /download/ {
limit_conn conn_limit 5;
proxy_pass http://backend;
}
}
}
zone=conn_limit:10m
:10MB内存存储连接状态。limit_conn 5
:每IP最多5个并发连接。
实际案例
案例1:API接口防刷
场景:防止恶意用户高频调用登录接口。
解决方案:
http {
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=2r/s;
server {
location /api/login {
limit_req zone=login_limit burst=5 nodelay;
proxy_pass http://auth_service;
}
}
}
效果:同一IP每秒仅允许2次登录请求,突发不超过5次。
案例2:下载服务限速
场景:限制每个用户的下载并发连接数。
解决方案:
http {
limit_conn_zone $binary_remote_addr zone=download_limit:10m;
server {
location /files/ {
limit_conn download_limit 3;
limit_rate 500k; # 限制单个连接下载速度为500KB/s
proxy_pass http://storage;
}
}
}
效果:每IP最多3个并发下载,且每个连接限速500KB/s。
高级配置技巧
- 白名单设置:排除内网IP或信任IP。
geo $limit {
default 1;
192.168.0.0/24 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=dynamic_limit:10m rate=100r/s;
- 多维度限流:结合URI和IP。
limit_req_zone "$binary_remote_addr $uri" zone=uri_limit:10m rate=5r/s;
设置白名单
限流措施主要针对外部访问,内网访问由于安全性较高,无需进行限流限制,通过设置白名单机制即可实现。可以利用Nginx的ngx_http_geo_module和ngx_http_map_module这两个功能模块轻松完成配置
查看是否具有该功能
./configure --help |grep
http_limit_req_module
./configure --help |grep http_geo_module
./configure --help |grep http_map_module
在 nginx.conf 的 http 部分中配置白名单:
#
geo $limit {
default 1;
39.100.243.125 0;
192.168.0.0/24 0;
172.20.0.35 0;
}
map limit limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key
zone=myRateLimit:10m rate=10r/s;
参数说明:
geo功能:
- 对于白名单内的子网或IP地址,返回值为0
- 其他IP地址则返回1
map功能:
- 将limit值转换为limit_key
- 当$limit值为0(白名单)时,返回空字符串
- 当$limit值为1时,返回客户端实际IP地址
limit_req_zone功能:
- 限流key不再使用固定值binary_remote_addr
- 改为使用动态获取的limit_key
- 白名单用户(limit_key为空字符串)不受限流限制
- 非白名单用户将对其真实IP地址进行限流
11. Nginx高可用
什么是高可用?
高可用性(High Availability,简称HA)是分布式系统架构设计中的关键要素,其核心目标是通过合理设计最大限度减少系统服务中断时间。理想状态下,系统应能持续提供100%的可用服务,但考虑到现实中可能出现的各种意外情况,我们的设计目标实际上是尽可能降低服务故障的发生概率和影响程度
解决的问题
在生产环境中,Nginx常被用作反向代理对外提供服务。然而服务器难免会出现故障(如宕机),一旦Nginx服务中断,所有对外接口都将无法访问。虽然无法确保100%的服务可用性,但我们可以采取措施避免这类问题。我们使用keepalived实现Nginx的高可用方案。
双机热备方案 这是国内企业最常用的高可用性解决方案。双机热备由两台服务器组成:一台作为主服务器提供实时服务,另一台作为备用服务器处于待命状态。当主服务器出现故障时,备用服务器会自动接管服务,确保业务连续性。
企业级案例
user nginx;
worker_processes auto;
# 文件描述符限制
worker_rlimit_nofile 65536; # 设置所有 worker 进程能打开的文件数量上限[^3]
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
worker_connections 1024; # 每个 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;
types_hash_max_size 2048;
# SSL/TLS 配置
ssl_protocols TLSv1.2 TLSv1.3; # 启用安全协议版本
ssl_prefer_server_ciphers on;
# 缓存路径配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g; # 定义缓存路径和参数[^4]
# 负载均衡配置
upstream backend_servers {
server 192.168.1.10:8080 weight=5;
server 192.168.1.11:8080 weight=5;
server 192.168.1.12:8080 backup; # 定义后端服务器列表并设置权重和备份服务器[^2]
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://backend_servers; # 将请求转发到后端服务器
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt; # SSL 证书路径
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_session_cache shared:SSL:10m; # SSL 会话缓存配置
ssl_session_timeout 10m;
location / {
root /var/www/html;
index index.html index.htm;
}
}
# 静态资源缓存配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { # 匹配静态资源文件扩展名
expires 30d; # 客户端缓存30天
add_header Cache-Control "public"; # 允许所有缓存服务器缓存
access_log off; # 减少日志噪音[^4]
}
}