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;
        }
    }
}
相关推荐
XIAOHEZIcode18 小时前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220701 天前
如何搭建本地yum源(上)
运维
ping某3 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树884 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质4 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工4 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智4 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_4 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉5 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造