nginx 介绍及作用

1 nginx 介绍

Nginx(Engine X)是一款高性能的 HTTP/反向代理服务器及邮件(IMAP/POP3)代理服务器,采用事件驱动、异步非阻塞的架构,内存占用少、并发处理能力强。适合作为静态文件服务器、反向代理、负载均衡器与 API 网关的边缘组件。

补充要点:

  • 常见部署形式:单机 + 负载均衡(前置 LB),或作为集群的边缘入口(搭配 Keepalived/HAProxy)实现高可用。
  • 模块化:核心 + 可选模块(如 http_gzip_modulehttp_stub_status_modulehttp_v2_module 等),开源版与商业版(Nginx Plus)功能略有差异(例如主动健康检查、内置 Dashboard 等)。
  • 常见性能指标:worker_processesworker_connectionskeepalive_timeoutsendfiletcp_nopushtcp_nodelay 等。

参考文章------Nginx详解(一文带你搞懂Nginx)

2 反向代理

2.1 正向代理和反向代理

  • 正向代理:客户端知道代理,客户端把请求发给代理,由代理代表客户端去请求目标服务器。常用于客户端侧的访问控制、缓存、突破地域限制或匿名上网。

    • 绕过地域限制(翻墙/访问被封锁的站点)
    • 企业或学校的上网审计、过滤、访问控制与缓存(节省带宽)
    • 客户端隐私/匿名(隐藏真实 IP)
    • 客户端调试(通过代理抓包、修改请求)
  • 反向代理:客户端不知道代理,客户端把请求发给看起来像目标服务器(或目标域名)的代理,代理再把请求转发给一个或多个后端服务。常用于负载均衡、SSL 终端、请求路由、缓存、WAF 等。

    • 负载均衡(把流量分发到多台后端)
    • SSL/TLS 终止(在代理处解密,后端使用 HTTP)
    • 服务聚合、URL 路由、API 网关功能(认证、限流、熔断)
    • 缓存静态或部分动态内容、减轻后端压力
    • 安全防护(WAF、IP 限制、隐藏真实后端拓扑)
特性 正向代理(Forward) 反向代理(Reverse)
谁主动配置代理? 客户端(浏览器/系统) 服务端(DNS 指向/负载均衡)
目标服务器看到的 IP 看到代理 IP(不是客户端) 看到的是反向代理 IP(后端看不到真实客户端,除非代理透传)
常见用途 绕过限制、缓存、审计、匿名 负载均衡、SSL 终止、缓存、路由、WAF
典型软件 Squid、Shadowsocks、V2Ray、SSH -D Nginx、HAProxy、Cloudflare、Kong
是否对外公开后端拓扑? 不改变目标服务器拓扑 隐藏后端拓扑(对外只暴露代理)

2.2 配置案例

