企业级 Web 服务 Nginx 基础
一、背景描述
1. Web 服务
数字化时代,互联网已经深度融入我们生活的方方面面。从日常浏览新闻资讯、社交娱乐,到在线购物、移动支付,再到企业的数字化转型和各种互联网应用的蓬勃发展,背后都离不开 Web 服务支撑。
想象一下,当你打开手机上的购物 App,轻松地浏览商品、下单购买,或者在电脑上登录社交媒体平台,与朋友互动交流。
这些看似简单的操作,实际上都涉及到复杂的网络交互过程。每一次你点击链接、提交表单,都是向远程服务器发送请求,而服务器则需要快速、准确地响应这些请求,将你所需的信息返回给你。
2. Nginx: Web 领域的明星
在众多提供 Web 服务的软件中,Nginx 凭借其卓越的性能和丰富的功能,成为了互联网行业的明星级工具。它是一款高性能的 HTTP 和反向代理 Web 服务器,同时也具备邮件代理服务器等功能。
事实上,许多知名的互联网公司,如腾讯、阿里巴巴、百度等,都在其业务中大量使用 Nginx 来处理海量的用户请求。
# curl -I 域名地址
Server:Nginx
比如, curl -I www.sina.com
curl -I www.taobao.com
3. URI vs URL
**URI(Uniform Resource Identifier,统一资源标识符):**广义概念,是用于唯一标识互联网上资源的字符串(如网页、图片、文件等),包含两种形式:URL 和 URN(URN 较少用,如书籍的 ISBN)。
**URL(Uniform Resource Locator,统一资源定位符):**是 URI 的子集,不仅标识资源,还指定了访问资源的具体路径 / 方式(如协议、服务器地址、端口等)。
二、相关介绍
Nginx官网:https://nginx.org/
Nginx (engine x) 是一个高性能的HTTP和反向代理Web服务器,同时也提供了IMAP/POP3/SMTP等邮件服务。其特点是占用内存少,并发能力强。
Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的。
第一个公开版本0.1.0发布于2004年10月4日,后来被美国的F5公司(硬件负载均衡厂商)收购。
1. 三大功能
HTTP 服务器
- 同类型 Web 服务器软件:Apache、Nginx(俄罗斯)、IIS(微软)、lighttpd(德国)
反向代理
接收客户端的请求,然后将这些请求转发到内部的多个服务器上进行处理,最后将处理结果返回给客户端。这就好比是一个“智能接待员”。
☆ 正向代理 vs 反向代理
正向代理

特点:知道自己使用了代理,需要填写代理服务器的IP等相关连接信息
场景:常见于代理客户端上网等操作(科学上网)
反向代理

特点:
用户是无感知的,不知道使用了代理服务器。
反向代理服务器是和真实访问的服务器是在一起的,有关联的。
作用:
① 可以根据实际业务需求,分发代理页面到不同的解释器
② 可以隐藏真实服务器的路径
- 场景:常见于代理后端服务器
负载均衡
当有大量的用户请求时,单台服务器可能无法承受如此大的压力。
Nginx的负载均衡功能可以将这些请求均匀地分配到多个后端服务器上,从而提高系统的整体处理能力和可靠性。这就像是一个“交通指挥官”。
负载均衡技术 (Load Balance,LB),其原理就是把用户请求分发到不同的服务器,使流量合理分配。
负载均衡作用:服务器容灾,流量分发
① 流量分发 请求平均 降低单例压力
② 安全 隐藏后端真实服务
③ 屏蔽非法请求(七层负载均衡)
http://www.itcast.cn/images/1.jpg => *.jpg图片 => 调度后端的图片服务器

