Nginx文档笔记

一、安装

  1. 安装文档
  2. Ubuntu:除了文档列出的依赖,额外依赖
    1
    2
    3
    4
    5
    sudo apt install libssl-dev
    sudo apt install libxml2-dev
    sudo apt install libxslt1-dev
    sudo apt install libgd-dev
    sudo apt install libgeoip-dev

二、nginx管理

  1. 一个master进程和多个worker进程,如果缓存开启,则缓存加载和缓存管理两个进程也在初始化运行
  2. nginx通过信号管理,除了nginx -s quit/reload/reopen/stop 也可以通过kill 命令发送信号给master进程

三、Web服务器

静态资源

  1. root 指定资源根目录
  2. location 匹配url, =普通字符串匹配,~表示正则匹配
  3. sendfile,sendfile_max_chunk:允许数据从一个文件描述符直接拷贝到另外一个,指定分片大小避免较快的连接长期占用worker进程
  4. tcp_nodelay:禁用nagle算法,避免延迟响应,配合keepalive
  5. backlog:支持更多连接,需要配合内核配置优化

反向代理

  1. proxy_pass: 请求发送到指定服务组
  2. proxy_bind:如果代理服务器有多个网卡,则与上游服务连接时可以指定ip地址
  3. proxy_set_header,proxy_buffer_size,proxy_timeout,proxy_connect_timeout等
  4. SSL: 基本原理与配置与https一致

压缩

  1. gzip
  2. gzip_types
  3. gzip_min_length:低于这个阈值不会进行压缩
  4. gzip_proxied:如果请求来自代理服务器,则不会进行压缩,所以通过检查请求的cache-control,符合条件的才进行压缩
  5. gzip_static:允许直接发送压缩文件
    1
    2
    3
    4
    5
    6
    7
    server {
    gzip on;
    gzip_types text/plain application/xml;
    gzip_proxied no-cache no-store private expired auth;
    gzip_min_length 1000;
    ...
    }

四、负载均衡

HTTP负载均衡

代理

  1. 设置一组上游服务 upstream, 默认使用round robin 算法
  2. 通过proxy_pass 指定上游服务组

算法

  1. round robin:通过server_weight 参数轮询
  2. least_conn:发送给最少连接的上游服务,server_weight 参数作为参考
  3. ip_hash:通过ip地址计算哈希值,如果需要移除一台服务,则可以设置为down,则请求将依规则发给下一台
  4. hash:用户定义的哈希值进行路由
  5. random:随机取出指定数量的服务,从中再根据least_conn算法路由

慢启动

  1. 设置slow_start 避免服务刚恢复时,承载过多请求

服务失败检测

  1. max_fails:失败达到参数设置,则nginx认为服务不可用,默认1次
  2. fail_timeout:认为不可用的持续时间,即不再重试的时间,默认10s

数据共享

  1. 设置zone可以使nginx多个worker进程共享相同的upstream 服务组设置及相关计数

使用DNS

  1. 设置resolver,valid为ttl时间,ipv6可以设置关闭
  2. upstream 下各服务为域名

TCP、UDP负载均衡

  1. 与http负载均衡类似

反向代理时传递客户端的真实IP而非负载均衡器的IP地址

  1. 配置nginx接受代理协议,则nginx将真实客户端ip和端口存储在变量$proxy_protocol_addr,$proxy_protocol_port

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    http {
    #...
    server {
    listen 80 proxy_protocol;
    listen 443 ssl proxy_protocol;
    #...
    }
    }

    stream {
    #...
    server {
    listen 12345 proxy_protocol;
    #...
    }
    }
  2. http修改当前server ip为当前实际客户端的ip

    1
    2
    3
    4
    5
    6
    http {
    server {
    #...
    real_ip_header proxy_protocol;
    }
    }
  3. 将ip地址传递给上游服务

    1
    2
    3
    4
    http {
    proxy_set_header X-Real-IP $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
    }
  4. 将$proxy_protocol_addr添加到log_format中

五、安全

SSL

安全地协商出一份对称加密秘钥
RSA算法流程

  1. 客户端发送client hello,客户端随机数,带上可选加密参数信息
  2. 服务端响应server hello,服务端随机数,已选加密参数信息
  3. 服务端响应certificate,发送服务器证书,server hello done
  4. 客户端发送证书公钥加密后的预主秘钥,客户端进一步用预主秘钥生成主秘钥,发送第一个用主密钥加密的数据
  5. 服务端用证书私钥解密预主秘钥,生成主密钥,握手完成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

server {
listen 443 ssl;
server_name www.example.com;
keepalive_timeout 70;

ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
#...
}
}

https优化

  1. 使用keepalive
  2. 复用SSL会话参数,避免重复SSL握手

同一个IP支持多个https server

  1. 因为SSL先于浏览器发送http请求,所以,服务端只提供默认证书,致使请求都指向默认server
  2. 最好的解决方法是,分ip部署https server
  3. 另外可以通过使用多个域名公共证书,同时需要TLS SNI support enabled

HTTP基础认证

  1. auth_basic:对话框的用户区
  2. auth_basic_user_file:用户密码表的文件路径
  3. satisfy allow deny 设置ip限制
  4. auth_request 可以指定认证location

限流

  1. limit_conn_zone limit_conn: 限制连接数,限制每个客户端的连接数也可以设置服务接收的连接数
  2. limit_req_zone limit_req: 限制某个location下,请求的频率;burst,如果请求超出限制区,则burst为队列长度,其他请求立即返回503
  3. limit_rate: 限制location下的带宽