ithuang
ithuang
发布于 2025-11-22 / 2 阅读
0

企业级 Web 服务 Nginx 基础

企业级 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 的子集,不仅标识资源,还指定了访问资源的具体路径 / 方式(如协议、服务器地址、端口等)。

https://www.baidu.com/

http://www.example.com/

二、相关介绍

Nginx官网:https://nginx.org/

Nginx (engine x) 是一个高性能的HTTP和反向代理Web服务器,同时也提供了IMAP/POP3/SMTP等邮件服务。其特点是占用内存少,并发能力强。

Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的。

第一个公开版本0.1.0发布于2004年10月4日,后来被美国的F5公司(硬件负载均衡厂商)收购。

1. 三大功能

HTTP 服务器

  1. 同类型 Web 服务器软件:Apache、Nginx(俄罗斯)、IIS(微软)、lighttpd(德国)

反向代理

接收客户端的请求,然后将这些请求转发到内部的多个服务器上进行处理,最后将处理结果返回给客户端。这就好比是一个“智能接待员”。

☆ 正向代理 vs 反向代理

正向代理

企业级 Web 服务 Nginx 基础1.png

特点:知道自己使用了代理,需要填写代理服务器的IP等相关连接信息

场景:常见于代理客户端上网等操作(科学上网)

反向代理

企业级 Web 服务 Nginx 基础2.png

特点:

用户是无感知的,不知道使用了代理服务器。

反向代理服务器是和真实访问的服务器是在一起的,有关联的。

作用:

① 可以根据实际业务需求,分发代理页面到不同的解释器

② 可以隐藏真实服务器的路径

  1. 场景:常见于代理后端服务器

负载均衡

当有大量的用户请求时,单台服务器可能无法承受如此大的压力。

Nginx的负载均衡功能可以将这些请求均匀地分配到多个后端服务器上,从而提高系统的整体处理能力和可靠性。这就像是一个“交通指挥官”。

负载均衡技术 (Load Balance,LB),其原理就是把用户请求分发到不同的服务器,使流量合理分配。

负载均衡作用:服务器容灾,流量分发

① 流量分发 请求平均 降低单例压力

② 安全 隐藏后端真实服务

③ 屏蔽非法请求(七层负载均衡)

http://www.itcast.cn/images/1.jpg => *.jpg图片 => 调度后端的图片服务器

企业级 Web 服务 Nginx 基础3.png

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

企业级 Web 服务 Nginx 基础4.png

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

企业级 Web 服务 Nginx 基础5.png

企业级 Web 服务 Nginx 基础6.png

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

企业级 Web 服务 Nginx 基础7.png

企业级 Web 服务 Nginx 基础8.png

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

企业级 Web 服务 Nginx 基础9.png

企业级 Web 服务 Nginx 基础10.png

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编译安装到的软件目录
--userworker进程运行用户
--groupworker进程运行用户组
--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、端口占用

企业级 Web 服务 Nginx 基础11.png

可以通过以下命令进行查看和停止Nginx

ps aux|grep nginx

nginx -s stop

企业级 Web 服务 Nginx 基础12.png

2、依赖缺失

企业级 Web 服务 Nginx 基础13.png

# 需要下载库
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 signalstop关闭 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

企业级 Web 服务 Nginx 基础14.png

案例:添加一个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文件

测试效果

http://www.ithuang666.com

企业级 Web 服务 Nginx 基础15.png

curlhttp://www.ithuang666.com

[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

运行结果:

企业级 Web 服务 Nginx 基础16.png

六、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区块里面,不然会陷入重定向的死循环(想一想为什么);

☆ 案例三:防盗链原理和实现 (了解)

作用:就是防止我们站点中的资源被别人所使用 -> 主要针对资源文件,如(图片、音乐、视频)

企业级 Web 服务 Nginx 基础17.png

当 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.ithuang666.com/

企业级 Web 服务 Nginx 基础18.png

这是正常的结果,能访问到我们准备的测试图片!

http://www.opponentdevops.com/

企业级 Web 服务 Nginx 基础19.png

这是不正常的结果,想盗链却访问到了我们默认给出的图片!

直接访问http://www.ithuang666.com/test.png

企业级 Web 服务 Nginx 基础20.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;
}

企业级 Web 服务 Nginx 基础21.png

nginx -s reload

企业级 Web 服务 Nginx 基础22.png

2. 目录显示

基本语法:

在 location / {} 中添加下面配置
    autoindex on;
    index index;        # 注意,这里不是 index index.html 那种以前的配置

企业级 Web 服务 Nginx 基础23.png

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

企业级 Web 服务 Nginx 基础24.png

小结:

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

企业级 Web 服务 Nginx 基础25.png

企业级 Web 服务 Nginx 基础26.png

默认是允许所有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;
}

企业级 Web 服务 Nginx 基础27.png

企业级 Web 服务 Nginx 基础28.png

思考:

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 请求返回异常,实际是权限配置问题。


企业级排查状态码的通用方法

  1. 分层确定故障点
    浏览器 → CDN/WAF → 反向代理/网关 → 应用服务 → 数据库/缓存。状态码是谁返回的,问题就出在那一层。
  2. 查看响应头
    Server、X-Cache、CF-Ray 等头部能说明经过了几层代理。
  3. 对比直接访问与通过代理
    如之前你做的:IP 直连 vs 域名访问、curl vs 浏览器,差异在于请求头、协议、CDN 拦截等。
  4. 实时监控日志
    tail -f 你的 Nginx/Apache 错误日志和访问日志,然后复现,往往直接定位。