2. 基本架构
Nginx的架构主要由一个**主进程(Master Process)和多个工作进程(Worker Processes)**组成。
- **主进程:**主进程主要负责管理Nginx的配置文件、启动和停止工作进程、重新加载配置等工作。它就像是一个“管理者”,负责整个Nginx系统的统筹和协调。
- **工作进程:**工作进程负责实际处理客户端的请求。多个工作进程可以并行处理多个请求,从而提高Nginx的并发处理能力。工作进程之间相互独立,互不影响,当某个工作进程出现故障时,不会影响其他工作进程的正常运行。
3. Nginx 特点
① 高可靠:稳定性 master 进程 管理调度请求分发到哪一个 worker -> worker 进程 响应请求一 master 多 worker
② 热部署:a. 平滑升级,b. 可以快速重载配置
③ 高并发:可以同时响应更多的请求 事件 epoll 模型 几万
④ 响应快:尤其在处理静态文件上,响应速度很快 sendfile
⑤ 低消耗:CPU 和内存 1W 个请求 内存 2~3MB
⑥ 分布式支持:反向代理 七层负载均衡,新版本也支持四层负载均衡
三、Nginx 安装部署
阿里源(可选)
cat >/etc/yum.repos.d/aliyun.repo<<EOF
[baseos]
name=CentOS Stream \$releasever - BaseOS
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/BaseOS/\$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=1
[baseos-debug]
name=CentOS Stream \$releasever - BaseOS - Debug
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/BaseOS/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[baseos-source]
name=CentOS Stream \$releasever - BaseOS - Source
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/BaseOS/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[appstream]
name=CentOS Stream \$releasever - AppStream
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/AppStream/\$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=1
[appstream-debug]
name=CentOS Stream \$releasever - AppStream - Debug
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/AppStream/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[appstream-source]
name=CentOS Stream \$releasever - AppStream - Source
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/AppStream/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[crb]
name=CentOS Stream \$releasever - CRB
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/CRB/\$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[crb-debug]
name=CentOS Stream \$releasever - CRB - Debug
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/CRB/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[crb-source]
name=CentOS Stream \$releasever - CRB - Source
baseurl=https://mirrors.aliyun.com/centos-stream/\$stream/CRB/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[highavailability]
name=CentOS Stream \$releasever - HighAvailability
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/HighAvailability/\$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[highavailability-debug]
name=CentOS Stream \$releasever - HighAvailability - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/HighAvailability/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[highavailability-source]
name=CentOS Stream \$releasever - HighAvailability - Source
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/HighAvailability/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[nfv]
name=CentOS Stream \$releasever - NFV
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/NFV/\$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[nfv-debug]
name=CentOS Stream \$releasever - NFV - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/NFV/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[nfv-source]
name=CentOS Stream \$releasever - NFV - Source
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/NFV/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[rt]
name=CentOS Stream \$releasever - RT
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/RT/\$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[rt-debug]
name=CentOS Stream \$releasever - RT - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/RT/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[rt-source]
name=CentOS Stream \$releasever - RT - Source
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/RT/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[resilientstorage]
name=CentOS Stream \$releasever - ResilientStorage
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/ResilientStorage/\$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[resilientstorage-debug]
name=CentOS Stream \$releasever - ResilientStorage - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/ResilientStorage/\$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[resilientstorage-source]
name=CentOS Stream \$releasever - ResilientStorage - Source
baseurl=http://mirrors.aliyun.com/centos-stream/\$stream/ResilientStorage/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[extras-common]
name=CentOS Stream \$releasever - Extras packages
baseurl=http://mirrors.aliyun.com/centos-stream/SIGs/\$stream/extras/\$basearch/extras-common/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=1
[extras-common-source]
name=CentOS Stream \$releasever - Extras packages - Source
baseurl=http://mirrors.aliyun.com/centos-stream/SIGs/\$stream/extras/source/extras-common/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
EOF
1. 常见安装方式
常见安装方式:
① yum 安装配置,需使用 Nginx 官方源或者 EPEL 源
② 源码编译
dnf/yum 安装 nginx
[root@server1 ~]# cat /etc/os-release
NAME="CentOS Stream"
VERSION="9"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="9"
PLATFORM_ID="platform:el9"
PRETTY_NAME="CentOS Stream 9"
ANSI_COLOR="0;31"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:centos:centos:9"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://issues.redhat.com/"
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 9"
REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream"
[root@server1 ~]# nginx -v
nginx version: nginx/1.20.1
[root@server1 ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
[root@server1 ~]# ls /usr/share/nginx/html/
baidu.html test-index-html.tar.gz 石头剪刀布游戏.html
index.html 星尘接接乐小游戏代码.html 随机猜数字游戏.html
[root@server1 ~]# netstat -pantul|grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 972/nginx: master p
tcp6 0 0 :::80 :::* LISTEN 972/nginx: master p
[root@server1 ~]#
源码编译安装 nginx
[root@server2 ~]# cat /etc/os-release
NAME="CentOS Stream"
VERSION="9"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="9"
PLATFORM_ID="platform:el9"
PRETTY_NAME="CentOS Stream 9"
ANSI_COLOR="0;31"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:centos:centos:9"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://issues.redhat.com/"
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 9"
REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream"
[root@server2 ~]# nginx -v
nginx version: nginx/1.30.1
[root@server2 ~]# cat /usr/local/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 引入conf.d目录下的所有子配置(关键)
include conf.d/*.conf;
}
[root@server2 ~]# ls /usr/local/nginx/html/
index.html itheimadevops opponent
[root@server2 ~]# ls /usr/local/nginx/html/
index.html itheimadevops opponent
[root@server2 ~]# netstat -pantul|grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 927/nginx: master p
[root@server2 ~]#
2. dnf 安装 nginx(重点)
dnf install epel-release -y # 让软件源更加完善,这一步操作可选
dnf install nginx -y
EPEL (Extra Packages for Enterprise Linux)
软件源中包含了许多额外的软件包
安装完成,验证测试
nginx -v
启动服务
systemctl start nginx
systemctl status nginx
systemctl enable nginx
打开浏览器,输入 Linux 主机的 IP 地址查看 Nginx 测试页
提示:dnf 安装的 nginx 网站根目录默认在/usr/share/nginx/html
测试页html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Nginx 测试页</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: #f5f5f5;
}
.container {
background: white;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
max-width: 500px;
margin: 0 auto;
}
h1 { color: #009639; }
.ok { color: green; font-size: 48px; }
</style>
</head>
<body>
<div class="container">
<div class="ok">✓</div>
<h1>Nginx 运行正常</h1>
<p>站点已成功搭建!</p>
<hr>
<p>服务器时间: <span id="time"></span></p>
</div>
<script>
document.getElementById('time').innerText = new Date().toLocaleString();
</script>
</body>
</html>
3. 源码编译安装 nginx(重点)
软件的编译安装过程:编译安装三步走(配置 + 编译 + 安装)
① 配置软件(预编译) ./configure
② 编译,生成可执行的软件包 make
③ 安装 make install
源码地址:https://nginx.org/en/download.html

或者也可以从 GitHub 上进行下载。


在 release 页面,可以看到最新发布的版本


在主页,可以看到【从源码构建】


3.1. ☆ 环境准备
# 第一步:卸载 dnf 包
[root@nginx ~] # dnf remove -y nginx
# 第二步:上传软件包到Linux当中
nginx-1.28.0.tar.gz
3.2. ☆ 第一步:安装依赖库
dnf install pcre-devel zlib-devel openssl-devel -y
Development Libraries,开发库,简写devel
3.3. ☆ 第二步:创建 nginx 账号
useradd -r -s /sbin/nologin nginx
3.4. ☆ 第三步:配置/编译与安装
安装gcc
yum install -y gcc
GCC 是 Linux 世界的“基础设施级工具”
它不仅是编译器,更是优化、调试、跨平台的核心工具
下载Nginx源码包
wget https://nginx.org/download/nginx-1.28.0.tar.gz
解压Nginx源码包
tar xvf nginx-1.28.0.tar.gz
预编译(环境检测 + 生成编译配置)
cd nginx-1.28.0
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module
源码编译及安装Nginx
make -j$(nproc) && make install
-j$(nproc) 多进程并行编译
-j 允许 make 同时执行多个任务
echo $(nproc) 返回 CPU 核心数
配置 Nginx 环境变量
echo 'PATH=$PATH:/usr/local/nginx/sbin/' >> /etc/profile && source /etc/profile
更改 /usr/local/nginx 目录权限
chown -Rf nginx:nginx /usr/local/nginx
查看 Nginx 版本信息
nginx -v
nginx -V
nginx -version
编译参数说明
| 参数 | 作用 |
|---|---|
| --prefix | 编译安装到的软件目录 |
| --user | worker进程运行用户 |
| --group | worker进程运行用户组 |
| --with-http_ssl_module | 支持https 需要pcel-devel依赖 |
| --with-http_stub_status_module | 基本状态信息显示 查看请求数、连接数等 |
| --with-http_realip_module | 定义客户端地址和端口为header头信息 常用于反向代理后的真实IP获取 |
3.5. 验证测试
安装完成后,你可以通过以下命令来管理 Nginx
# 启动
/usr/local/nginx/sbin/nginx
或者
nginx
然后使用以下命令来验证 Nginx 是否启动成功
# 查看 Nginx 进程
ps -ef | grep nginx
或者
ps aux | grep nginx
# 查看 Nginx 运行端口
netstat -pantul|grep nginx
打开浏览器,输入Nginx服务器IP地址
停止Nginx
# 停止
/usr/local/nginx/sbin/nginx -s quit
/usr/local/nginx/sbin/nginx -s stop
或者
nginx -s quit
nginx -s stop
3.6. 常见错误
1、端口占用

可以通过以下命令进行查看和停止Nginx
ps aux|grep nginx
nginx -s stop

2、依赖缺失

# 需要下载库
dnf install -y pcre-devel
3、编译报错
一般是下面的命令没执行
yum install pcre-devel zlib-devel openssl-devel -y
3.7. 配置 systemd 服务管理 nginx
CentOS Stream 9 配置:
# 注意:一定要提前把Nginx停止掉 ----省略操作
nginx -s stop
# Nginx服务配置到该文件中 ----省略操作
cat >/usr/lib/systemd/system/nginx.service <<EOF
[Unit]
Description=Nginx Web Server
After=network.target
[Service]
Type=forking
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
启动Nginx服务
systemctl daemon-reload
systemctl start nginx
systemctl status nginx
systemctl enable nginx
3.8. stop vs quit
思考:nginx -s stop 和 nginx -s quit 的区别?
stop:强制终止,会直接终止请求
quit:平滑停止,不中断现有连接,停止较慢
4. 目录和参数介绍
Nginx 的主要配置文件通常位于 /etc/nginx/nginx.conf
源码编译的一般在 /usr/local/nginx/conf/nginx.conf
提示:find / -name nginx.conf 快速查找 nginx.conf 配置文件
4.1. 软件目录
| 目录 | 作用 |
|---|---|
| conf | 配置文件(nginx.conf) |
| html | 网站默认目录 |
| logs | 日志(access.log、error.log) |
| sbin | 可执行文件 [软件的启动 停止 重启等] |
4.2. 操作参数
| 参数 | 作用 |
|---|---|
| -V | 显示Nginx版本号以及配置选项 |
| -s signal | stop关闭 quit优雅的关闭 reopen重开日志 reload重载 |
四、Nginx 企业级服务配置
1. nginx.conf 五大块
nginx.conf 存储位置有两种情况:
① dnf/yum 安装的,则通常在 /etc/nginx/nginx.conf ,查看存放命令
rpm -ql nginx
② 自定义安装,大多数都是位于 Nginx 软件安装目录
源码编译的 nginx 默认的配置文件位置:/usr/local/nginx/conf/nginx.conf
优化配置文件
dnf/yum 安装 nginx
[root@server1 ~]# cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
[root@server1 ~]# sed -i '/^\s*#/d; /^\s*$/d' /etc/nginx/nginx.conf
[root@server1 ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
[root@server1 ~]# wc -l /etc/nginx/nginx.conf
35 /etc/nginx/nginx.conf
[root@server1 ~]#
源码编译安装 nginx
[root@nginx ~]# cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak
[root@nginx ~]# sed -i '/^\s*#/d; /^\s*$/d' /usr/local/nginx/conf/nginx.conf
[root@nginx ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@nginx ~]# wc -l /usr/local/nginx/conf/nginx.conf
22 /usr/local/nginx/conf/nginx.conf
[root@nginx ~]#
# 或者通过vim删除空行和注释行
[root@nginx ~]# vim nginx.conf
:g/^#/d 删除注释行
:g/^$/d 删除空行
【正则表达式解释】
-
-E:Extend Expression,启用扩展正则表达式(支持更强大的元字符,如 | 表示或)。
-
-v:invert,反向匹配,即输出不匹配模式的行。
-
'#|^$':正则表达式,匹配两种情况:
-
- #:任意位置包含 # 的行(通常是注释)。
- ^:空行(^ 表示行首, 表示行尾,中间无内容,所以是空行)。
2. main 区块
全局块在配置文件的最外层,定义 Nginx 进程的全局运行参数,影响整个服务的底层行为。
user nginx; # 指定运行Nginx的工作进程用户(如nginx/www-data)
worker_processes auto; # 工作进程数(建议设为CPU核心数或auto自动适配)
error_log /var/log/nginx/error.log warn; # 错误日志路径及级别(debug/info/notice/warn/error/crit)
pid /var/run/nginx.pid; # Nginx主进程PID文件存放路径
# 其他全局参数(如性能调优)
worker_rlimit_nofile 65535; # 单个进程可打开的最大文件描述符数(需与系统ulimit一致)
3. events 区块
用于配置 Nginx 处理连接事件的底层机制(如多路复用、并发模型)。
控制 Nginx 与客户端/后端服务器之间的网络连接行为,直接影响高并发场景下的性能。
events {
worker_connections 1024; # 每个工作进程可同时处理的最大连接数(默认通常为512~1024)
use epoll; # 事件驱动模型(Linux推荐epoll,Mac/BSD用kqueue,Windows用select)
multi_accept on; # 是否允许单次事件循环接受多个新连接(默认off)
}
4. http 区块
包裹所有与 HTTP 协议相关的配置(如虚拟主机、路由、静态文件服务等)。
是 Nginx 作为 Web 服务器的核心模块,并包含多个 server 块(虚拟主机)。
1 http => N server => M location
一个配置文件中,有且只有一个 http 区块
http 区块中可以有多个 server 区块,每个 server 区块就相当于一个项目配置
1个 server 区块中可以有多个 location,每个 location 区块就相当于一个 url 链接匹配规则
http {
include /etc/nginx/mime.types; # 引入MIME类型映射文件(决定文件扩展名对应的Content-Type)
default_type application/octet-stream; # 默认MIME类型(当未匹配mime.types时使用)
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; # 仅在sendfile开启时有效,优化数据包发送
tcp_nodelay on; # 禁用Nagle算法,提升实时性(对小数据包友好)
keepalive_timeout 65; # 客户端长连接的超时时间(单位:秒)
# 包含多个server块(虚拟主机配置)
include /etc/nginx/conf.d/*.conf; # 通常将具体站点配置拆分到独立文件中
}
5. server & location 区块
关于这两个区块,我们单独重点讲解。
五、server 区块 (重点)
1. 基本字段
1 http => N server => N location
1个 Server 可以理解成一个独立的服务
每个 Loacation 相当于一个 URI 规则
Server 区块定义一个独立的Web服务实例(即“虚拟主机”),可监听端口或域名,实现多站点托管。
通过绑定域名/IP+端口,区分不同的网站服务(例如同时托管example.com和api.example.com)。
server {
listen 80; # 监听端口,默认为80
server_name localhost; # 绑定域名
root html;
location / {
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
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;
}
}
listen:监听端口,默认为80
server_name:很重要,可以绑定域名(使用最多)、可以绑定IP,localhost本机虚拟域名(即127.0.0.1)
root html:代表Nginx项目目录,从安装目录开始算起
当用户访问网站时,Nginx 会从该目录读取文件。
例如:
请求 /index.html → 实际读取 html/index.html
请求 /images/logo.png → 实际读取 html/images/logo.png
html 目录是 Nginx 自带的示例网站目录,在 /usr/local/nginx/html 下
location:url匹配规则
location = /50x.html精准匹配;
location ~ \.php$正则匹配;~表示区分大小写,\.表示对.转义,php$表示以php后缀结尾的
location / 代表如果刚才那些匹配规则都没有生效,则默认匹配location /
error_page 500 502 503 504 /50x.html:如果服务器端响应500、502、503、504,则自动跳转到/50x.html这个额错误页面
FastCGI(Fast Common Gateway Interface)是一种协议,
用于在Web 服务器(如 Nginx、Apache)和应用程序(如 PHP、Python)之间高效传递请求。
fastcgi_pass:请求转化给后面的地址
fastcgi_index:动态请求中的默认首页
fastcgi_param:参数设计,SCRIPT_FILENAME代表脚本名称。
$document_root代表root指定的项目目录;
$fastcgi_script_name请求的文件名称;
2. 基于域名虚拟机(重点)
在生产环境中,单台 Web 服务器有时需部署多个网站。
可通过搭建虚拟主机(vhost),将不同域名解析绑定至独立目录,实现多站点隔离部署。
http://www.ithuang666.com-> /usr/local/nginx/html/ithuang

案例:添加一个http://www.ithuang666.com
第一步:编辑nginx.conf,添加虚拟主机
server {
listen 80;
server_name www.ithuang666.com;
root /usr/local/nginx/html/ithuang; # 推荐使用绝对路径
location / {
# root html;
index index.html index.htm;
}
...
}
[root@server1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@server1 ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name www.ithuang666.com;
root /usr/local/nginx/html/ithuang;
location / {
# root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@server1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server1 ~]# nginx -s reload
[root@server1 ~]# systemctl status nginx
● nginx.service - Nginx Web Server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: di>
Active: active (running) since Sun 2026-05-24 14:42:16 CST; 33min ago
Process: 871 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, statu>
Process: 887 ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf>
Main PID: 893 (nginx)
Tasks: 2 (limit: 22926)
Memory: 5.8M
CPU: 143ms
CGroup: /system.slice/nginx.service
├─ 893 "nginx: master process /usr/local/nginx/sbin/nginx -c /usr/>
└─2930 "nginx: worker process"
5月 24 14:42:16 server1 systemd[1]: Starting Nginx Web Server...
5月 24 14:42:16 server1 systemd[1]: Started Nginx Web Server.
[root@server1 ~]#
注意:每行配置完成之后,一定要注意结束标记符号 ;
Nginx配置详细解释
# ================== 全局区 ==================
# worker 进程数量
# 一般建议:CPU 核心数(1 表示单进程,实验环境 OK)
worker_processes 1;
# ================== 事件模型 ==================
events {
# 单个 worker 进程最多允许的并发连接数
worker_connections 1024;
}
# ================== HTTP 服务配置 ==================
http {
# 引入 MIME 类型映射文件
# 用于根据文件后缀决定 Content-Type(如 .html .jpg .css)
include mime.types;
# 当文件类型无法匹配时的默认类型
default_type application/octet-stream;
# 启用零拷贝,提高静态文件传输效率
sendfile on;
# HTTP 长连接保持时间(秒)
# 客户端在 65 秒内再次请求无需重新建立连接
keepalive_timeout 65;
# ================== 虚拟主机(server 块) ==================
server {
# 监听 80 端口(HTTP 默认端口)
listen 80;
# 虚拟主机域名
# 访问 http://www.ithuang666.com 才会命中这个 server
server_name www.ithuang666.com;
# 网站根目录(非常关键)
# 这里对应的是:
# /usr/local/nginx/html/ithuang/index.html
root /usr/local/nginx/html/ithuang;
# ================== 站点根路径 / ==================
location / {
# 默认首页文件
# 当访问 / 时,会按顺序查找:
# index.html → index.htm
index index.html index.htm;
# 这里没有再写 root
# 表示继承 server 级别的 root
# 不会再被覆盖,路径是正确的
}
# ================== 错误页配置 ==================
# 当出现 500 / 502 / 503 / 504 错误时
# 内部重定向到 /50x.html
error_page 500 502 503 504 /50x.html;
# 精确匹配 /50x.html
location = /50x.html {
# 错误页所在目录
# 实际文件路径:
# /usr/local/nginx/html/50x.html
root html;
}
}
}
第二步:配置域名解析
Linux
cat >/etc/hosts<<EOF
192.168.80.11 www.ithuang666.com
EOF
在/usr/local/nginx/html目录下创建itheimadevops文件夹,然后在其目录下创建index.html文件
cd /usr/local/nginx/html
mkdir ithuang
vim ithuang/index.html
重载Nginx
手动启动nginx ,重载配置文件 ,先进行配置语法检查再进行重载
nginx -t
nginx -s reload
Windows
在Windows电脑中,解析hosts域名,设置IP与域名映射,强制让DNS把www.ithuang666.com指向虚拟机IP
在/usr/local/nginx/html目录下创建itheimadevops文件夹,然后在其目录下创建index.html文件
测试效果

[root@server1 ~]# curl www.ithuang666.com
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="images/logo.png" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Hab home-字符编程网www.zfcode.cn</title>
<meta name="keywords" content="Hab home -字符编程网www.zfcode.cn" />
<meta name="description" content="Hab home ,一套多个小游戏网站合集,采用响应式布局设计,自适应手机移动端,用户体验更好。字符编程网www.zfcode.cn" />
<meta name="author" content="" />
<meta name="copyright" content="" />
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
<meta name="viewport" content="width=device-width" />
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet" />
<!-- Material Dashboard CSS -->
<link href="css/material-dashboard.css" rel="stylesheet"/>
<!-- CSS for Demo Purpose, don't include it in your project -->
<link href="css/demo.css" rel="stylesheet" />
<!-- Fonts and icons -->
<link rel="stylesheet" href="css/font-awesome-4.7.0/css/font-awesome.min.css">
<link href='css/2d7207a20f294df196f3a53cae8a0def.css' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="wrapper">
<div class="sidebar" data-color="purple" data-image="images/404.jpg">
<!--
Tip 1: You can change the color of the sidebar using: data-color="purple | blue | green | orange | red"
Tip 2: you can also add an image using data-image tag
-->
<div class="logo">
<a href="https://www.zfcode.cn" target="right" class="simple-text"><img src="images/logo.png " width="30" height="30"/>Hab home</a>
</div>
<div class="sidebar-wrapper">
<ul class="nav">
<li class="active">
<a href="link/0.html" target="right" >
<i class="fa fa-twitch"></i>
<p>全部游戏</p>
</a>
</li>
<li>
<a href="link/1.html" target="right">
<i class="fa fa-mortar-board"></i>
<p>益智游戏</p>
</a>
</li>
<li>
<a href="link/2.html" target="right" >
<i class="fa fa-reddit-alien"></i>
<p>动作游戏</p>
</a>
</li>
<li>
<a href="link/3.html"target="right" >
<i class="fa fa-rocket"></i>
<p>射击游戏</p>
</a>
</li>
<li>
<a href="link/4.html" target="right" >
<i class="fa fa-houzz"></i>
<p>消除游戏</p>
</a>
</li>
<li>
<a href="link/5.html" target="right" >
<i class="fa fa-modx"></i>
<p>休闲游戏</p>
</a>
</li>
<li>
<a href="link/6.html" target="right" >
<i class="fa fa-delicious"></i>
<p>棋牌游戏</p>
</a>
</li>
<li>
<a href="http://wpa.qq.com/msgrd?v=3&uin=123&site=qq&menu=yes" target="right" >
<i class="fa fa-user-circle"></i>
<p>联系作者</p>
</a>
</li>
<li>
<a href="https://www.zfcode.cn" target="right" >
<i class="fa fa-coffee"></i>
<p>字符编程官网</p>
</a>
</li>
<li>
<a href="http://www.baidu.com/" target="right" >
<i class="fa fa-commenting"></i>
<p>友情链接</p>
</a>
</li>
</ul>
<div align="center">
<hr><a href="http://www.zfcode.cn">字符编程网</a>版权所有
</div>
</div>
</div>
<div class="main-panel">
<nav class="navbar navbar-transparent navbar-absolute" style="background-color: #fff;">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse">
<span class="sr-only">切换导航</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="link/index.html" class="dropdown-toggle" target="right">
<i class="fa fa-windows"></i>
<p class="hidden-lg hidden-md">关于我们</p>
</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="content">
<div class="container-fluid">
<div class="row" style="margin-top: -15px;">
<iframe src="link/0.html" width="100%" height="999" name="right" style="border: none;" ></iframe>
</div>
</div>
</div>
</div>
</body>
<!-- Core JS Files -->
<script src="js/jquery-3.1.0.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/material.min.js" type="text/javascript"></script>
<!-- Charts Plugin -->
<script src="js/chartist.min.js"></script>
<script src="js/material-dashboard.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".nav li").click(function(){
$(".nav li").removeClass("active");
$(this).addClass("active");
})
// Javascript method's body can be found in assets/js/demos.js
});
</script>
</html>
[root@server1 ~]#
常见问题说明:
问题1:启动脚本比较混乱,Nginx有两种启动方式:systemctl 或 sbin/nginx,两者不要混用,防止把自己绕进去
systemctl管理:---省略
systemctl start nginx
systemctl reload nginx
systemctl stop nginx
sbin/nginx管理:
cd /usr/local/nginx
sbin/nginx
sbin/nginx -s reload
sbin/nginx -s quit
3. 基于端口虚拟机
优势:默认不占用80端口,能够稍微隐秘一些
第一步:编辑nginx.conf配置文件
[root@server1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@server1 ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 2026;
server_name www.ithuang666.com;
root /usr/local/nginx/html/ithuang;
location / {
# root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@server1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server1 ~]# nginx -s reload
[root@server1 ~]#
第二步:检查配置并重载Nginx
nginx -t
nginx -s reload
netstat -pantul|grep nginx
运行结果:

六、location区块(重点)
作用:location区块用于URL规则匹配,既支持精准匹配,也支持正则匹配
http://nginx.org/en/docs/http/ngx_http_core_module.html#location
根据用户请求的URI来执行不同的操作
根据用户请求的网站URL进行匹配,匹配指定的请求URI
请求URI不包含查询字符串,如http://localhost:8080/test?id=10,请求URI是/test)
1. 基本语法
location [ = | ~ | * | ^ ] uri { .... } # 指令 匹配标识 匹配的网站网址 匹配URI之后要执行的配置段
☆ = 精确匹配
location = / {
#规则
}
注意:以上匹配操作只能匹配首页!
☆ ~ 大小写敏感
location ~ /Example/ {
#规则
}
为什么用 ~ 表示大小写敏感?
因此 ~ 在正则生态中 “默认大小写敏感” 的共识
大家用过 grep 命令,正则匹配默认就是区分大小写
请求示例
http://www.example.com/Example/ [成功] http://www.example.com/example/ [失败]
☆ ~* 大小写忽略
location ~* /Example/ {
# 规则
}
为什么用 ~* 表示大小写不敏感?
因为 * 在正则体系中,表示通配符的意思,可以表征任意字符,取包容兼容的意思。
请求示例
http://www.example.com/Example/ [成功] http://www.example.com/example/ [成功]
☆ ^~ 只匹配以 URI 开头
location ^~ /img/ {
#规则
}
请求示例
以 /img/ 开头的请求,都会匹配上
http://www.example.com/img/a.jpg [成功] http://www.example.com/img/b.mp4 [成功] http://www.example.com/bimg/b.mp4 [失败] http://www.example.com/Img/b.mp4 [失败]
2. 优先级
优先级:location如果有多个规则,则其也有优先级概念
常见 location 优先级排序(高→低):
1、location = /path:精确匹配(仅匹配 /path 这一个路径,不匹配子路径);
2、location ^~ /path:前缀优先匹配(匹配 /path 开头的路径,且优先级高于正则);
3、location ~ /path 或 location ~* /path:正则匹配(分别对应大小写敏感 / 不敏感);
4、location /path:普通前缀匹配(匹配 /path 开头的路径);
5、location /:最宽泛的普通前缀匹配(兜底)。
三大类
1 属于精准匹配 =
2、3 属于正则匹配 ~
4、5 属于普通匹配 /
1. 优先级最高
location = / { # 精确匹配
#规则
}
2. 优先匹配
location ^~ /images/ { # 开头匹配
#规则
}
3. 正则匹配 网站资源
区分大小写
location ~ \.(gif|jpg|jpeg|png) { # 大小写敏感
#规则
}
不区分大小写
location ~* \.(gif|jpg|jpeg|png) { # 大小写忽略
#规则
}
4. 根据资源目录进行匹配
location /documents/ { # 资源目录匹配
#规则
}
5. 所有匹配不满足时,匹配默认的location /
location / {
#规则
}
3. URL 重写
URL 重写是指服务器端(或客户端)对请求的 URL 地址进行 “修改 / 转换” 的技术,本质是将一个 URL 映射到另一个实际处理请求的 URL
基本语法
rewrite 匹配内容 替代内容 flag标记
flag标记说明:
| 标记 | 作用 |
|---|---|
| last | 本条规则匹配完成,继续匹配新的location URI规则 |
| break | 本条规则匹配完成即终止,不再匹配后面的任何规则 |
| redirect | 返回302临时重定向,浏览器地址会显示跳转后的URL地址 |
| permanent | 返回301永久重定向,浏览器地址会显示跳转后的URL地址 |
last:最后的;
URI:Uniform Resource Identifier / 统一资源标识符(Uniform Resource Identifier,URI)是一个用于标识某一互联网资源名称的字符串。
多条 rewrite,从上到下匹配,匹配到之后就不再匹配其他rewrite规则。
另外还要特别注意:
last 与 break,进行重定向时,其客户端URL地址不会改变。
redirect 与 permanent,进行重定向时,其客户端URL地址会发生改变。
官方文档地址:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite
☆ 案例一:资源重定向
要求:把访问的/demo.html,重定向到/demo.php,实现伪静态,也可以实现隐藏真实页面
# vim /usr/local/nginx/conf/nginx.conf
location / {
index index.html index.htm;
rewrite /demo.html /demo.php last;
}
注意:
rewrite后面两个参数中,斜杠/不能少;
又比如,
location / {
index index.html index.htm;
rewrite /demo.html /index.html break;
}
访问 http:IP:Port/demo.html 时,会跳转到展示 index.html
☆ 案例二:域名重定向
要求:公司的域名升级了,需要把所有请求重定向到新域名
# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.old.com;
rewrite / http://www.new.com permanent;
}
注意:
新域名和旧域名,不能是同一个server区块里面,不然会陷入重定向的死循环(想一想为什么);
☆ 案例三:防盗链原理和实现 (了解)
作用:就是防止我们站点中的资源被别人所使用 -> 主要针对资源文件,如(图片、音乐、视频)

当 Web2 服务器未经授权直接引用 Web1 服务器的资源(如图片、视频、CSS 文件)时,会形成跨站资源盗用。例如:
① 用户访问 Web2 页面时,浏览器向 Web1 发送请求加载http://web1.com/logo.png
② 表面上用户认为资源属于 Web2,实际所有流量成本由 Web1 承担,且 Web2 通过盗用提升自身丰富度
解决方案:
① 图片加水印
② 通过判断referer来源,确定是否返回对应的资源文件
基本语法:
location / {
valid_referers 绑定域名;
if ($invalid_referer) {
return 404;
}
}
图片防盗链案例(拓展)
1. 防盗链核心背景(精简且易懂)
问题本质:跨站资源盗用(盗链)是指第三方网站(如www.opponentdevops.com)直接引用我方站点(www.itheimadevops.com)的图片、视频等静态资源,导致我方承担带宽成本,且被盗用资源未体现我方权益。
核心解决方案:通过Nginx的valid_referers模块校验请求的Referer头(标识请求来源),仅允许合法来源访问资源,非法来源则返回403/默认图片。
辅助方案:图片加水印(需结合业务工具,我们聚焦Nginx配置层面)。
2. 环境准备(步骤标准化)
| 站点角色 | 域名 | 服务器路径 | 核心用途 |
|---|---|---|---|
| 我方合法站点 | www.ithuang666.com | /usr/local/nginx/html/ithuang | 存放正版静态资源 |
| 第三方盗链站点 | www.opponentdevops.com | /usr/local/nginx/html/opponent | 模拟盗链场景 |
步骤1:修改Nginx主配置
cat > /usr/local/nginx/conf/nginx.conf <<EOF
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 引入conf.d目录下的所有子配置(关键)
include conf.d/*.conf;
}
EOF
mkdir -p /usr/local/nginx/conf/conf.d
chown -Rf nginx:nginx /usr/local/nginx/
nginx -t
nginx -s reload
步骤2:配置盗链测试站点(模拟攻击者)
# 1. 创建盗链站点根目录
mkdir -p /usr/local/nginx/html/opponent
# 2. 编写盗链页面(引用我方图片)
cat > /usr/local/nginx/html/opponent/test.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>盗链测试</title>
</head>
<body>
<!-- 盗用我方站点的test.png图片 -->
<img src="http://www.ithuang666.com/test.png" />
</body>
</html>
EOF
# 3. 配置Nginx站点(单独配置文件,避免污染主配置)
cat > /usr/local/nginx/conf/conf.d/opponentdevops.conf << EOF
server {
listen 80;
server_name www.opponentdevops.com;
# 盗链站点根目录
root /usr/local/nginx/html/opponent;
# 默认索引页
location / {
index test.html index.html;
charset utf-8; # 避免中文乱码
}
}
EOF
步骤3:配置本地域名解析(模拟用户访问)
# 编辑hosts文件,绑定域名到服务器IP(替换为你的实际IP)
sed -i '/ithuang/d' /etc/hosts
echo "192.168.80.11 www.ithuang666.com www.opponentdevops.com" >> /etc/hosts
cat /etc/hosts
记得修改window系统中的hosts文件
3. 我方站点防盗链配置
步骤1:准备图片
# 把默认图片和测试图片放到我方站点根目录(需提前上传default.jpg,如404占位图)
mkdir -p /usr/local/nginx/html/ithuang
cp default.jpg /usr/local/nginx/html/ithuang
cp test.png /usr/local/nginx/html/ithuang
chown -Rf nginx:nginx /usr/local/nginx
步骤2:写我方站点index.html文件
cat >/usr/local/nginx/html/ithuang/index.html<<EOF
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>正常访问</title>
</head>
<body>
<!-- 测试图片 -->
<img src="http://www.ithuang666.com/test.png" />
</body>
</html>
EOF
步骤3:编写防盗链Nginx配置(单独配置文件,易维护)
cat > /usr/local/nginx/conf/conf.d/ithuang.conf << EOF
server {
listen 80;
server_name ithuang666.com;
# 我方站点根目录
root /usr/local/nginx/html/ithuang;
index index.html;
charset utf-8;
# 图片防盗链核心配置(匹配常见图片格式,不区分大小写)
location ~* \.(gif|jpg|jpeg|png|bmp|webp)$ {
# 允许的合法Referer来源
valid_referers
none # 允许无Referer的请求(如用户直接在浏览器输入图片URL)
blocked # 允许Referer被防火墙/代理隐藏的请求(如加密Referer)
server_names # 匹配当前server_name(www.ithuang666.com)
.ithuang.com; # 匹配所有子域名(如bbs.ithuang666.com)
# 非法Referer处理逻辑
if (\$invalid_referer) {
# 方案1:返回403禁止访问(推荐,直接拒绝盗链)
# return 403;
# 方案2:返回默认图片(友好提示,避免404)
rewrite ^/ /default.jpg break; # 关键:用break避免死循环
}
# 静态资源缓存(优化性能,非防盗链核心但建议配置)
expires 30d; # 浏览器缓存30天
add_header Cache-Control "public, max-age=2592000";
add_header X-Frame-Options SAMEORIGIN; # 额外防嵌套盗链
}
}
EOF
步骤4:校验配置并重启Nginx
# 1. 检查配置语法(避免重启失败)
nginx -t
# 2. 重新加载Nginx配置文件(不中断现有服务)
nginx -s reload
4. 测试防盗链

这是正常的结果,能访问到我们准备的测试图片!
http://www.opponentdevops.com/

这是不正常的结果,想盗链却访问到了我们默认给出的图片!
直接访问http://www.ithuang666.com/test.png

直接访问对应站点,不存在盗链!
七、安全加固(了解)
1. 版本隐藏
前置知识点:curl 命令
curl http://192.168.88.104,发起http请求,得到响应内容
或
curl -I http://192.168.88.104,发起http请求,不获取响应内容,而获取响应信息
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Fri, 21 Feb 2025 10:11:33 GMT
Content-Type: text/plain
Connection: keep-alive
Vary: Accept-Encoding
由上图可知,Server: nginx/1.26.2显示了服务器的Nginx版本信息。每个版本都不是完美的,都可能存在漏洞。
在http段加入server_tokens off
http {
server_tokens off;
}

nginx -s reload

2. 目录显示
基本语法:
在 location / {} 中添加下面配置
autoindex on;
index index; # 注意,这里不是 index index.html 那种以前的配置

打开浏览器,访问如下图所示:

小结:
autoindex on功能比较简单,就是为了显示Nginx对应项目录下的所有文件信息。
location / {
autoindex on;
index index;
}
注意:
由于 autoindex 会显示项目目录下的所有文件信息,所以其比较适合内部使用,不建议在外部环境使用!
如果存在 index 字段并且命中了文件,那么还是会优先展示文件内容,而不是目录;
3. 基于IP的访问控制
基于ngx_http_access_module模块,默认可使用
语法:
deny ip 禁止IP访问
allow ip 允许IP访问
https://nginx.org/en/docs/http/ngx_http_access_module.html


默认是允许所有IP访问。
案例:
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all;
}


思考:
192.168.1.1 这个IP,也满足下方 allow 192.168.1.0/24;那到底最终是允许还是不允许访问呢?
答:
不允许访问,默认从上往下执行,一旦匹配到某个规则,则自动触发。不会继续往下匹配!
提示:403,禁止访问。
总结
HTTP 状态码
一、2xx:成功,但企业场景下要关注细节
- 200 OK:常规成功。但在 API 网关中,可能会对返回内容做校验,如果 body 为空可能被判定为半失败。
- 201 Created:资源创建成功,RESTful API 中 POST 创建用户/订单的标配。
- 204 No Content:操作成功但无需返回 body(如 PUT 更新、DELETE 删除)。前端需注意不要解析 body。
- 206 Partial Content:断点续传或大文件分片下载。企业级存储/文件服务中常见,配合
Range头使用。
二、3xx:重定向与缓存,常被误解
- 301 Moved Permanently:永久重定向,浏览器会缓存,导致后续直接跳转。企业级中更换域名时慎用,一旦缓存旧域名可能一直跳转,需要结合 Cache-Control 控制。
- 302 Found:临时重定向。常见于未登录跳转登录页,但搜索引擎可能仍然索引原 URL。很多企业更推荐 303/307。
- 304 Not Modified:缓存协商命中,节省带宽。排查缓存问题时,看到大量 304 说明策略生效。
- 307 Temporary Redirect:请求方法不变(POST 还是 POST),适合表单提交后跳转。
- 308 Permanent Redirect:永久且方法不变,企业 API 版本迁移时使用。
三、4xx:客户端错误,是安全与风控的主战场
- 400 Bad Request:请求报文语法错误。在企业网关层常被自定义校验规则触发(如参数类型错误、JSON 格式非法)。排查需看服务端日志中的具体错误消息。
- 401 Unauthorized:未认证,缺少有效 Token。微服务架构中 JWT 过期、签名不匹配都会返回 401。注意与 403 区分:401 是“你没登录”,403 是“你登录了但没权限”。
- 403 Forbidden:授权失败。常见于角色权限不足、IP 黑名单、WAF 拦截。即使给了正确 Token 也会被拒。
- 404 Not Found:路径不存在。企业级中可能是 API 路由未注册、发布失败、网关路由配置错误。也用于安全目的(防止枚举)。
- 405 Method Not Allowed:请求方法不允许。例如只允许 GET 的接口收到了 POST,网关策略可能拦截。检查 CORS 配置时也会遇到。
- 408 Request Timeout:客户端请求超时。企业级通常说明客户端在服务端等待时间内未发送完整请求,可能因为网络太慢或客户端代码 Bug。
- 409 Conflict:资源冲突。常见于并发写入同一数据(如乐观锁失败、版本冲突),业务上用来防止重复创建订单。
- 410 Gone:资源永久删除,比 404 更明确。用于 API 版本废弃通知。
- 422 Unprocessable Entity:语义错误。请求格式正确,但参数不符合业务规则(如注册时邮箱格式对,但已存在)。企业 RESTful 中表单验证失败常用。
- 429 Too Many Requests:限流状态码。企业在网关或接口层面用令牌桶/漏桶实现,超过阈值返回 429,响应头常带
Retry-After。这是稳定性的关键。
四、5xx:服务端错误,需要立即关注
-
500 Internal Server Error:通用服务端错误。代码异常、空指针、数据库连接超时未捕获都会导致。排查必须先看应用日志。
-
502 Bad Gateway:网关/代理从上游服务器收到无效响应。企业级经典原因:
-
- 后端服务进程挂了,Nginx 无法连接。
- 后端返回了不符合 HTTP 协议的内容。
- 容器未就绪,K8s Service 指向了 unhealthy 的 Pod。
-
503 Service Unavailable:服务暂时不可用(你之前遇到的问题)。常见原因:
-
- 应用在重启/部署中。
- 连接池满,所有 worker 繁忙。
- CDN 回源失败、源站宕机。
- 维护模式开启。
排查时先看 Nginx error_log 和上游服务状态。
-
504 Gateway Timeout:网关等待上游响应超时。企业环境中,往往是后端接口耗时太长(复杂查询、死锁),或者网关超时配置(proxy_read_timeout)过短。需要分析慢请求。
-
505 或不支持的版本:极少见,关注点在于企业是否强制 HTTP/2。
五、企业级特有的“非标准”状态码
这些由代理、CDN 自定义,但却非常常见:
-
499 client closed request(Nginx 特有):客户端主动断开连接,一般是因为用户关闭了页面、取消了请求,或者客户端超时设置比服务端短。在日志里看到大量 499 说明用户耐心不足或服务端处理太慢。
-
444 No Response:Nginx 用来直接丢弃请求不返回任何内容,常用于防扫描。
-
520/521/522/524(Cloudflare 等 CDN):
-
- 520:源站返回了未知错误。
- 521:源站拒绝了 CDN 连接。
- 522:CDN 连接源站超时。
- 524:CDN 与源站建立连接但等待响应超时。
这些需要通过 CDN 分析平台与源站日志联合排查。
-
CORS 相关的预检请求 200/204:虽然不是错误,但企业级前后端分离调试时常遇到 OPTIONS 请求返回异常,实际是权限配置问题。
企业级排查状态码的通用方法
- 分层确定故障点
浏览器 → CDN/WAF → 反向代理/网关 → 应用服务 → 数据库/缓存。状态码是谁返回的,问题就出在那一层。 - 查看响应头
Server、X-Cache、CF-Ray等头部能说明经过了几层代理。 - 对比直接访问与通过代理
如之前你做的:IP 直连 vs 域名访问、curl vs 浏览器,差异在于请求头、协议、CDN 拦截等。 - 实时监控日志
tail -f你的 Nginx/Apache 错误日志和访问日志,然后复现,往往直接定位。