Pages

Sunday, 16 May 2021

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 变量

------------------

nginx配置负载均衡


  1. 负载均衡原理

    七层的负载均衡

    负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。简单而言就是当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。而Nginx目前支持自带3种负载均衡策略,还有2种常用的第三方策略。

    主要用到upstream模块

  2. 负载均衡算法

    默认是rr算法

    每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

    1
    2
    3
    4
    upstream test {
    server localhost:8080;
    server localhost:8081;
    }
    wrr

    指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
    例如

    1
    2
    3
    4
    upstream test {
    server localhost:8080 weight=9;
    server localhost:8081 weight=1;
    }

    那么10次一般只会有1次会访问到8081,而有9次会访问到8080

    ip-hash

    上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用ip_hash了,ip_hash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

    1
    2
    3
    4
    5
    upstream test {
    ip_hash;
    server localhost:8080;
    server localhost:8081;
    }
    url-hash

    按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法

    1
    2
    3
    4
    5
    6
    upstream backend { 
    hash $request_uri;
    hash_method crc32;
    server localhost:8080;
    server localhost:8081;
    }
    fair

    上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用ip_hash了,ip_hash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

    1
    2
    3
    4
    5
    upstream test {
    ip_hash;
    server localhost:8080;
    server localhost:8081;
    }

    会话保持推荐使用ip-hash

  3. 负载均衡实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      upstream xiaomi {
    server 172.16.10.221:80;
    server 172.16.10.222:80;
    }
    server {
    listen 80;
    server_name nginx.myi-cloud.com;
    client_max_body_size 1024M;
    location / {
    proxy_pass http://xiaomi;
    proxy_set_header Host $host:$server_port;
    }
    }

No comments:

Post a Comment