Skip to content

Nginx

简介

1.1 Nginx和Apache对比

Nginx:

  • 轻量级
  • 抗并发
  • 静态处理性能比apache高三倍以上
  • 设计高度模块化
  • 配置简洁
  • 支持7层负载均衡
  • 优秀的反向代理服务器
  • 易启动
  • 社区活跃

Apache:

  • rewrite强大
  • 模块多
  • bug少,稳定
  • 对php支持简单
  • 处理动态请求时有优势

安装

2.1 安装方式

  1. 编译安装:版本随意、安装复杂、升级繁琐、规范、便于管理
  2. epel安装:版本较低、安装简单、配置不易读
  3. 官方仓库:版本较新、安装简单、配置易读

2.2 配置官方yum源

bash
[nginx-stable]
name=nginx stable repo
baseurl=https://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

2.3 编译安装

查看nginx默认模块:

bash
nginx -V
  1. 安装相关依赖:

    bash
    yum install -y gcc glibc gcc-c++ pcre-devel openssl-devel patch
  2. 下载Nginx源码和第三方模块(如nginx_upstream_check)

    bash
    wget https://nginx.org/download/nginx-1.26.1.tar.gz
    wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip
  3. 将第三方模块加载到Nginx模块中

    bash
    # 解压后进入Nginx目录
    # 选择一个最接近Nginx版本的
    patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch
  4. 用命令把--add-module=/root/nginx_upstream_check_module-master 添加到nginx -V 的参数中

    bash
    ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --add-module=/root/nginx_upstream_check_module-master --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
  5. 编译/安装

    bash
    make && make install

启动方式

  1. 通过systemctl启动

  2. 使用绝对路径运行

    bash
    nginx           # 启动
    nginx -s stop   # 停止
    nginx -s reload # 重载

配置文件

/etc/nginx/nginx.conf

nginx
# 核心模块
user  nginx;                 # 启动nginx虚拟用户
worker_processes  auto;      # 启动子进程的数量,auto以cpu内核数为准

error_log  /var/log/nginx/error.log notice; # 错误日志
pid        /var/run/nginx.pid;              # 进程PID存放的位置

# 事件模块
events {
    worker_connections  1024;              # TCP连接的最大连接数
}

