06. Nginx 服务器

Nginx 服务器

Nginx 是一款高性能的HTTP和反向代理服务器。在高连接并发的情况下,能够支持高达5万个并发连接数的响应,而内存、CPU等系统资源消耗却非常低,运行非常稳定。

Nginx 部署

bash 复制代码
# 安装 nginx
[root@www ~]# yum -y install nginx

# 启动 nginx
[root@www ~]# systemctl enable nginx --now

# 准备主页
[root@www ~]# mv /usr/share/nginx/html/index.html{,.ori}
[root@www ~]# echo Hello World From Nginx > /usr/share/nginx/html/index.html

# 防火墙
[root@www ~]# firewall-cmd --add-service=http --permanent
[root@www ~]# firewall-cmd --reload

[root@client ~]# curl http://www.migaomei.cloud

# windows客户端修改 C:\Windows\System32\drivers\etc\hosts
# Linux或Unix修改 /etc/hosts
# 添加如下记录
10.1.8.10 www.migaomei.cloud

Nginx 配置

配置结构

Nginx 配置采用层级化、模块化的组织方式,整体是 "全局块 → 核心模块块 → 业务模块块" 的嵌套结构。

1. 全局配置块

作用于 Nginx 整个进程的基础配置,不嵌套在任何块内,是配置文件的 "根级别"。

