赵玉全 發表於 2025-11-26 11:34:06

Nginx概念、架构、配置与虚拟主机实战操作指南

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">Nginx 深度解析:概念、架构、配置与虚拟主机实战</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">一、Nginx 的概念</a></li><li><a href="#_lab2_0_1">二、Nginx 的特点</a></li><li><a href="#_lab2_0_2">三、Nginx 的进程结构(详细解析)</a></li><ul class="third_class_ul"><li><a href="#_label3_0_2_0">3.1 进程结构总览</a></li><li><a href="#_label3_0_2_1">3.2 主进程(Master Process)&mdash;&mdash;&ldquo;管理者&rdquo;</a></li><li><a href="#_label3_0_2_2">3.3 工作进程(Worker Process)&mdash;&mdash;&ldquo;执行者&rdquo;</a></li><li><a href="#_label3_0_2_3">3.4 进程间通信机制</a></li></ul><li><a href="#_lab2_0_3">四、Nginx 的配置(详细解析 + 流量流程)</a></li><ul class="third_class_ul"><li><a href="#_label3_0_3_4">配置文件整体结构模板</a></li><li><a href="#_label3_0_3_5">4.1 全局配置(全局块)</a></li><li><a href="#_label3_0_3_6">4.2 I/O 事件配置(events 块)</a></li><li><a href="#_label3_0_3_7">4.3 HTTP 配置(http 块)</a></li><li><a href="#_label3_0_3_8">4.4 Web 服务的监听配置(server 块)</a></li><li><a href="#_label3_0_3_9">4.5 其他配置(location 块)</a></li></ul><li><a href="#_lab2_0_4">五、Nginx 虚拟主机</a></li><ul class="third_class_ul"><li><a href="#_label3_0_4_10">5.1 访问状态统计配置</a></li><li><a href="#_label3_0_4_11">5.2 基于授权的访问控制(HTTP 基本认证)</a></li><li><a href="#_label3_0_4_12">5.3 基于客户端的访问控制(IP 黑白名单)</a></li><li><a href="#_label3_0_4_13">5.4 基于域名的 Nginx 虚拟主机</a></li><li><a href="#_label3_0_4_14">5.5 基于 IP 的 Nginx 虚拟主机</a></li><li><a href="#_label3_0_4_15">5.6 基于端口的 Nginx 虚拟主机</a></li><li><a href="#_label3_0_4_16">三种虚拟主机对比</a></li></ul></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>Nginx 深度解析:概念、架构、配置与虚拟主机实战</h2>
<p class="maodian"><a name="_lab2_0_0"></a></p><h3>一、Nginx 的概念</h3>
<p>Nginx(发音 &ldquo;engine x&rdquo;)是由俄罗斯开发者 Igor Sysoev 设计的<strong>高性能 HTTP 服务器、反向代理服务器、负载均衡器和 IMAP/POP3/SMTP 代理服务器</strong>。其核心设计理念是 &ldquo;事件驱动、异步非阻塞 I/O 模型&rdquo;,旨在以极低的资源消耗支撑超高并发连接,同时提供丰富的扩展功能。</p>
<p>从本质上讲,Nginx 是一个 &ldquo;请求分发与处理中枢&rdquo;:</p>
<ul><li>作为 Web 服务器:直接处理静态资源(HTML、CSS、JS、图片等)的请求,无需依赖后端应用;</li><li>作为反向代理:接收客户端请求后,转发到后端业务服务器(Tomcat、Node.js 等),并将响应结果返回给客户端,隐藏后端服务细节;</li><li>作为负载均衡器:将海量客户端请求均匀分发到多台后端服务器,提升系统并发能力和可用性;</li><li>其他角色:支持 SSL 终结、URL 重写、缓存、限流等附加功能,适配复杂业务场景。</li></ul>
<p>Nginx 广泛应用于互联网架构的 &ldquo;接入层&rdquo;,是目前全球使用最广泛的 Web 服务器之一(据 W3Techs 统计,全球 Top 1000 网站中约 60% 采用 Nginx)。</p>
<p class="maodian"><a name="_lab2_0_1"></a></p><h3>二、Nginx 的特点</h3>
<p>Nginx 之所以成为行业主流,核心源于以下六大特点,且每个特点都与底层设计深度绑定:</p>
<ol><li><strong>高并发支持</strong>:基于事件驱动(epoll/kqueue)和异步非阻塞 I/O 模型,单台服务器可轻松支撑 10 万 + 并发连接(远高于 Apache 的进程 / 线程模型)。其核心逻辑是 &ldquo;一个工作进程处理多个连接&rdquo;,避免了进程 / 线程切换的巨大开销;</li><li><strong>资源占用极低</strong>:空闲状态下内存占用仅几 MB,运行时 CPU 使用率远低于同类服务器。例如,4 核 8G 服务器部署 Nginx 后,仅占用 10-20MB 内存,可将大部分资源留给业务服务;</li><li><strong>功能全面且灵活</strong>:集静态资源服务、反向代理、负载均衡、SSL 配置、URL 重写、缓存、限流等功能于一体,支持第三方模块扩展(如 Lua 脚本、图片处理模块);</li><li><strong>稳定性极强</strong>:核心代码简洁(约 10 万行),故障率极低,支持 &ldquo;热部署&rdquo;(<code>nginx -s reload</code>)&mdash;&mdash; 无需重启服务即可重载配置,保障业务不中断;</li><li><strong>跨平台兼容</strong>:可运行在 Linux、Windows、FreeBSD、Solaris 等多种操作系统,主流 Linux 发行版(CentOS、Ubuntu)默认提供安装源;</li><li><strong>配置简单易维护</strong>:配置文件采用文本格式,结构清晰(块级层级),支持主配置 + 子配置拆分,便于批量管理和自动化部署。</li></ol>
<p class="maodian"><a name="_lab2_0_2"></a></p><h3>三、Nginx 的进程结构(详细解析)</h3>
<p>Nginx 启动后,会生成<strong>多进程架构</strong>,核心由 &ldquo;主进程(Master Process)&rdquo; 和 &ldquo;工作进程(Worker Process)&rdquo; 组成,部分场景会包含 &ldquo;辅助进程&rdquo;(缓存加载进程、日志轮转进程等)。这种架构设计是 Nginx 高并发、高稳定的核心保障,以下分进程详解:</p>
<p class="maodian"><a name="_label3_0_2_0"></a></p><h4>3.1 进程结构总览</h4>
<p>plaintext</p>
<div class="jb51code"><pre class="brush:bash;"># 启动 Nginx 后,通过 ps 命令查看进程(以 4 核服务器为例)
ps -ef | grep nginx
root      1234   10 10:00 ?      00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx   123512340 10:00 ?      00:00:02 nginx: worker process
nginx   123612340 10:00 ?      00:00:02 nginx: worker process
nginx   123712340 10:00 ?      00:00:02 nginx: worker process
nginx   123812340 10:00 ?      00:00:02 nginx: worker process</pre></div>
<ul><li>1 个主进程(root 用户运行,权限高,负责管理);</li><li>4 个工作进程(nginx 普通用户运行,权限低,负责处理请求);</li><li>(可选)缓存加载进程(<code>cache loader process</code>):启动时加载磁盘缓存到内存,完成后自动退出;</li><li>(可选)缓存管理进程(<code>cache manager process</code>):定期清理过期缓存,维持缓存大小在配置阈值内。</li></ul>
<p class="maodian"><a name="_label3_0_2_1"></a></p><h4>3.2 主进程(Master Process)&mdash;&mdash;&ldquo;管理者&rdquo;</h4>
<h5>核心作用:</h5>
<ol><li><strong>读取并验证配置文件</strong>:启动时加载&nbsp;<code>nginx.conf</code>,检查语法正确性;支持热重载(<code>nginx -s reload</code>),重新读取配置并生效,无需中断服务;</li><li><strong>创建并管理工作进程</strong>:根据&nbsp;<code>worker_processes</code>&nbsp;配置(默认与 CPU 核心数一致),通过&nbsp;<code>fork()</code>&nbsp;系统调用创建工作进程;监控工作进程状态,若工作进程异常退出,立即自动创建新的工作进程,保障服务可用性;</li><li><strong>接收并处理信号</strong>:响应管理员发送的信号(如启动、停止、重载、日志切割),例如:<ul><li><code>kill -HUP 主进程PID</code>:重载配置;</li><li><code>kill -TERM 主进程PID</code>:优雅停止服务(处理完当前请求后退出);</li></ul></li><li><strong>管理辅助进程</strong>:按需启动缓存加载 / 管理进程、日志轮转进程等。</li></ol>
<h5>运行权限:</h5>
<p>主进程必须以 root 用户运行,原因是:</p>
<ul><li>Nginx 需监听 80(HTTP)、443(HTTPS)等特权端口(Linux 中,非 root 用户无法绑定 1024 以下端口);</li><li>主进程需要创建 / 管理工作进程,且工作进程通常以低权限用户(如 nginx)运行,避免因工作进程被攻击导致系统权限泄露。</li></ul>
<p class="maodian"><a name="_label3_0_2_2"></a></p><h4>3.3 工作进程(Worker Process)&mdash;&mdash;&ldquo;执行者&rdquo;</h4>
<h5>核心作用:</h5>
<p><strong>处理客户端的 HTTP 请求</strong>,是 Nginx 并发能力的核心载体,其工作流程如下:</p>
<ol><li><strong>竞争接收连接</strong>:所有工作进程通过 &ldquo;共享监听套接字&rdquo;(主进程创建监听端口后,工作进程继承该套接字),采用 &ldquo;惊群效应优化&rdquo;(Nginx 1.11+ 已解决)竞争接收客户端连接;</li><li><strong>异步非阻塞处理请求</strong>:每个工作进程通过 epoll/kqueue 事件模型,同时处理成千上万个连接(由&nbsp;<code>worker_connections</code>&nbsp;配置限制),无需为每个连接创建线程 / 进程,资源消耗极低;</li><li><strong>请求处理流程</strong>:<ul><li>接收客户端请求数据;</li><li>解析 HTTP 协议(请求行、请求头、请求体);</li><li>匹配&nbsp;<code>server</code>&nbsp;块(通过监听端口 +<code>server_name</code>);</li><li>匹配&nbsp;<code>location</code>&nbsp;块(通过请求路径);</li><li>执行处理逻辑(返回静态资源、反向代理到后端服务、负载均衡分发等);</li><li>构建 HTTP 响应,发送给客户端;</li></ul></li><li><strong>无状态设计</strong>:工作进程之间完全独立,无共享内存,每个工作进程处理的请求互不影响,避免了进程间通信的开销,也提升了稳定性(单个工作进程故障不影响其他进程)。</li></ol>
<h5>关键配置与并发能力:</h5>
<p>工作进程的并发能力由两个核心配置决定:</p>
<ul><li><code>worker_processes</code>:工作进程数,推荐设置为 CPU 核心数(如 4 核服务器设为 4),避免进程切换开销,充分利用多核 CPU;</li><li><code>worker_connections</code>:每个工作进程的最大连接数(默认 1024),表示单个工作进程可同时处理的客户端连接数。</li></ul>
<p><strong>最大并发连接数计算公式</strong>:<code>最大并发数 = worker_processes &times; worker_connections &divide; 2</code>(除以 2 是因为每个 HTTP 连接包含 &ldquo;客户端&rarr;Nginx&rdquo; 和 &ldquo;Nginx&rarr;后端服务&rdquo; 两个连接,若仅处理静态资源,可无需除以 2)</p>
<p>例如:<code>worker_processes=4</code>,<code>worker_connections=1024</code>,则最大并发连接数约为 2048。</p>
<h5>运行权限:</h5>
<p>工作进程以低权限用户(如 nginx)运行,由主进程在创建时通过&nbsp;<code>setuid()</code>/<code>setgid()</code>&nbsp;系统调用切换用户,目的是:</p>
<ul><li>降低安全风险:若工作进程被恶意攻击,攻击者仅能获取 nginx 用户权限,无法操作系统核心资源;</li><li>限制文件访问:工作进程仅能访问 nginx 用户有权限的文件(如网站根目录、日志文件),避免误操作系统文件。</li></ul>
<p class="maodian"><a name="_label3_0_2_3"></a></p><h4>3.4 进程间通信机制</h4>
<p>Nginx 进程间通信主要依赖以下方式:</p>
<ol><li><strong>共享内存</strong>:用于共享配置信息(如&nbsp;<code>upstream</code>&nbsp;后端服务器状态、缓存元数据),避免每个进程重复加载配置,提升效率;</li><li><strong>信号</strong>:主进程通过信号(如&nbsp;<code>SIGCHLD</code>)监控工作进程状态,工作进程异常退出时,主进程收到信号后创建新的工作进程;</li><li><strong>文件锁</strong>:用于日志写入、缓存操作等场景,避免多个工作进程同时写入同一文件导致数据错乱。</li></ol>
<p class="maodian"><a name="_lab2_0_3"></a></p><h3>四、Nginx 的配置(详细解析 + 流量流程)</h3>
<p>Nginx 的核心配置文件为&nbsp;<code>/usr/local/nginx/conf/nginx.conf</code>(源码安装路径),采用<strong>块级层级结构</strong>,从外到内依次为:<code>全局块 &rarr; I/O事件块 &rarr; HTTP块 &rarr; Server块 &rarr; Location块</code>。</p>
<p class="maodian"><a name="_label3_0_3_4"></a></p><h4>配置文件整体结构模板</h4>
<p>nginx</p>
<div class="jb51code"><pre class="brush:plain;"># 一、全局配置(全局块)
worker_processes4;                  # 工作进程数,与CPU核心数一致
error_loglogs/error.logwarn;       # 错误日志路径+日志级别
pid      logs/nginx.pid;            # PID文件路径
worker_rlimit_nofile 65535;         # 每个工作进程的最大文件描述符限制
# 二、I/O事件配置(events块)
events {
    use epoll;                         # 使用epoll事件模型(Linux推荐)
    worker_connections10240;         # 每个工作进程最大连接数
    multi_accept on;                   # 允许工作进程一次性接收多个连接
    accept_mutex on;                   # 开启连接接收互斥锁,解决惊群效应
}
# 三、HTTP配置(http块)
http {
    include       mime.types;          # 引入MIME类型映射文件
    default_typeapplication/octet-stream; # 默认MIME类型(未知文件类型)
    # 日志格式定义(main为格式名,可在server/location块引用)
    log_formatmain'$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_loglogs/access.logmain; # 访问日志路径+使用main格式
    # 核心性能优化配置
    sendfile      on;                # 启用高效文件传输模式(零拷贝)
    tcp_nopush      on;                # 配合sendfile,减少TCP数据包数量
    tcp_nodelay   on;                # 禁用TCP延迟,提升实时性(适用于短连接)
    keepalive_timeout65;             # 长连接超时时间(秒)
    keepalive_requests 100;            # 每个长连接最多处理100个请求
    # 开启gzip压缩
    gzipon;
    gzip_min_length1k;               # 小于1k的文件不压缩
    gzip_types text/plain text/css application/json application/javascript; # 压缩的文件类型
    # 负载均衡集群配置(可选)
    upstream backend_servers {
      server 192.168.1.101:8080 weight=1; # 后端服务器1,权重1
      server 192.168.1.102:8080 weight=2; # 后端服务器2,权重2(接收更多请求)
    }
    # 四、Web服务的监听配置(server块,虚拟主机核心)
    server {
      listen       80;               # 监听80端口(HTTP默认端口)
      listen       192.168.1.100:80; # 绑定特定IP+端口(多IP服务器时使用)
      server_namewww.test.com test.com; # 绑定域名(多个域名用空格分隔)
      charset utf-8;               # 网页字符编码
      access_loglogs/www.test.com.access.logmain; # 该虚拟主机的访问日志
      # 五、其他配置(location块,路径匹配核心)
      # 匹配根路径(/)
      location / {
            root   /usr/local/nginx/html; # 网站根目录(静态资源存放路径)
            indexindex.html index.htm;# 默认首页文件(优先级:index.html &gt; index.htm)
            try_files $uri $uri/ /index.html; # 尝试访问文件→目录→跳转index.html(SPA应用常用)
      }
      # 匹配静态资源路径(图片、CSS、JS)
      location ~* \.(jpg|jpeg|png|gif|css|js)$ {
            root   /usr/local/nginx/static; # 静态资源独立存放目录
            expires 7d;                  # 浏览器缓存7天,减少重复请求
            add_header Cache-Control "public"; # 允许缓存
      }
      # 反向代理配置(匹配/api路径的请求)
      location /api/ {
            proxy_pass http://backend_servers; # 转发到负载均衡集群
            proxy_set_header Host $host;       # 传递客户端请求的Host头
            proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链IP
            proxy_connect_timeout 60;         # 代理连接超时时间
      }
      # 错误页面配置
      error_page404            /404.html; # 404错误跳转至404.html
      error_page   500 502 503 504/50x.html; # 5xx错误跳转至50x.html
      location = /50x.html {
            root   html; # 错误页面存放目录
      }
    }
}</pre></div>
<p class="maodian"><a name="_label3_0_3_5"></a></p><h4>4.1 全局配置(全局块)</h4>
<h5>核心指令解析</h5>
<table><thead><tr><th>指令</th><th>作用</th><th>配置建议</th></tr></thead><tbody><tr><td><code>worker_processes</code></td><td>定义工作进程数,直接影响并发能力</td><td>设为 CPU 核心数(<code>grep -c &quot;processor&quot; /proc/cpuinfo</code>&nbsp;查看),如 4 核设为 4</td></tr><tr><td><code>error_log</code></td><td>定义错误日志的路径和日志级别(debug/info/notice/warn/error/crit)</td><td>生产环境设为&nbsp;<code>warn</code>&nbsp;或&nbsp;<code>error</code>,避免日志过大;路径建议放在&nbsp;<code>/var/log/nginx/</code></td></tr><tr><td><code>pid</code></td><td>定义 Nginx 主进程 PID 文件的存放路径</td><td>默认在&nbsp;<code>logs/nginx.pid</code>,无需修改,便于管理进程</td></tr><tr><td><code>worker_rlimit_nofile</code></td><td>限制每个工作进程的最大文件描述符数(Linux 中,连接、文件都属于文件描述符)</td><td>设为 65535(与系统最大文件描述符一致,需先修改系统配置:<code>echo &quot;* soft nofile 65535&quot; &gt;&gt; /etc/security/limits.conf</code>)</td></tr><tr><td><code>worker_cpu_affinity</code></td><td>绑定工作进程到指定 CPU 核心,避免进程切换开销</td><td>4 核服务器配置:<code>worker_cpu_affinity 0001 0010 0100 1000</code>(每个进程绑定一个核心)</td></tr></tbody></table>
<h5>流量流程中的作用:</h5>
<p>全局配置是 Nginx 启动时加载的 &ldquo;基础配置&rdquo;,对所有工作进程和服务全局生效,不直接参与请求的路由,但决定了 Nginx 的整体性能上限(如并发连接数、进程资源限制)。</p>
<p class="maodian"><a name="_label3_0_3_6"></a></p><h4>4.2 I/O 事件配置(events 块)</h4>
<h5>核心指令解析</h5>
<table><thead><tr><th>指令</th><th>作用</th><th>配置建议</th></tr></thead><tbody><tr><td><code>use</code></td><td>指定 I/O 事件模型(epoll/kqueue/poll/select)</td><td>Linux 系统优先选&nbsp;<code>epoll</code>(高效处理海量并发连接);FreeBSD 选&nbsp;<code>kqueue</code>;Windows 选&nbsp;<code>select</code></td></tr><tr><td><code>worker_connections</code></td><td>每个工作进程的最大连接数(包括客户端连接、后端代理连接)</td><td>1G 内存服务器设为 10240,2G 设为 20480,需与&nbsp;<code>worker_processes</code>&nbsp;配合调整最大并发数</td></tr><tr><td><code>multi_accept</code></td><td>允许工作进程一次性接收多个新连接(默认 off)</td><td>开启(<code>on</code>),提升连接接收效率,尤其高并发场景</td></tr><tr><td><code>accept_mutex</code></td><td>开启连接接收互斥锁(默认 on),解决 &ldquo;惊群效应&rdquo;(多个工作进程同时竞争一个连接,导致资源浪费)</td><td>保持开启,避免惊群效应导致的性能损耗</td></tr><tr><td><code>worker_aio_requests</code></td><td>每个工作进程的异步 I/O 请求数(适用于大文件传输)</td><td>设为 1024,提升大文件(如视频、安装包)的传输效率</td></tr></tbody></table>
<h5>流量流程中的作用:</h5>
<p>I/O 事件配置决定了工作进程 &ldquo;如何接收和处理网络连接&rdquo;,是 Nginx 高并发的核心保障。当客户端发起连接时,工作进程通过配置的事件模型(如 epoll)监听连接事件,高效接收并处理连接,避免阻塞。</p>
<p class="maodian"><a name="_label3_0_3_7"></a></p><h4>4.3 HTTP 配置(http 块)</h4>
<p>HTTP 块是 Nginx 处理 HTTP/HTTPS 请求的 &ldquo;核心全局配置&rdquo;,包含所有与 HTTP 协议相关的配置,且可嵌套多个&nbsp;<code>server</code>&nbsp;块(虚拟主机)。</p>
<h5>核心指令解析</h5>
<table><thead><tr><th>指令</th><th>作用</th><th>配置建议</th></tr></thead><tbody><tr><td><code>include mime.types</code></td><td>引入 MIME 类型映射文件(定义文件扩展名与 Content-Type 的对应关系,如 .html &rarr; text/html)</td><td>必须配置,否则 Nginx 无法正确返回文件的 Content-Type 头,导致浏览器无法识别文件</td></tr><tr><td><code>default_type</code></td><td>未匹配到 MIME 类型时的默认类型</td><td>默认为&nbsp;<code>application/octet-stream</code>(浏览器会下载文件),无需修改</td></tr><tr><td><code>log_format</code></td><td>定义访问日志的格式(可自定义字段,如 IP、时间、请求路径、状态码)</td><td>生产环境保留&nbsp;<code>main</code>&nbsp;格式,便于日志分析(如统计访问 IP、错误请求)</td></tr><tr><td><code>access_log</code></td><td>定义访问日志的路径和使用的格式</td><td>每个虚拟主机可单独配置,便于区分不同网站的日志</td></tr><tr><td><code>sendfile</code></td><td>开启 &ldquo;零拷贝&rdquo; 文件传输模式(Nginx 直接将文件数据从磁盘写入网络套接字,无需经过用户态缓冲区)</td><td>开启(<code>on</code>),大幅提升静态资源传输效率,减少 CPU 占用</td></tr><tr><td><code>tcp_nopush</code></td><td>配合&nbsp;<code>sendfile</code>&nbsp;使用,将多个小数据包合并为一个数据包发送,减少 TCP 握手次数</td><td>开启(<code>on</code>),提升网络传输效率</td></tr><tr><td><code>tcp_nodelay</code></td><td>禁用 TCP 延迟(Nagle 算法),立即发送小数据包,提升实时性</td><td>短连接(如 API 接口)开启(<code>on</code>),长连接(如文件下载)关闭(<code>off</code>)</td></tr><tr><td><code>keepalive_timeout</code></td><td>长连接(HTTP/1.1)的超时时间,客户端在超时前可复用连接发送多个请求</td><td>设为 60 秒,减少连接建立 / 关闭的开销,提升并发能力</td></tr><tr><td><code>gzip</code></td><td>开启 gzip 压缩,减少文本类文件(HTML、CSS、JS、JSON)的传输体积</td><td>开启(<code>on</code>),配合&nbsp;<code>gzip_types</code>&nbsp;配置需要压缩的文件类型</td></tr><tr><td><code>upstream</code></td><td>定义负载均衡集群(后端业务服务器组),用于反向代理时的请求分发</td><td>后端多服务器部署时配置,支持轮询、权重、IP 哈希等负载策略</td></tr></tbody></table>
<h5>流量流程中的作用:</h5>
<p>客户端请求到达 Nginx 后,首先进入 HTTP 块进行 &ldquo;全局预处理&rdquo;:</p>
<ol><li>解析 HTTP 协议,识别请求行(方法、路径、协议版本)、请求头;</li><li>应用 gzip 压缩配置(若请求头支持压缩);</li><li>记录访问日志(按&nbsp;<code>log_format</code>&nbsp;格式);</li><li>根据请求的 &ldquo;监听端口&rdquo; 和 &ldquo;Host 头&rdquo;,匹配对应的&nbsp;<code>server</code>&nbsp;块,进入虚拟主机处理流程。</li></ol>
<p class="maodian"><a name="_label3_0_3_8"></a></p><h4>4.4 Web 服务的监听配置(server 块)</h4>
<p><code>server</code>&nbsp;块是 &ldquo;虚拟主机&rdquo; 的核心配置,每个&nbsp;<code>server</code>&nbsp;块对应一个独立的 Web 服务(可理解为一个网站),通过&nbsp;<code>listen</code>(监听端口)和&nbsp;<code>server_name</code>(绑定域名 / IP)区分不同的虚拟主机。</p>
<h5>核心指令解析</h5>
<table><thead><tr><th>指令</th><th>作用</th><th>配置示例</th></tr></thead><tbody><tr><td><code>listen</code></td><td>定义虚拟主机的监听端口 / IP + 端口,支持多端口监听</td><td>- 监听所有 IP 的 80 端口:<code>listen 80;</code>- 监听特定 IP 的 80 端口:<code>listen 192.168.1.100:80;</code>- 监听 HTTPS 端口:<code>listen 443 ssl;</code></td></tr><tr><td><code>server_name</code></td><td>定义虚拟主机绑定的域名 / IP,支持精确匹配、泛域名匹配、正则匹配</td><td>- 精确匹配:<code>server_name www.test.com test.com;</code>- 泛域名匹配:<code>server_name *.test.com;</code>(匹配所有子域名)- 正则匹配:<code>server_name ~^www\.(.*)\.com$;</code>(匹配&nbsp;<a href="https://www.xxx.com/" rel="external nofollow"   title="www.xxx.com">www.xxx.com</a>&nbsp;格式域名)</td></tr><tr><td><code>charset</code></td><td>定义网页的字符编码(如 UTF-8、GBK)</td><td>设为&nbsp;<code>utf-8</code>,避免中文乱码</td></tr><tr><td><code>access_log</code></td><td>定义该虚拟主机的独立访问日志</td><td>路径建议包含域名,如&nbsp;<code>logs/www.test.com.access.log</code>,便于日志拆分和分析</td></tr></tbody></table>
<h5>流量路由逻辑(关键):</h5>
<p>Nginx 如何通过&nbsp;<code>listen</code>&nbsp;和&nbsp;<code>server_name</code>&nbsp;匹配虚拟主机?</p>
<ol><li>第一步:匹配&nbsp;<code>listen</code>&nbsp;端口 &mdash;&mdash; 客户端请求的端口必须与&nbsp;<code>server</code>&nbsp;块的&nbsp;<code>listen</code>&nbsp;配置一致,否则直接拒绝;</li><li>第二步:匹配&nbsp;<code>server_name</code>&mdash;&mdash; 根据客户端请求头中的&nbsp;<code>Host</code>&nbsp;字段(如&nbsp;<code>Host: www.test.com</code>),按以下优先级匹配:<ul><li>精确匹配(如&nbsp;<code>www.test.com</code>);</li><li>左泛域名匹配(如&nbsp;<code>*.test.com</code>);</li><li>右泛域名匹配(如&nbsp;<code>www.*</code>);</li><li>正则匹配(如&nbsp;<code>~^www\..*\.com$</code>);</li><li>默认匹配(第一个&nbsp;<code>listen</code>&nbsp;端口一致的&nbsp;<code>server</code>&nbsp;块,或&nbsp;<code>server_name _;</code>&nbsp;的块)。</li></ul></li></ol>
<h5>流量流程中的作用:</h5>
<p>经过 HTTP 块预处理后,请求根据 &ldquo;端口 + Host&rdquo; 匹配到对应的&nbsp;<code>server</code>&nbsp;块,进入该虚拟主机的专属处理流程,后续的&nbsp;<code>location</code>&nbsp;块匹配、请求处理都基于该&nbsp;<code>server</code>&nbsp;块的配置。</p>
<p class="maodian"><a name="_label3_0_3_9"></a></p><h4>4.5 其他配置(location 块)</h4>
<p><code>location</code>&nbsp;块是&nbsp;<code>server</code>&nbsp;块的子配置,用于 &ldquo;按请求路径匹配处理逻辑&rdquo;,是 Nginx 路由配置的核心。一个&nbsp;<code>server</code>&nbsp;块可包含多个&nbsp;<code>location</code>&nbsp;块,按匹配优先级执行。</p>
<h5>核心指令解析</h5>
<table><thead><tr><th>指令</th><th>作用</th><th>配置示例</th><th></th></tr></thead><tbody><tr><td><code>location 匹配规则</code></td><td>定义请求路径的匹配规则,支持多种匹配模式(见下文)</td><td>- 前缀匹配:<code>location /api/ { ... }</code>- 精确匹配:<code>location = /index.html { ... }</code>- 正则匹配:`location ~* .(jpg</td><td>png)$ { ... }`</td></tr><tr><td><code>root</code></td><td>定义静态资源的根目录,请求路径会拼接在&nbsp;<code>root</code>&nbsp;后,形成文件的绝对路径</td><td><code>location /static/ { root /usr/local/nginx/; }</code>&nbsp;&rarr; 访问&nbsp;<code>/static/img.jpg</code>&nbsp;时,实际路径为&nbsp;<code>/usr/local/nginx/static/img.jpg</code></td><td></td></tr><tr><td><code>alias</code></td><td>定义路径别名,直接替换请求路径,与&nbsp;<code>root</code>&nbsp;不同(<code>alias</code>&nbsp;不拼接路径)</td><td><code>location /static/ { alias /usr/local/nginx/static/; }</code>&nbsp;&rarr; 效果同上,但更灵活(可自定义别名路径)</td><td></td></tr><tr><td><code>index</code></td><td>定义默认首页文件,当请求路径为目录时,自动查找该文件</td><td><code>index index.html index.htm index.php;</code></td><td></td></tr><tr><td><code>try_files</code></td><td>按顺序尝试访问文件 / 目录,若前面的路径不存在,执行最后一个动作(如跳转、返回 404)</td><td><code>try_files $uri $uri/ /index.html;</code>&nbsp;&rarr; 尝试访问文件&rarr;目录&rarr;跳转至 index.html(SPA 应用路由配置)</td><td></td></tr><tr><td><code>proxy_pass</code></td><td>反向代理指令,将请求转发到后端服务(如 Tomcat、负载均衡集群)</td><td><code>proxy_pass http://backend_servers;</code>(转发到 upstream 集群)或&nbsp;<code>proxy_pass http://127.0.0.1:8080;</code>(转发到本地服务)</td><td></td></tr><tr><td><code>expires</code></td><td>配置浏览器缓存时间,适用于静态资源(图片、CSS、JS)</td><td><code>expires 7d;</code>(缓存 7 天),减少重复请求,提升访问速度</td><td></td></tr><tr><td><code>error_page</code></td><td>配置错误页面跳转,当请求返回指定状态码时,跳转至对应的页面或路径</td><td><code>error_page 404 /404.html;</code>(404 错误跳转至 404.html)</td><td></td></tr></tbody></table>
<h5>location 匹配模式与优先级(关键)</h5>
<table><thead><tr><th>匹配模式</th><th>语法</th><th>优先级</th><th>说明</th><th></th></tr></thead><tbody><tr><td>精确匹配</td><td><code>location = /path { ... }</code></td><td>1(最高)</td><td>完全匹配请求路径,不包含子路径,例如&nbsp;<code>= /index.html</code>&nbsp;仅匹配&nbsp;<code>/index.html</code>,不匹配&nbsp;<code>/index.html?a=1</code></td><td></td></tr><tr><td>前缀匹配(^~)</td><td><code>location ^~ /path { ... }</code></td><td>2</td><td>以&nbsp;<code>/path</code>&nbsp;开头的路径,匹配成功后不再检查其他模式</td><td></td></tr><tr><td>正则匹配(~ 区分大小写,~* 不区分大小写)</td><td>`location ~* .(jpg</td><td>png)$ { ... }`</td><td>3</td><td>按正则表达式匹配路径,优先级低于精确匹配和 ^~ 前缀匹配</td></tr><tr><td>普通前缀匹配</td><td><code>location /path { ... }</code></td><td>4(最低)</td><td>以&nbsp;<code>/path</code>&nbsp;开头的路径,匹配成功后仍会检查更高优先级的模式</td><td></td></tr></tbody></table>
<h5>流量流程中的作用:</h5>
<p>请求匹配到&nbsp;<code>server</code>&nbsp;块后,进入&nbsp;<code>location</code>&nbsp;块匹配流程:</p>
<ol><li>按优先级顺序匹配所有&nbsp;<code>location</code>&nbsp;块的规则;</li><li>匹配成功后,执行该&nbsp;<code>location</code>&nbsp;块的处理逻辑:<ul><li>若为静态资源请求(如图片、HTML):通过&nbsp;<code>root</code>/<code>alias</code>&nbsp;找到文件,返回给客户端(开启 gzip 压缩、缓存等);</li><li>若为动态请求(如&nbsp;<code>/api</code>):通过&nbsp;<code>proxy_pass</code>&nbsp;转发到后端服务,接收后端响应后返回给客户端;</li></ul></li><li>若未匹配到任何&nbsp;<code>location</code>&nbsp;块,执行&nbsp;<code>server</code>&nbsp;块的默认逻辑(如返回 404)。</li></ol>
<p class="maodian"><a name="_lab2_0_4"></a></p><h3>五、Nginx 虚拟主机</h3>
<p>虚拟主机(Virtual Host)是指在一台服务器上通过 Nginx 配置,同时运行多个独立的 Web 服务(多个网站),共享服务器的 IP 和端口资源,通过&nbsp;<code>server_name</code>、IP、端口区分不同服务。</p>
<p class="maodian"><a name="_label3_0_4_10"></a></p><h4>5.1 访问状态统计配置</h4>
<p>Nginx 提供&nbsp;<code>ngx_http_stub_status_module</code>&nbsp;模块,用于统计 Nginx 的连接状态(如活跃连接数、请求数),需在编译时启用(<code>--with-http_stub_status_module</code>)。</p>
<h5>配置步骤:</h5>
<ol><li>编辑&nbsp;<code>nginx.conf</code>&nbsp;的&nbsp;<code>server</code>&nbsp;块,添加&nbsp;<code>location</code>&nbsp;块:</li></ol>
<p>nginx</p>
<div class="jb51code"><pre class="brush:plain;">server {
    listen 80;
    server_name www.test.com;
    # 访问状态统计配置
    location /nginx_status {
      stub_status on;               # 开启状态统计
      allow 192.168.1.0/24;         # 允许访问的IP网段(内网)
      deny all;                     # 拒绝其他所有IP访问,保障安全
    }
}</pre></div>
<ol><li>验证配置并重载 Nginx:</li></ol>
<div class="jb51code"><pre class="brush:bash;">nginx -t# 检查配置语法
nginx -s reload# 重载配置</pre></div>
<ol><li>访问测试:在允许的 IP 网段内,通过浏览器或 curl 访问&nbsp;<code>http://www.test.com/nginx_status</code>,输出结果如下:</li></ol>
<p>plaintext</p>
<div class="jb51code"><pre class="brush:plain;">Active connections: 2# 当前活跃连接数(包含等待连接)
server accepts handled requests
100 100 200# 累计接收连接数、累计处理连接数、累计请求数
Reading: 0 Writing: 1 Waiting: 1# 正在读取请求头的连接数、正在写入响应的连接数、等待请求的连接数(长连接)</pre></div>
<p class="maodian"><a name="_label3_0_4_11"></a></p><h4>5.2 基于授权的访问控制(HTTP 基本认证)</h4>
<p>通过用户名 / 密码验证客户端身份,仅授权用户可访问网站,适用于后台管理系统、内部服务等场景。</p>
<h5>配置步骤:</h5>
<ol><li>安装&nbsp;<code>htpasswd</code>&nbsp;工具(用于生成密码文件):</li></ol>
<div class="jb51code"><pre class="brush:bash;">yum install -y httpd-tools# CentOS/RHEL
apt install -y apache2-utils# Ubuntu/Debian</pre></div>
<ol><li>生成密码文件(用户名:admin,密码:123456):</li></ol>
<div class="jb51code"><pre class="brush:bash;">htpasswd -c /usr/local/nginx/conf/.htpasswd admin
# 输入密码(123456),生成密码文件 .htpasswd(隐藏文件,避免泄露)</pre></div>
<ol><li>编辑 Nginx 配置,添加授权控制:</li></ol>
<div class="jb51code"><pre class="brush:plain;">server {
    listen 80;
    server_name admin.test.com;
    location / {
      root /usr/local/nginx/admin;# 后台管理系统根目录
      index index.html;
      auth_basic "请输入用户名密码";# 认证提示信息
      auth_basic_user_file /usr/local/nginx/conf/.htpasswd;# 密码文件路径
    }
}</pre></div>
<ol><li>验证配置并重载 Nginx:</li></ol>
<div class="jb51code"><pre class="brush:bash;">nginx -t &amp;&amp; nginx -s reload</pre></div>
<ol><li>访问测试:访问&nbsp;<code>http://admin.test.com</code>,浏览器会弹出登录框,输入正确的用户名(admin)和密码(123456)才能访问,错误则返回 401 Unauthorized。</li></ol>
<p class="maodian"><a name="_label3_0_4_12"></a></p><h4>5.3 基于客户端的访问控制(IP 黑白名单)</h4>
<p>通过限制客户端的 IP 地址,允许或拒绝特定 IP / 网段访问,适用于防止恶意攻击、仅允许内网访问等场景。Nginx 支持两种配置方式:<code>allow/deny</code>&nbsp;指令(简单)和&nbsp;<code>ngx_http_limit_req_module</code>&nbsp;模块(限流)。</p>
<h5>5.3.1 allow/deny 指令(IP 黑白名单)</h5>
<div class="jb51code"><pre class="brush:plain;">server {
    listen 80;
    server_name www.test.com;
    location / {
      root /usr/local/nginx/html;
      index index.html;
      # 允许的IP/网段(白名单)
      allow 192.168.1.100;# 允许单个IP
      allow 192.168.1.0/24;# 允许192.168.1.0网段
      allow 127.0.0.1;# 允许本地访问
      deny all;# 拒绝其他所有IP(必须放在最后,顺序影响结果)
    }
    # 仅拒绝特定IP(黑名单)
    location /api/ {
      deny 10.0.0.1;# 拒绝10.0.0.1访问
      deny 172.16.0.0/16;# 拒绝172.16.0.0网段
      allow all;# 允许其他所有IP
    }
}</pre></div>
<ul><li>规则:<code>allow</code>&nbsp;和&nbsp;<code>deny</code>&nbsp;按配置顺序执行,匹配到第一个规则后立即生效;</li><li>适用场景:简单的 IP 限制,如仅允许内网访问后台服务。</li></ul>
<h5>5.3.2 基于访问频率的控制(限流)</h5>
<p>通过&nbsp;<code>ngx_http_limit_req_module</code>&nbsp;模块,限制单个客户端的访问频率(如每秒最多 10 个请求),防止恶意请求压垮服务器。</p>
<p>nginx</p>
<div class="jb51code"><pre class="brush:plain;">http {
    # 定义限流规则:以客户端IP为key,缓存区大小10M,访问频率10r/s(每秒10个请求)
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
    server {
      listen 80;
      server_name www.test.com;
      location / {
            limit_req zone=one burst=5 nodelay;# 应用限流规则
            # burst=5:允许突发5个请求(超过10r/s的部分,最多5个排队)
            # nodelay:突发请求不排队,直接返回503(避免客户端等待)
            root /usr/local/nginx/html;
            index index.html;
      }
    }
}</pre></div>
<ul><li>测试:通过&nbsp;<code>ab -n 100 -c 10 http://www.test.com/</code>&nbsp;模拟高并发请求,超过频率限制的请求会返回 503 Service Temporarily Unavailable。</li></ul>
<p class="maodian"><a name="_label3_0_4_13"></a></p><h4>5.4 基于域名的 Nginx 虚拟主机</h4>
<p><strong>核心原理</strong>:服务器绑定多个域名(如&nbsp;<code>www.test1.com</code>、<code>www.test2.com</code>),所有域名解析到同一服务器 IP;Nginx 通过&nbsp;<code>server_name</code>&nbsp;匹配客户端请求的&nbsp;<code>Host</code>&nbsp;头,分发到对应的虚拟主机。</p>
<h5>配置步骤:</h5>
<ol><li>服务器绑定多个域名(需在 DNS 服务器配置解析,本地测试可修改&nbsp;<code>/etc/hosts</code>):</li></ol>
<div class="jb51code"><pre class="brush:bash;"># 本地测试:编辑 /etc/hosts,添加域名映射
echo "192.168.1.100 www.test1.com www.test2.com" &gt;&gt; /etc/hosts</pre></div>
<ol><li>准备两个网站的根目录和测试页面:</li></ol>
<div class="jb51code"><pre class="brush:bash;"># 网站1:www.test1.com
mkdir -p /usr/local/nginx/html/test1
echo "&lt;h1&gt;Test1 Website&lt;/h1&gt;" &gt; /usr/local/nginx/html/test1/index.html
# 网站2:www.test2.com
mkdir -p /usr/local/nginx/html/test2
echo "&lt;h1&gt;Test2 Website&lt;/h1&gt;" &gt; /usr/local/nginx/html/test2/index.html</pre></div>
<ol><li>编辑 Nginx 配置,添加两个&nbsp;<code>server</code>&nbsp;块:</li></ol>
<div class="jb51code"><pre class="brush:plain;"># 虚拟主机1:www.test1.com
server {
    listen 80;
    server_name www.test1.com;
    location / {
      root /usr/local/nginx/html/test1;
      index index.html;
    }
}
# 虚拟主机2:www.test2.com
server {
    listen 80;
    server_name www.test2.com;
    location / {
      root /usr/local/nginx/html/test2;
      index index.html;
    }
}</pre></div>
<ol><li>验证配置并重载 Nginx:</li></ol>
<div class="jb51code"><pre class="brush:bash;">nginx -t &amp;&amp; nginx -s reload</pre></div>
<ol><li>访问测试:</li></ol>
<ul><li>访问&nbsp;<code>http://www.test1.com</code>,显示&nbsp;<code>Test1 Website</code>;</li><li>访问&nbsp;<code>http://www.test2.com</code>,显示&nbsp;<code>Test2 Website</code>。</li></ul>
<p class="maodian"><a name="_label3_0_4_14"></a></p><h4>5.5 基于 IP 的 Nginx 虚拟主机</h4>
<p><strong>核心原理</strong>:服务器配置多个 IP 地址(如&nbsp;<code>192.168.1.100</code>、<code>192.168.1.101</code>);Nginx 通过&nbsp;<code>listen</code>&nbsp;指令绑定不同的 IP,客户端访问不同的 IP 时,匹配到对应的虚拟主机。</p>
<h5>配置步骤:</h5>
<ol><li>给服务器添加多个 IP(以 CentOS 7 为例):</li></ol>
<div class="jb51code"><pre class="brush:bash;"># 临时添加IP(重启网络失效)
ifconfig ens33:1 192.168.1.101 netmask 255.255.255.0 up
# 永久添加IP:编辑网卡配置文件
cat &gt; /etc/sysconfig/network-scripts/ifcfg-ens33:1 &lt;&lt; EOF
TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.1.101
NETMASK=255.255.255.0
DEVICE=ens33:1
ONBOOT=yes
EOF
# 重启网络
systemctl restart network</pre></div>
<ol><li>准备两个网站的根目录(同 5.4 步骤 2);</li><li>编辑 Nginx 配置,<code>listen</code>&nbsp;绑定不同 IP:</li></ol>
<p>nginx</p>
<div class="jb51code"><pre class="brush:plain;"># 虚拟主机1:绑定192.168.1.100
server {
    listen 192.168.1.100:80;# 绑定IP+端口
    server_name 192.168.1.100;
    location / {
      root /usr/local/nginx/html/test1;
      index index.html;
    }
}
# 虚拟主机2:绑定192.168.1.101
server {
    listen 192.168.1.101:80;
    server_name 192.168.1.101;
    location / {
      root /usr/local/nginx/html/test2;
      index index.html;
    }
}</pre></div>
<ol><li>验证配置并重载 Nginx;</li><li>访问测试:</li></ol>
<ul><li>访问&nbsp;<code>http://192.168.1.100</code>,显示&nbsp;<code>Test1 Website</code>;</li><li>访问&nbsp;<code>http://192.168.1.101</code>,显示&nbsp;<code>Test2 Website</code>。</li></ul>
<p class="maodian"><a name="_label3_0_4_15"></a></p><h4>5.6 基于端口的 Nginx 虚拟主机</h4>
<p><strong>核心原理</strong>:Nginx 的不同&nbsp;<code>server</code>&nbsp;块监听不同的端口(如 80、8080、8888);客户端通过 &ldquo;IP + 端口&rdquo; 访问,Nginx 根据端口匹配对应的虚拟主机,是最简单的虚拟主机配置方式。</p>
<h5>配置步骤:</h5>
<ol><li>准备两个网站的根目录(同 5.4 步骤 2);</li><li>编辑 Nginx 配置,<code>listen</code>&nbsp;绑定不同端口:</li></ol>
<p>nginx</p>
<div class="jb51code"><pre class="brush:plain;"># 虚拟主机1:监听80端口
server {
    listen 80;
    server_name 192.168.1.100;
    location / {
      root /usr/local/nginx/html/test1;
      index index.html;
    }
}
# 虚拟主机2:监听8080端口
server {
    listen 8080;
    server_name 192.168.1.100;
    location / {
      root /usr/local/nginx/html/test2;
      index index.html;
    }
}</pre></div>
<ol><li>开放端口(若防火墙开启):</li></ol>
<div class="jb51code"><pre class="brush:bash;">firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload</pre></div>
<ol><li>验证配置并重载 Nginx;</li><li>访问测试:</li></ol>
<ul><li>访问&nbsp;<code>http://192.168.1.100:80</code>,显示&nbsp;<code>Test1 Website</code>;</li><li>访问&nbsp;<code>http://192.168.1.100:8080</code>,显示&nbsp;<code>Test2 Website</code>。</li></ul>
<p class="maodian"><a name="_label3_0_4_16"></a></p><h4>三种虚拟主机对比</h4>
<table><thead><tr><th>类型</th><th>核心区分依据</th><th>适用场景</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>基于域名</td><td><code>server_name</code>(域名)</td><td>多网站共享同一 IP + 端口(如共享 80/443),互联网场景最常用</td><td>用户友好(无需记端口),节省 IP 资源</td><td>需配置 DNS 解析,本地测试需修改 hosts</td></tr><tr><td>基于 IP</td><td><code>listen</code>(绑定 IP)</td><td>服务器有多个 IP,需区分不同 IP 对应的服务(如内网 / 外网服务分离)</td><td>配置简单,无需依赖 DNS</td><td>浪费 IP 资源,IP 数量有限</td></tr><tr><td>基于端口</td><td><code>listen</code>(端口)</td><td>测试环境、内部服务(如后台管理系统),无需域名解析</td><td>配置最简单,无需额外资源</td><td>用户需记端口(如 8080),不适合互联网场</td></tr></tbody></table>
<p>到此这篇关于Nginx概念、架构、配置与虚拟主机实战操作指南的文章就介绍到这了,更多相关nginx架构与虚拟主机内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
頁: [1]
查看完整版本: Nginx概念、架构、配置与虚拟主机实战操作指南