Nginx是现在最流行的Web服务器和反向代理服务器之一它性能高资源占用少稳定性好能支持高并发很多大型网站都在用Nginx比如淘宝京东百度腾讯等等Nginx几乎已经成了Web服务器的标配是每个后端开发者和运维都必须掌握的技能。

我用Nginx很多年了配置过很多网站和服务踩了一些坑也总结了一些经验今天就来分享一下Nginx高性能配置的实战经验从入门到调优全面分享包括基础配置性能优化安全加固负载均衡反向代理等等希望能帮大家更好地使用Nginx提升网站性能和稳定性。

一、Nginx简介

先简单介绍一下Nginx。

Nginx是一个高性能的HTTP和反向代理服务器也是一个IMAP/POP3/SMTP代理服务器由俄罗斯程序员Igor Sysoev开发2004年发布第一个版本Nginx的特点是占用内存少并发能力强性能高稳定性好配置简单模块化设计功能丰富。

Nginx的优势:

  1. 高并发高性能: Nginx采用事件驱动异步非阻塞模型能支持高并发单机能支持几万甚至几十万并发连接性能非常高。
  2. 资源占用少: Nginx占用内存很少10000个连接才占用几百MB内存比Apache少很多。
  3. 稳定性高: Nginx稳定性非常好能长时间运行不宕机很多网站运行Nginx几年都不重启。
  4. 配置简单: Nginx的配置文件很简单易懂模块化设计很容易上手。
  5. 功能丰富: Nginx支持反向代理负载均衡静态文件服务SSL/TLS虚拟主机URL重写Gzip压缩缓存等等很多功能能满足各种需求。
  6. 模块化设计: Nginx采用模块化设计有很多第三方模块能扩展各种功能。

2017年Nginx已经非常成熟了版本大概是1.10.x1.12.x很多公司都在用Nginx是Web服务器的首选。

二、Nginx基础配置

先说说Nginx的基础配置Nginx的配置文件一般是nginx.conf结构大概是这样的:

# 全局配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# 事件配置
events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

# HTTP配置
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    # 核心配置
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Gzip压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 虚拟主机
    server {
        listen 80;
        server_name example.com;
        root /var/www/example.com;
        index index.html index.htm;

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

下面详细说说各个部分的配置。

1. 全局配置

  • user: Nginxworker进程运行的用户一般设置为nginx或者www-data不要用root安全。
  • worker_processes: worker进程数量一般设置为CPU核心数auto会自动设置为CPU核心数这样能充分利用多核CPU性能最好。
  • error_log: 错误日志路径和级别级别有debuginfonoticewarnerrorcrit等等一般设置为warn或者error。
  • pid: Nginx主进程PID文件路径。

2. 事件配置

  • workerconnections: 每个worker进程能支持的最大连接数一般设置为1024或者更高比如20484096根据服务器配置和需求调整Nginx总并发= workerprocesses * worker_connections。
  • use epoll: 事件模型Linux下用epoll性能最好FreeBSD下用kqueue。
  • multi_accept: 尽量一次接受多个连接开启on能提高并发性能。

3. HTTP配置

  • include mime.types: 引入MIME类型文件让Nginx能正确识别各种文件类型。
  • default_type: 默认MIME类型一般设置为application/octet-stream。
  • log_format: 日志格式定义访问日志的格式。
  • access_log: 访问日志路径和格式。
  • sendfile: 开启sendfile高效传输静态文件性能好。
  • tcp_nopush: 和sendfile一起开启能提高传输效率。
  • tcp_nodelay: 禁止Nagle算法减少延迟提高响应速度。
  • keepalive_timeout: 长连接超时时间一般设置为65秒或者根据需求调整长连接能减少TCP握手开销提高性能。
  • typeshashmax_size: MIME类型哈希表大小一般设置为2048避免报错。

三、性能优化

下面说说Nginx的性能优化配置这些配置能大大提高Nginx的性能。

1. worker进程和连接数

worker_processes auto;
worker_rlimit_nofile 65535;

events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
}
  • worker_processes设置为auto自动匹配CPU核心数。
  • workerrlimitnofile设置worker进程能打开的最大文件数一般设置为65535或者更高。
  • worker_connections设置每个worker进程的最大连接数根据服务器配置调整一般65535就够了。
  • multi_accept开启一次接受多个连接提高并发。

2. 高效传输配置

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    keepalive_requests 1000;
}
  • sendfile开启高效传输静态文件。
  • tcp_nopush和sendfile一起提高传输效率。
  • tcp_nodelay减少延迟。
  • keepalive_timeout长连接超时。
  • keepalive_requests一个长连接能处理的最大请求数一般设置为1000或者更高。

3. Gzip压缩

http {
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
    gzip_vary on;
    gzip_proxied any;
}
  • gzip开启Gzip压缩能减少传输数据量提高网站加载速度。
  • gzipminlength小于1k的文件不压缩因为压缩小文件反而可能变大。
  • gzipcomplevel压缩级别1-96是性能和压缩率的折中推荐。
  • gzip_types需要压缩的MIME类型文本类文件都压缩图片视频等已经压缩过的不用压缩。
  • gzip_vary添加Vary: Accept-Encoding头让CDN和代理能正确缓存。

4. 静态文件缓存

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    access_log off;
}