nginx 复制代码
# 全局配置示例
user nginx;                  # 运行Nginx的用户/用户组
worker_processes auto;       # 工作进程数(核心参数,建议设为CPU核心数)
error_log /var/log/nginx/error.log;  # 错误日志路径
pid /run/nginx.pid;          # 主进程PID文件路径
include /usr/share/nginx/modules/*.conf;  # 加载外部模块配置(全局级引入)
2. 核心模块 块

Nginx 的核心功能模块 events 块,用于处理网络连接相关配置。

nginx 复制代码
events {
    worker_connections 1024;  # 每个工作进程的最大并发连接数
    use epoll;                # 事件驱动模型(epoll是Linux下高性能选择)
    multi_accept on;          # 允许一个进程一次性接受多个新连接
}
3. 业务模块 块

处理具体业务的核心配置块,最核心的是 http 块(HTTP/HTTPS 服务),可以包含多个 server 块(虚拟主机)。

nginx 复制代码
# http块:所有HTTP/HTTPS服务的公共配置,可嵌套多个server块
http {
    # HTTP全局公共配置
    include       /etc/nginx/mime.types;  # 加载MIME类型映射
    default_type  application/octet-stream; # 默认响应类型
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request"'; # 日志格式
    access_log  /var/log/nginx/access.log  main; # 访问日志
    sendfile     on;  # 高效文件传输开关
    keepalive_timeout  65;  # 长连接超时时间

    # server块:虚拟主机配置(一个http块可包含多个server)
    server {
        listen       80;  # 监听端口(80=HTTP,443=HTTPS)
        server_name  localhost;  # 域名/IP(可配置多个,用空格分隔)
        root         /usr/share/nginx/html;  # 网站根目录

        # location块:URL路径匹配规则(一个server块可包含多个location)
        location / {
            index  index.html index.htm;  # 默认首页
            try_files $uri $uri/ /index.html;  # 路径匹配规则
        }

        # 错误页面配置
        error_page  404              /404.html;
        error_page  500 502 503 504  /50x.html;
    }

    # 第二个虚拟主机(示例)
    server {
        listen       8080;
        server_name  test.example.com;
        # ... 其他配置
    }
}
4. 特殊配置:HTTPS 专属块

如果配置 HTTPS,会在 server 块内增加 SSL 相关配置:

bash 复制代码
server {
    listen       443 ssl;  # 监听HTTPS端口并启用SSL
    server_name  example.com;

    # SSL证书配置
    ssl_certificate      /etc/nginx/cert/server.crt;  # 公钥文件
    ssl_certificate_key  /etc/nginx/cert/server.key;  # 私钥文件
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    # ... 其他配置(如root、location等)
}

配置加载机制

  1. include 指令 :Nginx 支持通过 include 引入外部配置文件,实现模块化管理。
    • 把不同虚拟主机配置拆到 /etc/nginx/conf.d/*.conf
    • 把不同代理配置拆到 /etc/nginx/default.d/*.conf
  2. 配置优先级:
    • 同层级:后定义的配置覆盖先定义的;
    • 不同层级:子级(如 location)覆盖父级(如 server/http);
    • location 匹配:精准匹配(=)> 正则匹配(~/~*)> 普通前缀匹配。

nginx.conf 配置详解

nginx 复制代码
# 更多配置详情参考官方文档:
#   * 英文官方文档: http://nginx.org/en/docs/
#   * 俄文官方文档: http://nginx.org/ru/docs/

# 指定Nginx工作进程的运行用户为nginx
user nginx;

# 工作进程数,设置为auto时会自动根据CPU核心数调整
worker_processes auto;

# 错误日志文件路径及存储位置
error_log /var/log/nginx/error.log;

# Nginx主进程PID文件路径,用于标识进程ID
pid /run/nginx.pid;

# 加载动态模块,详细说明可查看/usr/share/doc/nginx/README.dynamic文件
include /usr/share/nginx/modules/*.conf;

# 事件模块配置块,用于设置网络连接相关参数
events {
    # 每个工作进程的最大并发连接数,默认1024
    worker_connections 1024;
}

# HTTP核心模块配置块,包含HTTP服务的主要配置
http {
    # 定义访问日志的格式,命名为main
    # 日志字段说明:客户端IP - 远程用户 [访问时间] "请求信息" 状态码 发送字节数 "来源页面" "用户代理" "代理IP"
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # 启用访问日志,使用main格式,日志文件存储路径
    access_log  /var/log/nginx/access.log  main;

    # 启用高效文件传输模式,减少磁盘I/O和CPU消耗
    sendfile            on;

    # 启用TCP_NOPUSH选项,在发送响应时累积数据后一次性发送,提高网络效率(需配合sendfile使用)
    tcp_nopush          on;

    # 启用TCP_NODELAY选项,禁用Nagle算法,减少数据传输延迟(适用于实时性要求高的场景)
    tcp_nodelay         on;

    # HTTP长连接超时时间,超过65秒无活动则关闭连接
    keepalive_timeout   65;

    # 文件类型哈希表的最大容量,增大可提高文件类型查找效率
    types_hash_max_size 4096;

    # 引入MIME类型配置文件,定义不同文件后缀对应的响应类型
    include             /etc/nginx/mime.types;

    # 默认MIME类型,当无法识别文件类型时使用(二进制流格式)
    default_type        application/octet-stream;

    # 加载/etc/nginx/conf.d目录下的所有.conf后缀配置文件(模块化配置)
    # 更多说明参考http://nginx.org/en/docs/ngx_core_module.html#include
    include /etc/nginx/conf.d/*.conf;

    # 虚拟主机配置块(默认HTTP服务)
    server {
        # 监听IPv4的80端口(HTTP默认端口)
        listen       80;

        # 监听IPv6的80端口
        listen       [::]:80;

        # 虚拟主机域名,_表示匹配所有未明确指定的域名
        server_name  _;

        # 网站根目录,存放静态资源的路径
        root         /usr/share/nginx/html;

        # 加载默认虚拟主机的额外配置文件(来自/etc/nginx/default.d/*.conf)
        include /etc/nginx/default.d/*.conf;

        # 配置404错误页面,当请求资源不存在时返回/404.html
        error_page 404 /404.html;
        # 精确匹配/404.html的访问路径(无额外配置,直接返回文件)
        location = /404.html {
        }

        # 配置500/502/503/504服务器错误页面,返回/50x.html
        error_page 500 502 503 504 /50x.html;
        # 精确匹配/50x.html的访问路径(无额外配置,直接返回文件)
        location = /50x.html {
        }
    }

# TLS/SSL加密服务配置(默认注释,启用需取消注释并配置证书)
#
#    server {
#        # 监听IPv4的443端口(HTTPS默认端口),启用SSL和HTTP/2协议
#        listen       443 ssl http2;
#        # 监听IPv6的443端口,启用SSL和HTTP/2协议
#        listen       [::]:443 ssl http2;
#        # 虚拟主机域名(需替换为实际域名)
#        server_name  _;
#        # 网站根目录(与HTTP服务一致)
#        root         /usr/share/nginx/html;
#
#        # SSL证书文件路径(公钥)
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        # SSL证书密钥文件路径(私钥,需保密)
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        # SSL会话缓存配置:共享缓存,名称SSL,大小1MB
#        ssl_session_cache shared:SSL:1m;
#        # SSL会话超时时间,10分钟内再次连接无需重新握手
#        ssl_session_timeout  10m;
#        # SSL加密套件,优先选择高强度加密算法,排除aNULL和MD5
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        # 优先使用服务器端指定的加密套件
#        ssl_prefer_server_ciphers on;
#
#        # 加载默认虚拟主机的额外配置文件
#        include /etc/nginx/default.d/*.conf;
#
#        # 404错误页面配置(原配置笔误,应为/404.html,此处保留原注释结构)
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        # 服务器错误页面配置
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }
}

虚拟主机

同一个 web 服务器提供多个站点。

虚拟主机支持多种方式:

  1. 主机名
  2. 端口号
  3. IP地址(基本不用)

根据名称

bash 复制代码
# 参考主配置文件/etc/nginx/nginx.conf中server块配置
[root@www ~]# cp /etc/nginx/nginx.conf /etc/nginx/conf.d/vhost-name.conf
[root@www ~]# vim /etc/nginx/conf.d/vhost-name.conf
bash 复制代码
server {
    server_name  web1.migaomei.cloud;
    root         /usr/share/nginx/web1;
}
server {
    server_name  web2.migaomei.cloud;
    root         /usr/share/nginx/web2;
}
bash 复制代码
[root@www ~]# mkdir /usr/share/nginx/web{1,2}
[root@www ~]# echo web1.migaomei.cloud > /usr/share/nginx/web1/index.html
[root@www ~]# echo web2.migaomei.cloud > /usr/share/nginx/web2/index.html
[root@www ~]# systemctl restart nginx

客户端测试

bash 复制代码
# 配置名称解析,假设web服务器ip地址为10.1.8.10
10.1.8.10 web1.migaomei.cloud
10.1.8.10 web2.migaomei.cloud

[root@client ~]# curl http://web1.migaomei.cloud/
web1.migaomei.cloud
[root@client ~]# curl http://web2.migaomei.cloud/
web2.migaomei.cloud

提示:清理环境,避免影响后续实验。

bash 复制代码
[root@www ~]# mkdir /etc/nginx/conf.d/vhosts
[root@www ~]# mv /etc/nginx/conf.d/vhost-name.conf /etc/nginx/conf.d/vhosts

根据 port

bash 复制代码
[root@www ~]# vim /etc/nginx/conf.d/vhost-port.conf
bash 复制代码
server {
    listen       8081;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/8081;
}
server {
    listen       8082;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/8082;
}
bash 复制代码
[root@www ~]# mkdir /usr/share/nginx/808{1,2}
[root@www ~]# echo 8081 > /usr/share/nginx/8081/index.html
[root@www ~]# echo 8082 > /usr/share/nginx/8082/index.html
[root@www ~]# systemctl restart nginx

客户端测试

bash 复制代码
# 配置名称解析,假设web服务器ip地址为10.1.8.10
10.1.8.10 www.migaomei.cloud

[root@client ~]# curl http://www.migaomei.cloud:8081
8081
[root@client ~]# curl http://www.migaomei.cloud:8082
8082

提示:清理环境,避免影响后续实验。

配置 SSL/TLS

生成证书

bash 复制代码
#--1--生成私钥 
[root@www ~]# mkdir certs && cd certs
[root@www certs]# openssl genrsa -out www.key 2048  

#--2--生成请求文件csr
[root@www certs]# openssl req -new -key www.key -out www.csr -subj "/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.migaomei.cloud/emailAddress=webadmin@migaomei.cloud" 
# CN的值必须是网站域名

#--3--使用自己的私钥对请求文件签名,以生成证书 
[root@www certs]# openssl x509 -req -days 3650 -in www.csr -signkey www.key -out www.crt

配置站点

bash 复制代码
[root@www certs]# mkdir /etc/ssl/certs/www.migaomei.cloud
[root@www certs]# mv www* /etc/ssl/certs/www.migaomei.cloud

# 参照默认配置修改
[root@www ~]# cp /etc/nginx/nginx.conf /etc/nginx/conf.d/vhost-www.migaomei.cloud-ssl.conf
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.migaomei.cloud-ssl.conf
server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/html;
    # 证书
    ssl_certificate "/etc/ssl/certs/www.migaomei.cloud/www.crt";
    # 私钥
    ssl_certificate_key "/etc/ssl/certs/www.migaomei.cloud/www.key";
}

[root@www ~]# systemctl restart nginx

配置HTTP重定向到https

bash 复制代码
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.migaomei.cloud-ssl.conf
server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/html;
    # 证书
    ssl_certificate "/etc/ssl/certs/www.migaomei.cloud/www.crt";
    # 私钥
    ssl_certificate_key "/etc/ssl/certs/www.migaomei.cloud/www.key";
}

# 配置HTTP重定向到https
server {
    listen       80;
    listen       [::]:80;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/html;
    # 添加重定向
    return       301 https://$host$request_uri;
}
[root@www ~]# systemctl restart nginx

# 防火墙设置
[root@www ~]# firewall-cmd --add-service=https --permanent
[root@www ~]# firewall-cmd --reload

# 测试
[root@client ~]# curl http://www.migaomei.cloud/
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>

# 使用-k指明目标站点不是一个安全站点
[root@client ~]# curl -k https://www.migaomei.cloud/

# 使用-L指明跟随重定向
[root@client ~]# curl -Lk http://www.migaomei.cloud/

配置基本认证

用户名和密码使用plain text发送,所以最好配置SSL/TLS。

bash 复制代码
#安装工具
[root@www ~]# yum -y install httpd-tools
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.migaomei.cloud-ssl.conf
# add into the [server] section
server {
    .....
    location /auth-basic/ {
        auth_basic            "Basic Auth";
        auth_basic_user_file  "/etc/nginx/.htpasswd";
    }
}

[root@www ~]# systemctl restart nginx

# add user for Basic authentication
[root@www ~]# yum install -y httpd-tools
[root@www ~]# htpasswd -b -c /etc/nginx/.htpasswd migaomei 123456

# create a test page
[root@www ~]# mkdir /usr/share/nginx/html/auth-basic
[root@www ~]# vim /usr/share/nginx/html/auth-basic/index.html
<html>
<body>
<div style="width: 100%; font-size: 40px; font-weight: bold; text-align: migaomeier;">
Test Page for Basic Authentication
</div>
</body>
</html>

# 测试,通过-u选项指定用户名和密码
[root@client ~]# curl -ku migaomei:123456 https://www.migaomei.cloud/auth-basic/

支持动态脚本

使用 PHP

bash 复制代码
# 安装PHP和php-fpm,建议把其他的扩展包一起安装
[root@www ~]# yum install -y php php-fpm
# php-fpm: 负责接收web程序发来的php代码
# php:负责解析和执行php代码,并将结果返回给php-fpm

# 当客户端访问 php 站点时,web站点接收用户请求
# 并转发 php 代码给php-fpm服务
# php-fpm 服务调用php解析php网页,然后将结果返回给web程序
# web 程序将结果返回给客户端

# 启用并启动php-fpm服务
[root@www ~]# systemctl enable php-fpm --now

# 建议把其他的扩展包一起安装
[root@www ~]# yum install -y php-gd php-common php-pear php-mbstring php-mcrypt

# 查看 php 版本
[root@www ~]# php -v

# 测试 php 是否正常
[root@www ~]# echo "<?php echo 'PHP Test Page'.\"\n\"; ?>" > php_test.php 
[root@www ~]# php php_test.php 
PHP Test Page

# 准备测试页,使用phpinfo查看详细信息
[root@www ~]# echo "<?php phpinfo(); ?>" > /usr/share/nginx/html/info.php 

配置虚拟机主机支持php

bash 复制代码
# 修改配置文件
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.migaomei.cloud-ssl.conf
# add into the [server] section
server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/html;

    ssl_certificate "/etc/ssl/certs/www.migaomei.cloud/www.crt";
    ssl_certificate_key "/etc/ssl/certs/www.migaomei.cloud/www.key";

    # 匹配所有以.php结尾的URL请求,验证PHP文件是否存在
    # 存在则转发给本地9000端口的PHP-FPM处理,不存在则返回404
    location ~ \.php$ {
        # try_files:检测请求的PHP文件($uri)是否存在,不存在直接返回404错误
        # 作用:防止伪造PHP路径的恶意请求(如/xxx.php/yyy.jpg)被PHP-FPM解析,是重要的安全防护
        try_files $uri =404;
        
        # fastcgi_pass:指定FastCGI服务地址,将PHP请求转发到本地9000端口的PHP-FPM进程
        fastcgi_pass 127.0.0.1:9000;
        
        # fastcgi_index:定义FastCGI默认索引文件,请求目录时默认使用index.php
        fastcgi_index index.php;
        
        # fastcgi_param:设置传递给PHP-FPM的核心环境变量
        # SCRIPT_FILENAME:指定要执行的PHP文件绝对路径,
        # $document_root是网站根目录,$fastcgi_script_name是请求的脚本名
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        
        # include:引入Nginx默认的FastCGI参数配置文件,包含QUERY_STRING、REQUEST_METHOD等PHP运行必需的环境变量
        include fastcgi_params;
    }
}

# 配置HTTP重定向到https
server {
    listen       80;
    listen       [::]:80;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/html;
    # 添加重定向
    return       301 https://$host$request_uri;
}

还可以将php的配置与虚拟主机配置分离配置

bash 复制代码
[root@www ~]# vim vhost-www.migaomei.cloud-ssl.conf
server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/html;

    ssl_certificate "/etc/ssl/certs/www.migaomei.cloud/www.crt";
    ssl_certificate_key "/etc/ssl/certs/www.migaomei.cloud/www.key";

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
}

# 配置HTTP重定向到https
server {
    listen       80;
    listen       [::]:80;
    server_name  www.migaomei.cloud;
    root         /usr/share/nginx/html;
    # 添加重定向
    return       301 https://$host$request_uri;
}

[root@www ~]# vim /etc/nginx/default.d/php.conf 
location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

配置完成后,务必要重启nginx服务

bash 复制代码
[root@www ~]# systemctl restart nginx

客户端测试

bash 复制代码
[root@client ~]# curl -k https://www.migaomei.cloud/info.php

使用 FastCGI(选学)

bash 复制代码
# install from EPEL
[root@www ~]# yum install -y fcgiwrap
[root@www ~]# vim /etc/nginx/fcgiwrap.conf
# for example, enable CGI under [/cgi-bin]
location /cgi-bin/ {
    gzip off;
    root  /usr/share/nginx;
    fastcgi_pass  unix:/var/run/fcgiwrap.socket;
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
}

[root@www ~]# mkdir -m 755 /usr/share/nginx/cgi-bin
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.migaomei.cloud-ssl.conf
# add settings into [server] section of a site definition

server {
        .....
        include fcgiwrap.conf;
}

[root@www ~]# systemctl restart nginx
bash 复制代码
# Create Systemd file for FastCGI Wrap service and Start them.
[root@www ~]# vim /usr/lib/systemd/system/fcgiwrap.service
bash 复制代码
[Unit]
Description=Simple CGI Server
After=nss-user-lookup.target
Requires=fcgiwrap.socket

[Service]
EnvironmentFile=/etc/sysconfig/fcgiwrap
ExecStart=/usr/sbin/fcgiwrap ${DAEMON_OPTS} -c ${DAEMON_PROCS}
User=nginx
Group=nginx

[Install]
Also=fcgiwrap.socket
bash 复制代码
[root@www ~]# vim /usr/lib/systemd/system/fcgiwrap.socket
bash 复制代码
[Unit]
Description=fcgiwrap Socket

[Socket]
ListenStream=/run/fcgiwrap.socket

[Install]
WantedBy=sockets.target
bash 复制代码
[root@www ~]# systemctl enable --now fcgiwrap

# If SELinux is enabled, change policy.
[root@www ~]# vim nginx-www.te
module nginx-server 1.0;

require {
        type httpd_t;
        type var_run_t;
        class sock_file write;
}

#============= httpd_t ==============
allow httpd_t var_run_t:sock_file write;

[root@www ~]# checkmodule -m -M -o nginx-server.mod nginx-server.te

checkmodule: loading policy configuration from nginx-server.te
checkmodule: policy configuration loaded
checkmodule: writing binary representation (version 19) to nginx-server.mod
[root@www ~]# semodule_package --outfile nginx-server.pp --module nginx-server.mod

[root@www ~]# semodule -i nginx-server.pp

测试

bash 复制代码
# 准备测试文件
# Create a test scripts with a language (example below is Python3) under the directory you set CGI executable ([/usr/share/nginx/cgi-bin] on this example) and Access to it to verify CGI works normally.
[root@www ~]# vim /usr/share/nginx/cgi-bin/index.cgi
#!/usr/bin/python3
print("Content-type: text/html\n")
print("<html>\n<body>")
print("<div style=\"width: 100%; font-size: 40px; font-weight: bold; text-align: migaomeier;\">")
print("CGI Script Test Page")
print("</div>")
print("</body>\n</html>")

[root@www ~]# chmod 755 /usr/share/nginx/cgi-bin/index.cgi 

# 测试
[root@client ~]# curl http://www.migaomei.cloud/cgi-bin/index.cgi

反向代理

反向代理介绍

反向代理(reverse proxy),指的是**代理外网用户的请求到内部的指定的服务器,并将数据返回给用户。**客户端不直接与后端服务器进行通信,而是与反向代理服务器进行通信,隐藏了后端服务器的 IP 地址。

反向代理的主要作用是提供负载均衡和高可用性:

  • 负载均衡:Nginx可以将传入的请求分发给多个后端服务器,以平衡服务器的负载,提高系统性能和可靠性。

  • 缓存功能:Nginx可以缓存静态文件或动态页面,减轻服务器的负载,提高响应速度。

  • 动静分离:将动态生成的内容(如 PHP、Python、Node.js 等)和静态资源(如 HTML、CSS、JavaScript、图片、视频等)分别存放在不同的服务器或路径上。

  • 多站点代理:Nginx可以代理多个域名或虚拟主机,将不同的请求转发到不同的后端服务器上,实现多个站点的共享端口。

反向代理模块

Location 配置

Location 配置语法

Nginx 使用 location 匹配规则 + proxy_pass 反向代理指令实现反向代理功能,匹配本质是 "URL 路径匹配 → 命中对应规则 → 转发至指定后端地址"。

  • location 定义匹配路径
  • proxy_pass 指定后端服务地址
nginx 复制代码
http {
    # 后端服务可配置 upstream 集群(推荐,支持负载均衡)
    upstream backend_nginx {
        nginx 192.168.1.100:8080;  # 后端服务1
        nginx 192.168.1.101:8080;  # 后端服务2(多节点自动轮询负载均衡)
    }

    server {
        listen 80;  # Nginx 监听端口
        server_name localhost;  # 访问域名/IP

        # 1. 匹配所有请求(兜底规则)
        location / {
            proxy_pass http://backend_nginx;  # 转发至 upstream 集群
            # 必加的反向代理核心参数(传递客户端真实信息、适配后端服务)
            proxy_set_header Host $host;                # 传递客户端访问的域名
            proxy_set_header X-Real-IP $remote_addr;    # 传递客户端真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #传递IP链路
            proxy_set_header X-Forwarded-Proto $scheme; # 传递请求协议(http/https)
        }

        # 2. 匹配特定路径(如 /api 开头的请求,单独转发)
        location /api/ {
            proxy_pass http://192.168.1.102:9090/;  # 后端地址末尾带 /,会剔除匹配的 /api/
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}
Location 匹配规则
  1. 后端匹配逻辑:URL 路径 → 按 location 优先级命中规则 → 由规则内的 proxy_pass 转发至对应后端
  2. 优先级:精确匹配(=)> 前缀匹配(^~)> 正则匹配(/*)> 普通前缀 > 兜底(/);
  3. URL 重构关键:proxy_pass 末尾是否带 /,决定是否剔除 location 匹配的路径前缀。
1. 精确匹配(=)
  • 语法:location = /path { ... }

  • 逻辑:仅当请求 URL 与 /path 完全一致时命中,优先级最高。

  • 示例:

    nginx 复制代码
    # 仅匹配 http://localhost/login,不匹配 /login?a=1、/login/
    location = /login {
        proxy_pass http://backend_login:8080;
    }
2. 前缀配(^~)
  • 语法:location ^~ /path { ... }

  • 逻辑:URL 以 /path 开头即命中,优先级仅次于精确匹配,会跳过正则匹配

  • 用途:优先匹配静态资源(如 /static、/img)或特定业务路径,避免被正则规则拦截。

  • 示例:

    nginx 复制代码
    # 匹配所有 /static 开头的请求(如 /static/css/main.css、/static/img/1.jpg)
    location ^~ /static/ {
        proxy_pass http://backend_static:80;
    }
3. 正则匹配(~ / ~*)
  • 语法:

    • 区分大小写:location ~ /regex { ... }(如 /API 不匹配 /api 规则)
    • 不区分大小写:location ~* /regex { ... }(如 /API、/api 均匹配)
  • 逻辑:URL 符合正则表达式即命中,优先级低于前缀匹配(^~),多个正则规则按定义顺序匹配,先命中先生效

  • 示例:

    nginx 复制代码
    # 匹配所有 .jpg、.png、.gif 结尾的图片请求(不区分大小写)
    location ~* \.(jpg|png|gif)$ {
        proxy_pass http://backend_img:80;
    }
4. 普通前缀匹配(无符号)
  • 语法:location /path { ... }

  • 逻辑:URL 以 /path 开头即命中,优先级低于正则匹配,多个普通前缀规则按 "路径最长" 优先命中

  • 示例:

    nginx 复制代码
    # 规则1:匹配 /api/xxx(路径长度3)
    location /api/ {
        proxy_pass http://backend_api:9090;
    }
    # 规则2:匹配 /api/user/xxx(路径长度7,比规则1长,优先命中)
    location /api/user/ {
        proxy_pass http://backend_user:9090;
    }
5. 通用匹配(/)
  • 语法:location / { ... }
  • 逻辑:所有未被上述规则命中的请求,都会匹配此规则(兜底),优先级最低。
  • 用途:通常作为全局反向代理,转发所有默认请求到主后端服务。
proxy_pass 后端地址细节

proxy_pass 末尾是否带 /,会直接改变转发到后端的 URL 路径,这是后端匹配后 "URL 重构" 的核心,分 2 种场景:

场景 1:proxy_pass 末尾带 /
  • 逻辑:转发时,会剔除 location 匹配的路径前缀,将剩余路径拼接在后端地址后。

  • 示例:

    nginx 复制代码
    # location 匹配 /api/,proxy_pass 末尾带 /
    location /api/ {
        proxy_pass http://192.168.1.102:9090/;
    }
    # 实际转发逻辑:
    # 客户端请求 http://localhost/api/user/list → 后端接收 http://192.168.1.102:9090/user/list
场景 2:proxy_pass 末尾不带 /
  • 逻辑:转发时,会保留 location 匹配的路径前缀,直接拼接在后端地址后。

  • 示例:

    nginx 复制代码
    # location 匹配 /api/,proxy_pass 末尾不带 /
    location /api/ {
        proxy_pass http://192.168.1.102:9090;
    }
    # 实际转发逻辑:
    # 客户端请求 http://localhost/api/user/list → 后端接收 http://192.168.1.102:9090/api/user/list
综合示例

配置文件

nginx 复制代码
http {
    upstream backend_main { nginx 192.168.1.200:8080; }
    upstream backend_api { nginx 192.168.1.201:9090; }
    upstream backend_static { nginx 192.168.1.202:80; }
    upstream backend_login { nginx 192.168.1.203:8080; }

    server {
        listen 80;
        server_name localhost;

        # 1. 精确匹配:仅 /login → 后端 login 服务
        location = /login {
            proxy_pass http://backend_login;
            proxy_set_header Host $host;
        }

        # 2. 前缀匹配:/static/ 开头 → 后端静态服务(跳过正则)
        location ^~ /static/ {
            proxy_pass http://backend_static;
            proxy_set_header Host $host;
        }

        # 3. 正则匹配:图片后缀 → 后端静态服务
        location ~* \.(jpg|png|gif)$ {
            proxy_pass http://backend_static;
            proxy_set_header Host $host;
        }

        # 4. 普通前缀:/api/ 开头 → 后端 api 服务
        location /api/ {
            proxy_pass http://backend_api/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        # 5. 兜底匹配:所有未命中的请求 → 主后端服务
        location / {
            proxy_pass http://backend_main;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

匹配流程

客户端请求 URL 命中的 location 规则 转发至后端的 URL 对应后端服务
http://localhost/login = /login http://192.168.1.203:8080 backend_login
http://localhost/static/css/main.css ^~ /static/ http://192.168.1.202:80/css/main.css backend_static
http://localhost/img/1.jpg ~* .(jpg png gif)$ http://192.168.1.202:80/img/1.jpg backend_static
http://localhost/api/user/info /api/ http://192.168.1.201:9090/user/info backend_api
http://localhost/index / http://192.168.1.200:8080/index backend_main

反向代理实践环境

环境架构
服务器 主机名 IP地址 服务器角色
客户端 client.migaomei.cloud 10.1.8.11 测试服务器
Nginx 服务器 proxy.migaomei.cloud 10.1.8.20 代理服务器
Nginx 服务器 nginx1.migaomei.cloud 10.1.8.21 Web 服务器
Nginx 服务器 nginx2.migaomei.cloud 10.1.8.22 Web 服务器
Nginx 服务器 nginx3.migaomei.cloud 10.1.8.23 Web 服务器

/etc/hosts

bash 复制代码
# 所有节点
[root@nginx ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

############ proxy ##################
10.1.8.11 client.migaomei.cloud client
10.1.8.20 www.migaomei.cloud www
10.1.8.20 proxy.migaomei.cloud proxy
10.1.8.21 nginx1.migaomei.cloud nginx1
10.1.8.22 nginx2.migaomei.cloud nginx2
10.1.8.23 nginx3.migaomei.cloud nginx3
后端 nginx 服务器配置
bash 复制代码
# 除了客户端,所有节点安装nginx并启动nginx服务。
# 以nginx1为例
[root@nginx1 ~]# yum -y install nginx

# 启动并启用服务
[root@nginx1 ~]# systemctl enable nginx --now

# 防火墙设置
[root@nginx1 ~]# firewall-cmd --add-service=http --permanent
[root@nginx1 ~]# firewall-cmd --add-service=http

# 准备主页-其他节点
[root@nginx1 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html
[root@nginx2 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html
[root@nginx3 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html

# 客户端测试
[root@client ~]# curl http://www.migaomei.cloud/
Welcome to www.migaomei.cloud
[root@client ~]# curl http://nginx1.migaomei.cloud/
Welcome to nginx1.migaomei.cloud
[root@client ~]# curl http://nginx2.migaomei.cloud/
Welcome to nginx2.migaomei.cloud
[root@client ~]# curl http://nginx3.migaomei.cloud/
Welcome to nginx3.migaomei.cloud
前端 proxy 服务器配置
bash 复制代码
# 准备主页-代理节点
[root@proxy ~]# yum -y install nginx
[root@proxy ~]# echo Welcome to www.migaomei.cloud > /usr/share/nginx/html/index.html

[root@proxy ~]# mkdir /var/nginx
[root@proxy ~]# echo "Hello, Nginx" > /var/nginx/index.html
[root@proxy ~]# echo "Hello, migaomei" > /var/nginx/test.txt
[root@proxy ~]# cp /usr/share/nginx/html/nginx-logo.png /var/nginx/
[root@proxy ~]# ls /var/nginx/
index.html  nginx-logo.png  test.txt

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
nginx 复制代码
server {
	listen  80;
	server_name www.migaomei.cloud;

    # 匹配根位置
    location / {
      root /var/nginx;
      index index.html;
    }
}
bash 复制代码
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload
测试
bash 复制代码
[root@client ~]# curl http://www.migaomei.cloud/
Hello, Nginx

[root@client ~]# curl http://www.migaomei.cloud/test.txt
Hello, migaomei

访问 www.migaomei.cloud/nginx-logo.png,系统会返回以下页面:

**思考:**如果在Nginx目录中创建一个test.nn的文件,通过www.migaomei.cloud/test.nn访问该文件时,系统是否会返回对应文件内容?为什么?

答:不可以,因为"nn"类型的文件不在mime.type中,因此nginx无法对该文件进行解析,此时将下载文件到本地。

反向代理基础实践-代理本地

环境准备
bash 复制代码
[root@proxy ~]# mkdir /var/nginx/nginx{1,2}
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx1" > /var/nginx/nginx1/index.html
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx2" > /var/nginx/nginx2/index.html

[root@proxy ~]# mkdir /var/nginx{1,2}
[root@proxy ~]# echo "Hello, Nginx1" > /var/nginx1/index.html
[root@proxy ~]# echo "Hello, Nginx2" > /var/nginx2/index.html
[root@proxy ~]# tree /var/nginx*
/var/nginx
├── index.html
├── nginx1
│   └── index.html
├── nginx2
│   └── index.html
├── nginx-logo.png
└── test.txt
/var/nginx1
└── index.html
/var/nginx2
└── index.html

2 directories, 7 files

[root@proxy ~]# \
for path1 in www{1..2}
do
  for path2 in nginx{1..2}
  do
    mkdir -p /var/$path1/$path2
	echo "Hello, I'm here /var/$path1/$path2" > /var/$path1/$path2/index.html
  done
done

[root@proxy ~]# tree /var/www*
/var/www1
├── nginx1
│   └── index.html
└── nginx2
    └── index.html
/var/www2
├── nginx1
│   └── index.html
└── nginx2
    └── index.html

4 directories, 4 files

基本测试

bash 复制代码
[root@client ~]# curl http://www.migaomei.cloud/
Hello, Nginx

# 显示结果是目录/var/nginx/nginx1中内容
[root@client ~]# curl http://www.migaomei.cloud/nginx1/
Hello, I'm here /var/nginx/nginx1

# 显示结果是目录/var/nginx/nginx2中内容
[root@client ~]# curl http://www.migaomei.cloud/nginx2/
Hello, I'm here /var/nginx/nginx2
实践1:无符号匹配
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
nginx 复制代码
server {
	listen  80;
	server_name www.migaomei.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html;
    }
}
bash 复制代码
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

bash 复制代码
# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx1/
Hello, Nginx1
# 显示结果是目录/var/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx2/
Hello, I'm here /var/nginx/nginx2
# 显示结果是目录/var/nginx/nginx2中内容

实验结果:无符号匹配优先级高于默认的/。

实践2:正则表达式匹配
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
nginx 复制代码
server {
	listen  80;
	server_name www.migaomei.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html;
    }

    # 正则表达式匹配 /nginx.*
    location ~ /nginx.* {
        root /var/www1;
        index index.html;
    }
}
bash 复制代码
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

bash 复制代码
# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx1/
Hello, I'm here /var/www1/nginx1
# 显示结果是目录/var/www1/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx2/
Hello, I'm here /var/www1/nginx2
# 显示结果是目录/var/www1/nginx2中内容

实验结果:正则表达式匹配优先级高于无符号。

实践3:精确匹配
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
nginx 复制代码
server {
	listen  80;
	server_name www.migaomei.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html;
    }

    # 正则表达式匹配 /nginx.*
    location ~ /nginx.* {
        root /var/www1;
        index index.html;
    }

    # 精确匹配
    location = /nginx2/index.html {
        root /var/www2;
        index index.html;
    }

}
bash 复制代码
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

bash 复制代码
# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx1/
Hello, I'm here /var/www1/nginx1
# 显示结果是目录/var/www1/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx2/
Hello, I'm here /var/www2/nginx2
# 显示结果是目录/var/www2/nginx2中内容

实验结果:精确匹配优先级高于正则表达式。

反向代理基础实践-代理远端

实践1:无符号匹配
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
nginx 复制代码
server {
    listen  80;
    server_name www.migaomei.cloud;
    
    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配 /nginx1/ 开头,代理到nginx1.migaomei.cloud,/nginx1/不组合到后端服务器
    # 访问 /nginx1/ 开头,相当于直接访问http://nginx1.migaomei.cloud/
    location /nginx1/ {
        # 后端服务
        proxy_pass http://nginx1.migaomei.cloud/; # 注意:代理后端后面有 /。
        index index.html;
    }
}
bash 复制代码
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

bash 复制代码
# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx1/
Welcome to nginx1.migaomei.cloud
# 显示结果是服务器 nginx1.migaomei.cloud 内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx2/
Hello, I'm here /var/nginx/nginx2
# 显示结果是目录/var/nginx/nginx2中内容

实验结果:无符号匹配优先级高于默认的/。

实践2:正则表达式匹配
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
nginx 复制代码
server {
    listen  80;
    server_name www.migaomei.cloud;
    
    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配 /nginx1/ 开头,代理到nginx1.migaomei.cloud,/nginx1/不组合到后端服务器
    # 访问 /nginx1/ 开头,相当于直接访问http://nginx1.migaomei.cloud/
    location /nginx1/ {
        # 后端服务
        proxy_pass http://nginx1.migaomei.cloud/; # 注意:代理后端后面有 /。
        index index.html;
    }
 
    # 正则表达式匹配 /nginx.*
    location ~ /nginx[12].* {
        # 手动重写路径:去掉 /nginx 前缀,转发到目标服务器
        # ^/nginx[12](.*)$ 匹配 /nginx[12] 开头的完整路径,$1表示 /nginx[12] 后的所有内容
        # break 表示重写后不再匹配其他 rewrite 规则
        rewrite ^/nginx[12](.*)$ $1 break;
         
        # proxy_pass 不带 URI(无末尾的 /),配合 rewrite 实现路径替换
        proxy_pass http://nginx2.migaomei.cloud;  
        index index.html;
    }
}
bash 复制代码
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

bash 复制代码
# nginx 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx1/
Welcome to nginx2.migaomei.cloud
# 显示结果是服务器 nginx2.migaomei.cloud 内容

# nginx 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx2/
Welcome to nginx2.migaomei.cloud
# 显示结果是服务器 nginx2.migaomei.cloud 内容

实验结果:正则表达式匹配优先级高于无符号。

实践3:精确匹配
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
nginx 复制代码
server {
    listen  80;
    server_name www.migaomei.cloud;
    
    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配 /nginx1/ 开头,代理到nginx1.migaomei.cloud,/nginx1/不组合到后端服务器
    # 访问 /nginx1/ 开头,相当于直接访问http://nginx1.migaomei.cloud/
    location /nginx1/ {
        # 后端服务
        proxy_pass http://nginx1.migaomei.cloud/; # 注意:代理后端后面有 /。
        index index.html;
    }
 
    # 正则表达式匹配 /nginx.*
    location ~ /nginx[12].* {
        # 手动重写路径:去掉 /nginx 前缀,转发到目标服务器
        # ^/nginx[12](.*)$ 匹配 /nginx[12] 开头的完整路径,$1表示 /nginx[12] 后的所有内容
        # break 表示重写后不再匹配其他 rewrite 规则
        rewrite ^/nginx[12](.*)$ $1 break;
         
        # proxy_pass 不带 URI(无末尾的 /),配合 rewrite 实现路径替换
        proxy_pass http://nginx2.migaomei.cloud;  
        index index.html;
    }

    # 精确匹配
    location = /nginx1/ {
        proxy_pass http://nginx1.migaomei.cloud/;  
        index index.html;
    }

}
bash 复制代码
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

bash 复制代码
# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx1/
Welcome to nginx1.migaomei.cloud
# 显示结果是服务器 nginx1.migaomei.cloud 内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.migaomei.cloud/nginx2/
Welcome to nginx2.migaomei.cloud
# 显示结果是服务器 nginx2.migaomei.cloud 内容

实验结果:精确匹配优先级高于正则表达式。

缓存功能

启用缓存功能

要启用缓存,请在顶级http {}上下文中包含proxy_cache_path指令。

示例:

nginx 复制代码
http {
    # ...
    proxy_cache_path /var/cache/nginx keys_zone=mycache:10m max_size=10g inactive=60m;
}
  • 第一个参数 /var/cache/nginx,定义缓存内容保存到本地的文件系统路径。
  • 第二个参数 keys_zone,定义缓存区域的名称(mycache)和大小(10m)。
  • 第三个参数 max_size,定义最大缓存大小(10GB)。
  • 第四个参数 inactive,定义缓存数据在被认为是不活跃之前的时间(60分钟)。

然后将proxy_cache指令包含在您想要缓存服务器响应的上下文中,并指定proxy_cache_path指令keys_zone参数定义的区域名称。

示例:为nginx提供缓存。

nginx 复制代码
http {
    # ...
    proxy_cache_path /var/cache/nginx keys_zone=mycache:10m max_size=10g inactive=60m;
    server {
      listen  80;
      server_name www.migaomei.cloud;
      # 引用http中定义的缓存名称
      proxy_cache mycache1;
      # 必须指定缓存哪些返回状态码内容
      proxy_cache_valid 200 302 10m;
      # 可以为不同缓存指定缓存时间
      proxy_cache_valid 404 1m;
      location /nginx1 {
         proxy_pass http://nginx1.migaomei.cloud/;
      }
      location /nginx2 {
         proxy_pass http://nginx2.migaomei.cloud/;
      }
    }
}
启用多个缓存

每个代理使用不同缓存配置。

nginx 复制代码
http {
    # ...
    proxy_cache_path /var/cache/nginx1 keys_zone=mycache1:10m max_size=10g inactive=60m;
    proxy_cache_path /var/cache/nginx2 keys_zone=mycache2:10m max_size=10g inactive=60m;
    server {
      listen  80;
      server_name www.migaomei.cloud;

      location /nginx1 {
         proxy_cache mycache1;
         proxy_cache_valid 200 302 10m;
         proxy_cache_valid 404 1m;
         proxy_pass http://nginx1.migaomei.cloud/;
      }

      location /nginx2 {
         proxy_cache mycache2;
         proxy_cache_valid 200 302 10m;
         proxy_cache_valid 404 1m;
         proxy_pass http://nginx2.migaomei.cloud/;
      }
    }
}
控制缓存内容

前面的示例根据返回状态码控制缓存内容,我们还可以使用以下参数控制缓存内容:

  • 要更改计算密钥时使用的请求特征,请包含proxy_cache_key指令:

    nginx 复制代码
    proxy_cache_key "$host$request_uri$cookie_user";
  • 要定义在缓存响应之前必须发出具有相同密钥的请求的最小次数,请包含proxy_cache_min_uses指令:

    nginx 复制代码
    proxy_cache_min_uses 5;
  • 要缓存对使用GETHEAD以外的方法的请求的响应,请将它们与GETHEAD一起列出作为proxy_cache_methods指令的参数:

    nginx 复制代码
    proxy_cache_methods GET HEAD POST;
  • 为不同返回状态码设置超时时间,使用指令proxy_cache_valid

    nginx 复制代码
    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 404      1m;

    如果只指定时间,则只缓存200, 301, 302。

    nginx 复制代码
    proxy_cache_valid 5m;

    使用 any 可以缓存所有状态码。

    nginx 复制代码
    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 301      1h;
    proxy_cache_valid any      1m;
缓存空间大小

缓存数据量可能会暂时超过限制,NGINX 有两个额外的进程参与缓存:

  • 缓存管理器 定期激活以检查缓存的状态。如果缓存大小超过proxy_cache_path指令的max_size参数设置的限制,缓存管理器将删除最近最少访问的数据。如前所述,在缓存管理器激活之间的时间内,缓存的数据量可能会暂时超出限制。
  • 缓存加载器 仅在 NGINX 启动后运行一次。它将有关先前缓存的数据的元数据加载到共享内存区域。立即加载整个缓存可能会消耗足够的资源,从而在启动后的最初几分钟内降低 NGINX 的性能。为了避免这种情况,请通过在proxy_cache_path指令中包含以下参数来配置缓存的迭代加载:
    • loader_threshold -- 迭代的持续时间,以毫秒为单位(默认为200
    • loader_files -- 一次迭代期间加载的最大项目数(默认为100
    • loader_sleeps -- 迭代之间的延迟,以毫秒为单位(默认为50

在以下示例中,迭代持续300毫秒或直到加载了200项目:

bash 复制代码
proxy_cache_path /var/cache/nginx keys_zone=mycache:10m loader_threshold=300 loader_files=200;

负载均衡-七层

Nginx 反向代理支持七层 http/https 代理四层 TCP/UDP 代理

通过Nginx反向代理实现Nginx服务器负载均衡。

代理服务器配置
bash 复制代码
# 安装 nginx
[root@nginx ~]# yum -y install nginx

# 配置nginx
[root@nginx ~]# vim /etc/nginx/nginx.conf
# http块中增加如下内容
    upstream backends {
        nginx nginx1.migaomei.cloud:80;
        nginx nginx2.migaomei.cloud:80;
        nginx nginx3.migaomei.cloud:80;
    } 

# nginx块中修改主机名
        server_name www.migaomei.cloud;

## 对于HTTP配置,nginx部分更改如下
[root@nginx ~]# vim /etc/nginx/nginx.conf
# change [nginx] section like follows

    server {
        listen         80 default_nginx;
        listen         [::]:80 default_nginx;
        server_name    www.migaomei.cloud;
        root           /usr/share/nginx/html;
        
        #如果需要HTTP重定向为HTTPS,添加如下记录,并取消注释
        #return       301 https://$host$request_uri;
        
        # 添加如下内容
        proxy_redirect      off;
        proxy_set_header    Host $http_host;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        

        #修改location /记录,后端指向backends,上一步配置的主机清单
        location / {
            proxy_pass http://backends/;
        }
    }

# 启动并启用服务
[root@nginx ~]# systemctl enable nginx --now

# 防火墙设置
[root@nginx ~]# firewall-cmd --add-service=http --permanent
[root@nginx ~]# firewall-cmd --add-service=http

测试

bash 复制代码
[root@client ~]# for n in {1..90}; do curl http://10.1.8.20 -s; done | sort |uniq -c
     30 Welcome to nginx1.migaomei.cloud
     30 Welcome to nginx2.migaomei.cloud
     30 Welcome to nginx3.migaomei.cloud
负载均衡-upstream

Nginx 的 upstream 模块声明一组可以被 proxy_pass 和 fastcgi_pass 引用的服务器。这些服务器既可以使用不同的端口,也可以使用Unix Socket。这些服务器可被赋予了不同的权重、不同的类型甚至可以基于维护等原因被标记为 down。

upstream 语法:

复制代码
upstream name {
    ....
}

例如:

nginx 复制代码
upstream backend {
    nginx backend1.example.com weight=5 down backup;
    nginx 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    nginx unix:/tmp/backend2;
}

upstream 模块常用的指令有:

  • keepalive,每个 worker 进程为发送到 upstream 服务器的连接所缓存的个数。

  • nginx,定义一个upstream服务器的地址,还可包括一系列可选参数。

    • weight:权重,默认值为1;

    • max_fails:最大失败连接次数,失败连接的超时时长由fail_timeout指定;

    • fail_timeout:等待请求的目标服务器发送响应的时长;

    • backup:用于 fallback 的目的,所有服务均故障时才启动此服务器;

    • down:手动标记其不再处理任何请求;

示例:

nginx 复制代码
upstream backends {
    keepalive 32;
    nginx nginx1.migaomei.cloud:80 max_fails=3 fail_timeout=30s;
    nginx nginx2.migaomei.cloud:80 max_fails=3 fail_timeout=30s weight=2;
    nginx nginx3.migaomei.cloud:80 max_fails=3 fail_timeout=30s backup;
    nginx nginx4.migaomei.cloud:80 max_fails=3 fail_timeout=30s down;
}

upstream 模块调度算法一般分为两类:

  • 静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况。例如:rr、ip_hash 等都属于静态调度算法。

  • 动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求, 例如:连接数少(least_conn)的服务器优先获得请求,响应时间短(least_time)的服务器优先获得请求。

轮询(round-robin)

nginx 默认的调度算法,按客户端请求顺序把客户端的请求逐一分配到不同的后端节点服务器。如果后端节点服务器宕机(默认情况下Nginx只检测80端口),宕机的服务器会被自动从节点服务器池中剔除,以使客户端的用户访问不受影响。新的请求会分配给正常的服务器。

示例:

nginx 复制代码
upstream backends {
    nginx nginx1.migaomei.cloud:80;
    nginx nginx2.migaomei.cloud:80;
    nginx nginx3.migaomei.cloud:80;
}

测试结果

bash 复制代码
[root@client ~]# for i in {1..60}; do curl http://www.migaomei.cloud/test.html 2>/dev/null; done |sort |uniq -c
     20 Welcome to nginx1
     20 Welcome to nginx2
     20 Welcome to nginx3

**还可以在 rr 轮询算法的基础上为服务器加上权重。**权重和用户访问成正比,权重值越大,被转发的请求也就越多。 可以根据服务器的配置和性能指定权重值大小,有效解决新旧服务器性能不均带来的请求分配问题。在配置的nginx后面加个weight=number,number值越高,分配的概率越大。

示例:

nginx 复制代码
upstream backends {
    nginx nginx1.migaomei.cloud:80 weight=10;
    nginx nginx2.migaomei.cloud:80 weight=20;
    nginx nginx3.migaomei.cloud:80 weight=30;
}

测试结果

bash 复制代码
[root@client ~]# for i in {1..60}; do curl http://www.migaomei.cloud 2>/dev/null; done |sort |uniq -c
     10 Welcome to nginx1
     20 Welcome to nginx2
     30 Welcome to nginx3
IP哈希(ip_hash)

**每个请求按客户端IP的 hash 结果分配。**当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器。

该调度算法可以解决动态网页的 session 共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以这些客户端都会被分配到同一节点服务器,从而导致请求分配不均。

LVS负载均衡的-p参数、Keepalived配置里的per-sistence_timeout 50参数都类似这个Nginx里的ip_hash参数,其功能都可以解决动态网页的session共享问题。

示例:

nginx 复制代码
upstream backends {
    ip_hash;
    nginx nginx1.migaomei.cloud:80;
    nginx nginx2.migaomei.cloud:80;
    nginx nginx3.migaomei.cloud:80;
}

测试结果

bash 复制代码
[root@client ~]# for i in {1..60}; do curl http://www.migaomei.cloud/ 2>/dev/null; done |sort |uniq -c
     60 Welcome to nginx2
通用哈希(generic Hash

请求发送到的服务器由用户定义的键确定,该键可以是文本字符串、变量或组合。例如,密钥可以是配对的源 IP 地址和端口,或者是 URI。

在upstream中加入hash语句,nginx语句中不能写入weight等其他的参数,hash_method使用的是hash算法。url_hash按访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率命中率。

Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx的hash模块软件包。

示例:

nginx 复制代码
upstream backends {
    hash $request_uri;
    hash_method crc32;
    nginx nginx1.migaomei.cloud:80;
    nginx nginx2.migaomei.cloud:80;
    nginx nginx3.migaomei.cloud:80;
}
最少连接数(least_conn)

最少连接数,将请求分发给后端节点服务器连接数最少的那个机器。

示例:

nginx 复制代码
upstream backends {
    least_conn;
    nginx nginx1.migaomei.cloud:80;
    nginx nginx2.migaomei.cloud:80;
    nginx nginx3.migaomei.cloud:80;
}

测试结果

bash 复制代码
[root@client ~]# for i in {1..60}; do curl http://www.migaomei.cloud/ 2>/dev/null; done |sort |uniq -c
     20 Welcome to nginx1
     20 Welcome to nginx2
     20 Welcome to nginx3

最少连接数也支持权重。

最少时间(Least Time)

Least Time (仅限 NGINX Plus),对于每个请求,NGINX Plus 选择具有最低平均延迟和最少活动连接数的服务器,其中最低平均延迟是根据least_time指令中包含的以下参数来计算的:

  • header -- 从服务器接收第一个字节的时间。
  • last_byte -- 从服务器接收完整响应的时间。
  • last_byte inflight -- 从服务器接收完整响应的时间,考虑到不完整的请求。

示例:

nginx 复制代码
upstream backends {
    least_time header;
    nginx nginx1.migaomei.cloud:80;
    nginx nginx2.migaomei.cloud:80;
    nginx nginx3.migaomei.cloud:80;
}

负载均衡-四层

Nginx 反向代理支持七层 http/https 代理四层 TCP/UDP 代理

示例:

nginx 复制代码
stream {
    upstream stream_backend {
        least_conn;
        nginx backend1.example.com:12345 weight=5;
        nginx backend2.example.com:12345 max_fails=2 fail_timeout=30s;
        nginx backend3.example.com:12345 max_conns=3;
    }

    upstream dns_nginxs {
        least_conn;
        nginx 192.168.136.130:53;
        nginx 192.168.136.131:53;
        nginx 192.168.136.132:53;
    }

    server {
        listen        12345;
        proxy_pass    stream_backend;
        proxy_timeout 3s;
        proxy_connect_timeout 1s;
    }

    server {
        listen     53 udp;
        proxy_pass dns_nginxs;
    }

    server {
        listen     12346;
        proxy_pass backend4.example.com:12346;
    }
}

健康检查

Nginx支持多种方式检查后端服务器:

ome to nginx1

20 Welcome to nginx2

20 Welcome to nginx3

复制代码
==**最少连接数也支持权重。**==



##### 最少时间(Least Time)

[Least Time](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_time) (仅限 NGINX Plus),对于每个请求,NGINX Plus 选择具有最低平均延迟和最少活动连接数的服务器,其中最低平均延迟是根据`least_time`指令中包含的以下[参数](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_time)来计算的:

- `header` -- 从服务器接收第一个字节的时间。
- `last_byte` -- 从服务器接收完整响应的时间。
- `last_byte inflight` -- 从服务器接收完整响应的时间,考虑到不完整的请求。

示例:

```nginx
upstream backends {
    least_time header;
    nginx nginx1.migaomei.cloud:80;
    nginx nginx2.migaomei.cloud:80;
    nginx nginx3.migaomei.cloud:80;
}

负载均衡-四层

Nginx 反向代理支持七层 http/https 代理四层 TCP/UDP 代理

示例:

nginx 复制代码
stream {
    upstream stream_backend {
        least_conn;
        nginx backend1.example.com:12345 weight=5;
        nginx backend2.example.com:12345 max_fails=2 fail_timeout=30s;
        nginx backend3.example.com:12345 max_conns=3;
    }

    upstream dns_nginxs {
        least_conn;
        nginx 192.168.136.130:53;
        nginx 192.168.136.131:53;
        nginx 192.168.136.132:53;
    }

    server {
        listen        12345;
        proxy_pass    stream_backend;
        proxy_timeout 3s;
        proxy_connect_timeout 1s;
    }

    server {
        listen     53 udp;
        proxy_pass dns_nginxs;
    }

    server {
        listen     12346;
        proxy_pass backend4.example.com:12346;
    }
}

健康检查

Nginx支持多种方式检查后端服务器:

相关推荐
信创天地2 小时前
信创环境下数据库与中间件监控实战:指标采集、工具应用与告警体系构建
java·运维·数据库·安全·elk·华为·中间件
[H*]2 小时前
Flutter框架跨平台鸿蒙开发——AnimatedIcon动画图标
运维·nginx·flutter
运维小欣2 小时前
证券行业可观测平台选型指南:数字化转型的“千里眼”
运维
qq_411262422 小时前
esp32c3的at固件,开启了tcp服务器和透传模式。设备连接tcp后关闭wifi后没有断开tcp连接
服务器·网络·tcp/ip
优选资源分享2 小时前
开源免费 Linux 服务器管理工具 Server Box v1.0.1297
linux·服务器·开源
科技与数码2 小时前
深圳自动化系统研发公司九科信息:以全链路产品筑牢市场标杆
运维·自动化
颢珂智库Haokir Insights2 小时前
宝塔面板安装教程(新手完整指南)
linux·运维·服务器
大风起兮云飞扬丶2 小时前
让你的应用自动化起来
运维·自动化
岁岁种桃花儿2 小时前
K8s Nginx Pod 出现 CrashLoopBackOff?从配置排查到彻底解决
运维·nginx·kubernetes