苏苏的博客

简约至极

nginx安装与使用

使用systemd管理nginx

/usr/lib/systemd/system/nginx.service

[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

nginx proxy_request_buffering

上传大文件时需注意

https://stackoverflow.com/questions/12282342/nginx-files-upload-streaming-with-proxy-pass

accept_mutex and reuseport

https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/

fast-open –reuse-port –no-delay no-push

nginx mirror module

https://alex.dzyoba.com/blog/nginx-mirror/

upstream test {
    server 127.0.0.1:9091;
    server 127.0.0.1:9092;
    server 127.0.0.1:9093;
}

server{
    listen 8070;
    server_name hello.git.suconghou.cn;
    location / {
        location /v1/srv/wxtp/authnotify {
            mirror /mirror;
            mirror_request_body on;
        }
        proxy_pass http://test;
    }

    location /mirror {
        internal;
        set $dist '';
        if ($request_uri ~* /v1/(.*) ){
            set $dist /dev/$1;
        }
        proxy_pass http://127.0.0.1:8899$dist;
    }
}

nginx 负载均衡与健康检查

upstream report{
    server localhost1:18080 max_fails=3 fail_timeout=30s;
    server localhost1:28080 max_fails=3 fail_timeout=30s;
    server localhost2:18080 max_fails=3 fail_timeout=30s;
    server localhost2:28080 max_fails=3 fail_timeout=30s;
}

负载均衡配置了4台机器

max_fails = 3 fail_timeout=30s 表示 ${fail_timeout}(30秒)时间内出现${max-fails}(3次)次失败,就会把这个机器状态置为down(下线),失败$(fail_timeout)(30秒)时间后,会重新尝试启用这服务器;

Nginx只有当有访问时后,才发起对后端节点探测。如果本次请求中,节点正好出现故障,Nginx将把请求转交给接下来的节点处理。是否转发给下一个节点处理由 proxy_next_upstream 控制

语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off …;

默认值: proxy_next_upstream error timeout;

上下文: http, server, location

error # 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误
timeout # 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时
invalid_header # 后端服务器返回空响应或者非法响应头
http_500 # 后端服务器返回的响应状态码为500
http_502 # 后端服务器返回的响应状态码为502
http_503 # 后端服务器返回的响应状态码为503
http_504 # 后端服务器返回的响应状态码为504
http_404 # 后端服务器返回的响应状态码为404
off # 停止将请求发送给下一台后端服务器

如果探测所有节点均失效,备机也为失效时,那么nginx会对所有节点恢复为有效,重新尝试探测有效节点,如果探测到有效节点则返回正确节点内容,如果还是全部错误,那么继续探测下去,当没有正确信息时,节点失效时默认返回状态为502,但是下次访问节点时会继续探测正确节点,直到找到正确的为止。

nginx 默认是对非幂等请求不重试的(POST、LOCK、PATCH)

要对非幂等请求也重试要加上non_idemponent;

proxy_next_upstream error timeout http_500 non_idemponent;

生产环境中不建议加上non_idempotent选项

   location / {
        proxy_intercept_errors on;
        proxy_set_header Host $host;
        proxy_pass http://www_server3_plools;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_next_upstream error timeout http_503 non_idempotent;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }

        error_page 500 502 503 504 =200 /error.json;
        location = /error.json{
            default_type application/json;
            return 200 '{"retCode":"1001","retMsg":"invoke failed"}';
       }

nginx tls1.3

nginx 性能提升

http2 + tls1.3 + nginx upstream keepalive

openssl-cli s_client -connect beta.tupianzhibo.cn:443 -tls1_3

The only 100% safe things which may be done inside if in a location context are:

return …; rewrite … last;

https://www.jianshu.com/p/20a687873bf0

client_header_buffer_size
large_client_header_buffers

为什么 Nginx 在处理 header 时会只能读取 default_server 的 client_header_buffer_size 配置呢?

这个 default_server 是相对于 vhost 而言的。同一 ip:port 上的不同 vhost 通过域名相互区分。Nginx 收到请求后会根据域名定位到对应的 vhost 的 server 配置。然而,Nginx 解析域名(header 解析阶段)的时候就要用到 client_header_buffer_size 这个配置,所以没办法,只能取个默认值(default_server)了。最终结论是所有在 header 解析阶段用到的配置都只能从 default_server 读取,因为这个时候无法确定要用哪个具体的 server。

query

如果域名后面添加了路径,则不会转发

proxy_pass $live_server/beta$uri;

可以使用下面的

proxy_pass $live_server/beta$uri$is_args$args;

或者 $request_uri 变量