2.2.1 示例1 最简单的反向代理(单一后端)
nginx 复制代码
# 说明:对外暴露 80,将所有 /api/ 请求转发到后端服务(带路径替换)
server {
    listen 80;
    server_name example.com;

    # 限制上传大小(常用于文件上传服务)
    client_max_body_size 50m;

    location /api/ {
        # 转发到后端(末尾带 / 表示替换前缀)
        proxy_pass http://10.0.0.10:8080/;

        # 常用代理头,保留客户端真实 IP 等
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 超时设置(适当增大以防长请求被切断)
        proxy_connect_timeout 5s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # WebSocket 支持(若后端需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

注解:proxy_pass 末尾的 / 决定是否保留 location 的匹配前缀。

2.2.2 示例2 反向代理 + 静态与应用分离
nginx 复制代码
# 说明:/static/ 由 Nginx 直接提供,/ 替代理到应用服务器
server {
    listen 80;
    server_name app.example.com;

    root /var/www/app;   # 存放静态文件的本地路径
    index index.html;

    # 静态资源优先
    location /static/ {
        alias /var/www/app/static/;   # alias 与 root 的区别:alias 用于替换 location
        expires 30d;                  # 浏览器缓存时间
        add_header Cache-Control "public";
        try_files $uri $uri/ =404;
    }

    # 其余请求代理到应用
    location / {
        proxy_pass http://127.0.0.1:3000;
        include proxy_params;  # 推荐把公共 header 放在单独文件中
    }
}

在 Nginx 配置中,rootindex 指令共同决定了静态文件的处理逻辑。以下是具体作用和示例说明:

root** 指令**

作用 :设置请求的根目录路径。当 Nginx 处理请求时,会将 URL 路径拼接到 root 指定的路径后,形成完整的本地文件路径。

示例

  • 请求:http://app.example.com/images/logo.png
    Nginx 会查找文件:/var/www/app/images/logo.png
    root 路径 /var/www/app + URL 路径 /images/logo.png
  • 请求:http://app.example.com/about/index.html
    Nginx 会查找文件:/var/www/app/about/index.html

index** 指令**

作用:定义当请求指向目录(而非具体文件)时,默认返回的文件名列表。Nginx 会按顺序检查列表中的文件是否存在,返回第一个匹配的文件。

示例

  • 请求:http://app.example.com/(指向根目录)
    Nginx 会尝试按顺序查找:
    /var/www/app/index.html → 若存在则返回该文件;
    若不存在,则继续执行 location / 的代理规则(转发到后端应用)。
  • 请求:http://app.example.com/docs/(指向目录)
    Nginx 会尝试查找:
    /var/www/app/docs/index.html → 返回该文件(如果存在)。

关键注意事项

  1. 静态文件优先级
    location /static/ 优先于 location /
    • 请求 http://app.example.com/static/style.css → 由 Nginx 直接返回文件(不代理到后端)。
    • 请求 http://app.example.com/api/data → 代理到后端应用服务器(http://127.0.0.1:3000/api/data)。
  2. 目录请求的处理流程
    • 若请求以 / 结尾(如 http://app.example.com/),Nginx 会尝试返回 index 指定的文件(如 index.html)。
    • index 文件不存在,请求会落入 location / 被代理到后端(由后端应用处理)。
  3. alias** vs **root
    • location /static/ 使用 alias:URL 中的 /static/ 会被替换为 /var/www/app/static/
      示例:请求 /static/logo.png → 实际文件路径为 /var/www/app/static/logo.png
    • 若此处改用 root,路径会变为 /var/www/app/static/logo.png(多一层 /static)。

总结

  • root:定义静态文件的根目录基础路径。
  • index:指定目录请求的默认返回文件。
  • 协作效果:两者结合确保 Nginx 能高效处理静态资源(如 HTML、CSS、图片),并将动态请求无缝转发到后端应用。
2.2.3 示例3 反向代理 + 按路径分发到不同后端(微服务网关场景)
nginx 复制代码
# 说明:把不同 API 路径路由到不同后端服务
upstream auth_service {
    server 10.0.0.11:8081;
    server 10.0.0.12:8081;
}

upstream user_service {
    server 10.0.0.21:8080;
}

server {
    listen 80;
    server_name api.example.com;

    location /auth/ {
        proxy_pass http://auth_service/;  # 注意末尾 /
        include proxy_params;
    }

    location /user/ {
        proxy_pass http://user_service/;
        include proxy_params;
    }
}
2.2.4 示例4 支持 HTTPS 的反向代理(SSL 终止)
nginx 复制代码
server {
    listen 443 ssl http2;
    server_name secure.example.com;

    ssl_certificate /etc/ssl/certs/example.crt;
    ssl_certificate_key /etc/ssl/private/example.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        # SSL 在这里终止,后端可以使用 HTTP
        proxy_pass http://127.0.0.1:8080;
        include proxy_params;
    }
}

注:生产环境建议开启强安全配置(OCSP stapling、HSTS、现代 TLS 配置),在生产完整配置中会给出建议项。

2.2.5 案例5 基本的HTTP反向代理

将访问 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">nginx-proxy.com</font> 的请求代理到运行在 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://localhost:8080</font> 的后端Java应用。

nginx 复制代码
http {
    server {
        listen 80; # 监听80端口
        server_name nginx-proxy.com; # 指定域名

        location / {
            # 核心代理指令,将请求转发到 upstream 或指定地址
            proxy_pass http://localhost:8080;

            # 以下是一些常用的代理头设置,用于向后端传递客户端信息
            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到XFF头
            proxy_set_header X-Forwarded-Proto $scheme; # 传递客户端使用的协议(http/https)

            # 连接超时、发送超时、读取超时时间(单位:秒)
            proxy_connect_timeout 30;
            proxy_send_timeout 30;
            proxy_read_timeout 60;
        }
    }
}
2.2.6 案例6 根据路径反向代理到不同服务
  • <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/api/</font> 开头的请求代理到后端API服务器 (<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://api-backend:3000</font>)。
  • 其他所有请求代理到前端静态服务器 (<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://frontend:80</font>)。
nginx 复制代码
http {
    server {
        listen 80;
        server_name my-app.com;

        # 代理 /api/ 路径到后端API服务
        location /api/ {
            proxy_pass http://api-backend:3000/; # 注意结尾的 /,它会将 /api/xxx 转换为 /xxx 传递给后端
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 代理所有其他请求到前端服务
        location / {
            proxy_pass http://frontend:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

3 负载均衡

3.1 负载均衡 介绍

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

简单来说就是:现有的请求使服务器压力太大无法承受,所有我们需要搭建一个服务器集群,去分担原先一个服务器所承受的压力。Nginx提供了多种负载均衡算法:

  1. 轮询 (Round Robin): 默认方法。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器宕机,能自动剔除。
  2. 加权轮询 (Weighted Round Robin) : 指定轮询几率,<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">weight</font>(权重)和访问比率成正比。用于后端服务器性能不均的情况。权重越高,被分配到的概率越大。
  3. IP哈希 (ip_hash): 每个请求按访问IP的hash结果分配。这样每个访客固定访问一个后端服务器,可以解决Session共享的问题(但非最佳方案,通常建议使用共享Session存储)。

上述方式存在一个问题就是说,在负载均衡系统中,假如用户在某台服务器上登录了,那么该用户第二次请求的时候,因为我们是负载均衡系统,每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的。

我们可以采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

  1. 最少连接 (least_conn): 优先将请求分配给当前连接数最少的后端服务器。

3.2 配置案例

3.2.1 案例1 最简单的轮询(默认)
nginx 复制代码
upstream backend_rr {
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

server {
    listen 80;
    server_name lb.example.com;

    location / {
        proxy_pass http://backend_rr;
        include proxy_params;
    }
}
3.2.2 案例2 加权轮询(weight)
nginx 复制代码
upstream backend_weight {
    server 10.0.0.11:8080 weight=3;  # 更强的服务器,3 倍权重
    server 10.0.0.12:8080 weight=1;
}

# 使用方式与上文相同
3.2.3 案例3 ip_hash(会话亲和)
nginx 复制代码
upstream backend_iphash {
    ip_hash;  # 依据客户端 IP 哈希选择后端
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

注意:ip_hashweight 不能同时使用;并且当后端池发生变更(添加/删除节点)时,会话亲和性会打破。

3.2.4 案例4 least_conn(最少连接)
nginx 复制代码
upstream backend_leastconn {
    least_conn;
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}
3.2.5 案例5 keepalive 与被动健康检查
nginx 复制代码
upstream backend_keepalive {
    server 10.0.0.11:8080 max_fails=3 fail_timeout=30s;  # 被动剔除(3 次失败,30s 内视为 down)
    server 10.0.0.12:8080 max_fails=3 fail_timeout=30s;

    keepalive 32;   # 与后端保持 32 个空闲连接复用
}

server {
    listen 80;

    location / {
        proxy_pass http://backend_keepalive;
        proxy_http_version 1.1;
        proxy_set_header Connection "";   # 允许复用 keepalive
        include proxy_params;
    }
}

说明:被动健康检查靠 max_fails + fail_timeout。如需主动健康检查,推荐:Nginx Plus、nginx_upstream_check_module 或外部探活(例如 Kubernetes readiness probe 或 Keepalived + 脚本)。

4.1 动静分离介绍

Nginx的静态资源处理能力非常高效(得益于高效的异步非阻塞事件处理模型和<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">sendfile</font>等系统调用),而动态内容处理(如PHP、Python程序)通常由专门的应用服务器(如Tomcat, uWSGI, PHP-FPM)负责。动静分离技术通过代理的方式,在<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">server{}</font>配置段中使用带正则匹配的<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">location</font>指令,将静态资源(如图片、JS、CSS、HTML)的请求直接由Nginx本地处理,而动态请求则代理给后端的应用服务器处理。这样做可以:

  • 减轻应用服务器的负载,让其专注于处理动态请求。
  • 充分利用Nginx的高效特性来快速响应静态资源请求。
  • 可以方便地对静态资源进行缓存优化。

4.2 配置案例

4.2.1 案例1 经典的动静分离配置

假设静态文件存放在 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/data/www/static</font>,动态请求需要代理到 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://tomcat-app:8080</font>

nginx 复制代码
http {
    server {
        listen 80;
        server_name www.example.com;
        root /data/www; # 设置服务器默认根目录

        #  location ~* \.(gif|jpg|jpeg|png|css|js|ico|html)$ 是更常见的匹配静态文件的正则写法
        # 处理静态资源请求 (图片、样式、脚本等)
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css|js|flv|ico)$ {
            # 指定静态文件的实际存放路径
            root /data/www/static;
            # 启用高效文件传输 sendfile
            sendfile on;
            # 防止某些系统安全限制问题
            sendfile_max_chunk 1m;
            # 设置浏览器缓存过期时间,减少重复请求
            expires 30d; # 缓存30天
            # 尝试直接返回文件,如果没找到则继续寻找其他location或返回404
            try_files $uri $uri/ =404;
        }

        # 处理所有动态请求,代理到Tomcat
        location / {
            proxy_pass http://tomcat-app:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}
4.2.2 案例2 更清晰的路径分

将静态路径 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/static/</font> 和动态路径 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/api/</font> 明确分开。

nginx 复制代码
http {
    server {
        listen 80;
        server_name api-static-site.com;
        root /usr/share/nginx/html;

        # 所有 /static/ 路径下的请求被认为是静态资源
        location /static/ {
            # 静态文件目录,alias 路径末尾必须加 /
            alias /usr/share/nginx/html/static/;
            # 启用sendfile
            sendfile on;
            # 设置缓存
            expires max;
            # 关闭日志记录静态资源请求以提升性能(可选)
            access_log off;
        }

        # 所有 /api/ 路径下的请求被认为是动态API
        location /api/ {
            proxy_pass http://api-backend:8000/; # 注意末尾的 /,它会去除 /api 前缀
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        # 处理根路径和其他未匹配的请求,可以返回首页或代理到前端应用
        location / {
            try_files $uri $uri/ /index.html; # 常用于单页面应用(SPA)
            # 或者代理到一个前端服务器
            # proxy_pass http://frontend-server:3000;
        }
    }
}
4.2.3 案例3 静态资源缓存 + gzip
nginx 复制代码
http {
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1000;

    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

    server {
        listen 80;
        server_name cdn.example.com;

        location / {
            proxy_pass http://origin_server;
            proxy_cache my_cache;
            proxy_cache_valid 200 302 10m;
            proxy_cache_valid 404 1m;
            add_header X-Cache-Status $upstream_cache_status;
        }
    }
}
相关推荐
花开富贵贼富贵4 小时前
Nginx 反向代理与缓存功能
运维·nginx·缓存
ybb_ymm4 小时前
Docker下的使用命令
运维·docker·容器
qq_10055170755 小时前
WordPress给指定分类文章添加一个自动化高亮(一键复制)功能
运维·前端·自动化·php
_BugMan6 小时前
docker实战:基础操作、镜像打包、网络、容器编排
运维·docker·容器
Clownseven6 小时前
2025开发者云服务器评测:AWS, Vercel, Railway该如何选?
运维·服务器·aws
一条懒鱼6666 小时前
Nginx反向代理与缓存功能
运维·nginx
AscendKing6 小时前
Docker 部署 Ollama 详细教程以及镜像高速下载地址
运维·docker·容器
努力努力再努力wz7 小时前
【C++进阶系列】:位图和布隆过滤器(附模拟实现的源码)
java·linux·运维·开发语言·数据结构·c++
wayuncn7 小时前
哈尔滨服务器托管优选-青蛙云
运维·服务器·服务器租用·服务器托管·物理机租用·idc服务商