Nginx常见问题怎么解决?

240 阅读3分钟

Nginx名称版本

> vi scr/core/nginx.h
#define NGINX_VERSION      "1.0.0"
#define NGINX_VER          "test/" NGINX_VERSION

HTTPS协议

http {
    server {
        listen                     80;
        listen                     443 ssl;
        server_name                localhost;

        # 配置证书位置
        ssl_certificate            /home/keys/server.crt;
        # 配置秘钥位置
        ssl_certificate_key        /home/keys/server.key;
        # 双向认证
        #ssl_client_certificate     ca.crt;
        # 双向认证
        #ssl_verify_client          on;
        ssl_session_timeout        5m;
        ssl_protocols              SSLv2 SSLv3 TLSv1 TLSv1.2;
        ssl_ciphers                ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers  on;
        ...
    }
}

多端自动切换

http {
    server {
        location / {
            root   html/dist;
            index  index.html;
            if ($http_user_agent ~* 'Mobile') {
                root   html/mobile;
                index  index.html;
            }
        }
    }
}

反向代理

http {
    server {
        # 服务器超时时间
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 1800s;
        
        # 服务器FastCGI超时时间
        fastcgi_connect_timeout 5s;
        fastcgi_send_timeout 10s;
        fastcgi_read_timeout 1800s;

        # 请求服务器最大允许大小
        client_max_body_size 100m;
        client_body_buffer_size 100m;

        location /api/ {
            proxy_pass http://127.0.0.1:8000/;
            # 获取真实IP
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /ws {
            proxy_pass http://127.0.0.1:8000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
        }
    }
}

stream {
    server {
        listen            3308;
        proxy_pass 127.0.0.1:3306;
    }
}

负载均衡

http {
    upstream backend {
        #  使用 IP 哈希
        ip_hash;
        # 使用最少连接策略
        least_conn;

        # weight 权重,权重越小请求越多
        # 服务器在 fail_timeout 时间内允许最多失败 max_fails 次
        server backend1 weight=1 max_fails=3 fail_timeout=30s;
        server backend2 weight=2 max_fails=3 fail_timeout=30s;
        server backend3 weight=3 max_fails=3 fail_timeout=30s;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

并发优化

# 进程数
worker_processes auto;
# 绑定CPU核心数
worker_cpu_affinity auto;

# 连接处理相关
events {
    # 事件模型:epoll是Linux下最高效的模型(推荐)
    use epoll;
    # 最大并发连接数
    worker_connections 10240;
    # 连接复用
    multi_accept on;
    # 优化accept_mutex
    accept_mutex on;
    accept_mutex_delay 500ms;
}

http {
    # 开启高效文件传输模式
    sendfile on;
    
    # 合并小数据包发送,减少网络IO
    tcp_nopush on;
    
    # 关闭Nagle算法,降低延迟(适合小数据包)
    tcp_nodelay on;

    # 超时时间优化
    keepalive_timeout 65;
    keepalive_requests 100000;
    client_header_timeout 15s;
    client_body_timeout 15s;
    send_timeout 15s;

    # 连接数限制
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    limit_conn perip 100;
    limit_conn perserver 10000;

    # 缓冲区优化
    client_body_buffer_size 16k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k; 
    output_buffers 4 32k;
    postpone_output 1460;

    # Gzip优化
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_types
        application/atom+xml
        application/geo+json
        application/javascript
        application/x-javascript
        application/json
        application/ld+json
        application/manifest+json
        application/rdf+xml
        application/rss+xml
        application/xhtml+xml
        application/xml
        font/eot
        font/otf
        font/ttf
        image/svg+xml
        text/css
        text/javascript
        text/plain
        text/xml;

    # 开启缓存
    open_file_cache max=100000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 1;
    open_file_cache_errors on;

    # 反向代理优化
    proxy_buffering on;
    proxy_buffer_size 32k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    proxy_connect_timeout 5s;
    proxy_read_timeout 60s;
    proxy_send_timeout 60s;
    
    # ========== 核心:index.html 禁止缓存 ==========
    location = /index.html {
        # 禁止浏览器/代理缓存 index.html
        add_header Cache-Control "no-cache, no-store, must-revalidate";
        add_header Pragma "no-cache";
        add_header Expires "0";
        # 禁用 Nginx 自身的缓存
        expires off;
    }

    # ========== 带 Hash 的静态资源(JS/CSS/图片)长缓存 ==========
    location ~* .(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        # 长缓存(1年),因为文件名带 Hash,内容变则文件名变
        add_header Cache-Control "public, max-age=31536000, immutable";
        expires 1y; # Nginx 简化写法,等同于 max-age=31536000
        # 可选:开启 Gzip 压缩,提升加载速度
        gzip on;
        gzip_types application/javascript text/css image/svg+xml;
        # 可选:添加跨域头(如果资源被CDN/其他域名引用)
        add_header Access-Control-Allow-Origin *;
        # 可选:资源完整性校验(SRI),防止资源篡改
        add_header Content-Security-Policy "require-sri-for script style";
    }

    # ========== 兜底:其他资源默认缓存策略 ==========
    location / {
        # 匹配所有未命中上面规则的请求,默认转发到 index.html(SPA 路由适配)
        try_files $uri $uri/ /index.html;
        # 非 HTML 文件才缓存,避免误缓存 index.html
        if ($request_filename !~* .html$) {
            add_header Cache-Control "public, max-age=86400"; # 1天
            expires 1d;
        }
    }
}

安全拦截

http {
    server {
        # 黑名单
        deny all;
        # 白名单
        allow 127.0.0.1;
        # 关闭目录列表
        autoindex off;
        # 隐藏服务器信息
        server_tokens off;
        # 防止点击劫持
        # DENY: 页面不能被嵌入到任何iframe中
        # SAMEORIGIN: 页面只能被同源域名下的页面嵌入到iframe中
        # ALLOW-FROM uri: 页面可以被从指定uri的框架中嵌入
        add_header X-Frame-Options "SAMEORIGIN";
        # 启用浏览器的XSS过滤器
        add_header X-XSS-Protection "1; mode=block";
        # 阻止基于MIME类型的攻击
        add_header X-Content-Type-Options "nosniff";
        # 限制页面可以加载的资源
        # 只允许加载同源的资源, 不加载任何框架内的资源, 不执行内联脚本和eval等
        add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'none'";
        # 控制跨域资源共享
        add_header X-Permitted-Cross-Domain-Policies "master-only";
        # 强制浏览器只通过HTTPS发送请求
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
        # 指定页面如何发送Referer头
        add_header Referrer-Policy "no-referrer-when-downgrade";
        # 防止浏览器缓存敏感信息
        add_header Expires "0";
        add_header Cache-Control "no-cache, no-store, must-revalidate";

        location / {
            root   html;
            index  index.html;
            # 防越权
            internal;
        }
    }
}