静态文件比如JSCSS图片字体等等设置长时间缓存30天或者更长能减少服务器请求提高加载速度access_log off关闭静态文件的访问日志减少IO开销。

5. 客户端缓存

http {
    open_file_cache max=100000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}

openfilecache缓存文件描述符和元信息能减少磁盘IO提高静态文件访问性能。

四、安全加固

Nginx的安全加固也很重要下面说说常用的安全配置。

1. 隐藏版本号

http {
    server_tokens off;
}

server_tokens off隐藏Nginx版本号避免攻击者根据版本号利用已知漏洞。

2. 禁止访问敏感文件

location ~ /\.(ht|git|svn) {
    deny all;
    access_log off;
    log_not_found off;
}

禁止访问.htaccess.git.svn等敏感文件避免泄露信息。

3. 限制请求体大小

http {
    client_max_body_size 10m;
}

限制客户端请求体最大大小避免大文件上传攻击根据需求调整。

4. 限制请求速率

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

    server {
        location / {
            limit_req zone=one burst=20 nodelay;
        }
    }
}

限制每个IP的请求速率防止CC攻击和暴力破解rate=10r/s每秒最多10个请求burst=20允许突发20个请求。

5. 限制连接数

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    server {
        location / {
            limit_conn addr 10;
        }
    }
}

限制每个IP的最大连接数防止连接耗尽攻击。

6. HTTPS配置

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

配置HTTPS使用TLSv1.2TLSv1.3安全的加密套件开启HSTS强制HTTPS提高安全性。

五、反向代理和负载均衡

Nginx最常用的功能之一就是反向代理和负载均衡下面说说配置。

1. 反向代理

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1: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;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}
  • proxy_pass转发到后端服务。
  • proxysetheader设置转发的请求头让后端能获取真实的用户IP和协议。
  • proxyconnecttimeout连接后端超时。
  • proxyreadtimeout读取后端响应超时。

2. 负载均衡

http {
    upstream backend {
        server 192.168.1.10:8080 weight=3;
        server 192.168.1.11:8080 weight=2;
        server 192.168.1.12:8080 weight=1;
        ip_hash;
        keepalive 32;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}
  • upstream定义后端服务器组多个后端服务器负载均衡。
  • weight权重权重越高分配的请求越多。
  • ip_hash根据客户端IP哈希分配同一个IP的请求总是到同一个后端能保持会话。
  • keepalive保持和后端的长连接减少TCP握手开销提高性能。

负载均衡算法有轮询(默认)加权轮询iphashleastconn(最少连接)等等根据需求选择。

六、URL重写和伪静态

Nginx的URL重写也很常用比如伪静态URL美化等等。

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

这是PHP的伪静态配置try_files把所有请求都转发到index.php实现伪静态URL美化很多PHP框架比如LaravelThinkPHP都需要这样的配置。

也能用rewrite指令做URL重定向和重写:

# 301重定向,www.example.com -> example.com
server {
    listen 80;
    server_name www.example.com;
    return 301 http://example.com$request_uri;
}

# URL重写
location / {
    rewrite ^/article/(\d+)$ /index.php?article_id=$1 last;
}

七、踩坑经验

最后分享一些我用Nginx踩过的坑和经验。

1. 配置文件语法检查

修改Nginx配置之后一定要先检查语法再重启或者重载不然配置有问题会导致Nginx启动失败网站无法访问。

# 检查配置语法
nginx -t

# 重载配置
nginx -s reload

nginx -t检查配置语法有没有问题没问题再nginx -s reload重载配置这样安全不会导致网站中断。

2. 403 Forbidden 错误

经常遇到403错误一般是权限问题或者配置问题检查文件权限Nginx运行用户有没有权限读取文件还有检查root配置对不对index配置对不对有没有默认首页文件。

3. 502 Bad Gateway 错误

反向代理的时候经常遇到502错误一般是后端服务没启动或者端口不对或者后端服务挂了检查后端服务是否正常运行端口是否正确proxy_pass配置对不对。

4. 大文件上传失败

大文件上传失败一般是clientmaxbodysize设置太小调大这个配置就行同时也要检查后端服务的上传大小限制比如PHP的uploadmaxfilesizepostmax_size等等。

5. 静态文件不缓存

静态文件不缓存检查expires和Cache-Control配置对不对还有有没有其他配置覆盖了缓存配置另外开发的时候可能会禁用缓存上线要记得开启。

6. HTTPS配置问题

HTTPS配置经常遇到证书问题检查证书路径对不对证书是否有效证书和私钥是否匹配还有检查443端口是否开放防火墙是否允许HTTPS访问。

八、写在最后

Nginx高性能配置实战:从入门到调优。

Nginx是一个非常优秀的Web服务器和反向代理服务器性能高资源占用少稳定性好功能丰富配置简单是每个后端开发者和运维都必须掌握的技能。

这篇文章我们从Nginx简介基础配置性能优化安全加固反向代理负载均衡URL重写等等方面分享了Nginx的实战经验和最佳实践希望能帮大家更好地使用Nginx提升网站性能和稳定性。

当然Nginx的功能很强大还有很多高级功能和配置这篇文章只是介绍了常用的部分更多的功能需要大家在实际使用中不断学习和探索。

最后用一句话结尾:

"Nginx高性能Web服务器的王者用好了能让你的网站又快又稳。"

祝大家都能用好Nginx网站又快又稳!