# 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; # nginx访问日志

    sendfile        on;     # 文件高效传输
    #tcp_nopush     on;

    keepalive_timeout  65;  # 长连接的超时时间

    #gzip  on;              # 是否开启压缩
    charset utf-8,gbk       # 中文支持

    include /etc/nginx/conf.d/*.conf;   # 业务配置文件
}

业务配置文件:

nginx
server {
    listen 80;
    server_name www.sliman.com;
    location / {
        root /code/;
        index index.html index.htm;
    }
}

使用nginx -t检查语法

常用模块

nginx
charset utf-8,gbk;  # 中文支持

5.1 目录索引

  • autoindex: off|on 列出目录索引
  • autoindex_localtime: off|on 使用本地时间而不是GMT
  • autoindex_exact_size: on|off 使用精确的文件大小
nginx
autoindex on;              # 列出目录索引
autoindex_localtime on;    # 使用本地时间而不是GMT
autoindex_exact_size off;  # 人性化大小单位

5.2 用户认证

nginx
auth_basic test;                 # string|off 开启用户认证,string是一个描述
auth_basic_user_file auth_pass;  # 指定用户和密码文件

生成密码文件:

bash
yum -y install httpd-tools # 安装依赖
htpasswd -b -c /etc/nginx/auth_pass sliman sliman # 生成密码

5.3 IP限制

nginx
allow 10.11.10.0/24;  # address|CIDR|all 白名单
deny 10.11.10.0/24;   # address|CIDR|all 黑名单

5.4 状态模块

nginx
stub_status;  # [location] 访问路径显示nginx连接状态
bash
Active connections: 2               # 当前活动连接数
server accepts handled requests 
 2 2 1
# 已接收连接数量 已处理连接数量 当前http请求数
Reading: 0 Writing: 1 Waiting: 1 
# 当前读取请求头数量 当前响应的请求头数量 等待的请求数,开启了keepalive

5.5 连接限制

nginx
# [http] 区域名conn_zone,区域大小10m
limit_conn_zone $remote_addr zone=conn_zone:10m;
# [http][server][location] 同时连接数1
limit_conn conn_zone 1;

5.6 请求限制

nginx
# [http] 每秒限制请求数
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
# [http][server][location] burst: 超过连接数则延迟加载
limit_req zone=req_zone burst=3 nodelay;
# 重定向错误状态码,默认503
limit_req_status 478;
# 重定向错误页
error_page 478 /www/error/478.html;

5.7 上传大小限制

nginx
# Syntax:  
client_max_body_size size;
# Default:
client_max_body_size 1m;
# Context: http, server, location
# 网站上传文件的大小限制,默认是1m

5.8 内容替换

nginx
sub_filter 'hello' 'goodbye';

location语法优先级

匹配符匹配规则优先级
=精确匹配1
^~以某个字符串开头2
~区分大小写的正则匹配3
~*不区分大小写的正则匹配4
/通用匹配,任何请求都会匹配到5

Example:

nginx
location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

反向代理

代理配置:

nginx
proxy_pass http://www.baidu.com;

7.1 支持范围

Nginx代理服务支持的协议

  • HTTP
  • HTTPS
  • TCP
  • websocket
  • GRPC
  • POP/IMAP
  • RTMP

反向代理常用的协议

  • HTTP
  • HTTPS
  • websocket
  • GRPC

7.2 携带头部信息

nginx
# 传递Host
proxy_set_header Host $http_host;
# http版本号
proxy_http_version 1.1;
# 向服务器传递真实的$remote_addr
proxy_set_header X-Real-IP $remote_addr;
# 向服务器传递真实的$http_x_forwarded_for
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

7.3 代理TCP超时时间

nginx
# 请求后端服务器连接的超时时间,默认60s
proxy_connect_timeout 60s;
# 等待后端服务器的响应时间,默认60s
proxy_send_timeout 60s;
# 后端服务器传回给Nginx代理的超时时间,默认60s
proxy_read_timeout 60s;

7.4 代理缓冲区

Nginx将请求头部请求主体放在不同的内存缓冲区中

nginx
# 开启缓冲区
proxy_buffering on;
# 头部缓冲区大小
proxy_buffer_size 4k;
# 主体缓冲区大小
proxy_buffers 8 4k;

7.5 常用参数

常用参数可以保存至nginx/proxy_params文件中,通过include来引用

nginx
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 30s; # 代理连接web超时时间
proxy_read_timeout 60s; # 代理等待web响应超时时间
proxy_send_timeout 60s; # web 回传数据至代理超时时间


proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

# 让Nginx反向代理识别更多的后端错误码
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;

负载均衡

8.1 地址池

nginx
upstream webs {
    server 10.0.0.7;
    server 10.0.0.8;
}

location / {
    proxy_pass http://webs;
}

8.2 调度算法

调度算法概述
轮询按时间顺序逐一分配到不同的后端服务器(默认)
weight加权轮询,weight越大,分配到的访问几率越高
ip_hash每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器
url_hash按照访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器
least_conn最少链接数,哪个机器链接数少就分发给谁

轮询(默认)

nginx
upstream webs {
    server 10.0.0.7;
    server 10.0.0.8;
}

weight(加权轮询)

nginx
upstream webs {
    server 10.0.0.7 weight=5;
    server 10.0.0.8;
}

ip_hash

nginx
upstream webs {
    ip_hash; 
    server 10.0.0.7;
    server 10.0.0.8;
}

url_hash

nginx
upstream webs {
    server 10.0.0.7;
    server 10.0.0.8;
    hash $request_uri;
    hash_method crc32;
}

8.3 后端服务器状态

状态概述
down当前的server不参与调度
backup其它服务器都无法连接时采用backup服务器
max_fails允许请求失败的次数
fail_timeoutmax_fails失败后,服务暂停时间
max_conns限制最大的接收连接数

四层负载

Nginx的四层负载为假四层,采用代理的方式,配置方法如下:

  1. 编辑Nginx配置文件,在http模块外设置四层代理

    nginx
    include /etc/nginx/conf.c/*.conf;
  2. 编辑四层负载配置文件

    nginx
    stream {
        upstream webs{
            server 10.0.0.5:80;
            server 10.0.0.6:80;
        }
        server {
            listen 80;
            proxy_pass webs;
        }
    }

重写

10.1 模块语法

nginx
rewrite 1.html a.html;

后缀标记Flag:

flag作用
last最后一次rewrite匹配
break直接停止向后匹配,直接返回当前的rewrite结果,不再重新发起请求
redirect等同于return 302,临时重定向
permanent等同于return 301,永久重定向,只请求一次源站,之后浏览器缓存会将请求直接传给目标站点

重定向的其它写法:

nginx
return 301 /aaa/1.html
return 302 /bbb/2.html

开启rewrite日志:

nginx
http {
    rewrite_log on;
}

10.2 案例

错误页跳转

nginx
error_page 403 404 500 501 502 @error_test;
location @error_test {
    rewrite ^(.*)$ /404.html break;
}

在跳转后的请求行加上想要的参数&showoffline=1

nginx
# $args为Nginx内置的请求行参数
set $args "&showoffline=1";

网站维护,只允许指定IP访问

nginx
set $ip 0;
if ($remote_addr = "10.0.0.1"){
    set $ip 1;
}
if ($ip = 0){
    rewrite ^(.*)$ /wh.html break;
}

HTTPS

nginx
server {
    listen 443 ssl;
    ssl_certificate ssl_key/server.crt;
    ssl_certificate ssl_key/server.key;
    # 让php支持https
    fastcgi_param HTTPS on;
}

# 80跳转443
server {
    listen 80;
    server_name www.wp.com;
    return 302 https://$server_name$request_uri;
}

性能优化

12.1 压力测试工具

安装

bash
yum install -y httpd-tools

语法

bash
ab -n 10000 -c 200 http://127.0.0.1/
  • -n:请求数
  • -c:并发数
  • -k:是否开启长连接

12.2 系统性能优化

文件句柄最大打开数

bash
# /etc/security/limits.conf
* - nofile 65535

调整内核参数

让TIME_WAIT状态重用

bash
# /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 0

12.3 代理服务优化

配置代理使用长连接

nginx
upstream http_backend {
    server 127.0.0.1:8080;
    keepalive 16;  # 长连接
}

server {
    ...
    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";  # 清除"Connection"字段
        proxy_next_upstream error timeout http_500 http_502 http_503 http_504;  # 平滑过度
        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;

        proxy_connect_timeout 30s; # 代理连接web超时时间
        proxy_read_timeout 60s;    # 代理等待web响应超时时间
        proxy_send_timeout 60s;    # web 回传数据至代理超时时间

        proxy_buffering on;     # 开启代理缓冲区
        proxy_buffer_size 32k;  # 代理接收web响应头信息的缓冲区大小
        proxy_buffers 4 128k;   # 缓冲代理接收单个长连接内包含的web响应的数量和大小
    }
}

对于fastcgi服务器,需要设置fastcgi_keep_conn以便保持长连接

nginx
upstream fastcgi_backend {
    server 127.0.0.1:9000;
    keepalive 8;
}

server {
    location /fastcgi/ {
        fastcgi_pass fastcgi_backend;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_keepconn on;
        fastcgi_connect_timeout 60s;
        include fastcgi_params;
        ...
    }
}

12.4 静态资源优化

配置静态资源缓存场景

nginx
location ~ .*\.(jpg|gif|png)$ {
    expires      7d;
}
location ~ .*\.(js|css)$ {
    expires      30d;
}

如果开发代码没有正式上线,希望静态文件不被缓存

nginx
location ~ .*\.(js|css|html)$ {
    add_header Cache-Control no-store;
    add_header Pragma no-cache;
}

12.5 静态资源读取

大文件推荐,将多个包一次发送,提升网络传输效率,需开启sendfile

nginx
sendfile on;
tcp_nopush on;

小文件推荐,来一个包发一个,提高网络实时性,需开启keepalive

nginx
tcp_nodelay on;

12.6 静态资源压缩

nginx
location ~ .*\.(txt|xml|html|json|js|css)$ {
    gzip on;                # 开启gzip压缩
    gzip_http_version 1.1;  # 压缩协议版本
    gzip_comp_level 1;      # 压缩比
    gzip_types text/plain application/json application/x-javascript application/css application/xml text/javascript;  # 压缩哪些文件
}

12.7 防止资源盗链

nginx
location ~* \.(jpg|jpeg|gif|png|webp|svg|mp4|webm|ogg)$ {
    # 1. 白名单设置
    valid_referers none blocked 
                     ~\.google\.   # 允许谷歌图片搜索抓取
                     ~\.baidu\.   # 允许百度图片搜索抓取
                     *.example.com 
                     example.com;
    
    # 2. 拦截无效引用
    if ($invalid_referer) {
        return 403;
    }
    
    # 3. 开启静态缓存
    expires 365d;
    add_header Cache-Control "public, immutable";
    
    # 4. 安全头防XSS
    add_header X-Content-Type-Options "nosniff";
}

12.8 允许跨域访问

nginx
add_header Access-Control-Allow-Origin "https://mysite.com";
add_header Access-Control-Allow-Methods "GET, POST";

12.9 CPU亲和配置

查看Nginx worker进程绑定:

bash
ps -eo pid,args,psr|grep [n]ginx

nginx.conf中配置CPU亲和:

bash
worker_processes auto;      # 与CPU核心一致即可
worker_cpu_affinity auto;   # CPU亲和

12.10 通用优化配置

nginx
user www;                   # nginx进程启动用户
worker_processes auto;      #与cpu核心一致即可
worker_cpu_affinity auto;   # cpu亲和

error_log /var/log/nginx/error.log warn;    # 错误日志
pid /run/nginx.pid;
worker_rlimit_nofile 35535;     #每个work能打开的文件描述符,调整至1w以上,负荷较高建议2-3w

events {
    use epoll;                  # 使用epoll高效网络模型
    worker_connections 10240;   # 限制每个进程能处理多少个连接,10240x[cpu核心]
}

http {
    include             mime.types;
    default_type        application/octet-stream;
    charset utf-8;      # 统一使用utf-8字符集

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

    #定义json日志格式              
    log_format json_access '{"@timestamp":"$time_iso8601",'
                      '"host":"$server_addr",'
                      '"clientip":"$remote_addr",'
                      '"size":$body_bytes_sent,'
                      '"responsetime":$request_time,'
                      '"upstreamtime":"$upstream_response_time",'
                      '"upstreamhost":"$upstream_addr",'
                      '"http_host":"$host",'
                      '"url":"$uri",'
                      '"domain":"$host",'
                      '"xff":"$http_x_forwarded_for",'
                      '"referer":"$http_referer",'
                      '"status":"$status"}';

    access_log  /var/log/nginx/access.log  main;    # 访问日志

    server_tokens off;  # 禁止浏览器显示nginx版本号
    client_max_body_size 200m;  # 文件上传大小限制调整

    # 文件高效传输,静态资源服务器建议打开
    sendfile            on;
    tcp_nopush          on;
    # 文件实时传输,动态资源服务建议打开,需要打开keepalive
    tcp_nodelay         on;
    keepalive_timeout   65;

    # Gzip 压缩
    gzip on;
    gzip_disable "MSIE [1-6]\.";    #针对IE浏览器不进行压缩
    gzip_http_version 1.1;
    gzip_comp_level 2;      #压缩级别
    gzip_buffers 16 8k;     #压缩的缓冲区
    gzip_min_length 1024;   #文件大于1024字节才进行压缩,默认值20
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg;

    # 虚拟主机
    include /etc/nginx/conf.d/*.conf;
}

12.11 优化总结

  1. CPU亲和、worker进程数、调整每个worker进程打开的文件数
  2. 使用epool网络模型、调整每个worker进程的最大连接数
  3. 文件的高效读取sendfile、nopush
  4. 文件的传输实时性、nodealy
  5. 开启tcp长连接,以及长连接超时时间keepalived
  6. 开启文件传输压缩gzip
  7. 开启静态文件expires缓存
  8. 隐藏Nginx版本号
  9. 禁止通过ip地址访问,禁止恶意域名解析,只允许域名访问
  10. 配置防盗链、以及跨域访问
  11. 防DDOS、CC攻击,限制单IP并发连接,以及http请求
  12. 优雅显示Nginx错误页面
  13. Nginx加密传输https优化
  14. Nginx proxy_cache、fastcgi_cache、uwsgi_cache 缓存,第三方工具(squid、varnish)