nginx 499错误处理及nginx的配置参数
作者:mmseoamin日期:2023-12-20

nginx 499错误处理及nginx的配置参数

背景

近期响应集团降本增效,节省ci,stg机器,我们项目开始容器化,在改造过程中,链路的访问发生了变化,导致出现了499,解决方如下

访问链路: 域名—> ELB (内网访问) —> openrestry (stg环境,支持自定义lua脚本) —> ELB(提供服务固定ip) —> (容器集群)POd

499处理

nignx报499的原因是服务端响应超时,nginx主动断开连接。例如:nginx配置默认超时时间为60s,当服务端接口响应为62s才返回结果,那么当60s时,nginx主动断开连接。

1. 调整如下proxy_xxx_timeout

2. 优化接口,提高接口的响应速度

server{
    location / {
        proxy_connect_timeout 200;
        proxy_send_timeout 200;
        proxy_read_timeout 200;
    }
}

proxy_connect_timeout: 控制与后端服务器建立连接的超时时间,单位是秒,默认是60秒。

proxy_read_timeout: 控制等待后端服务器响应的超时时间,单位是秒,默认是60秒。

proxy_send_timeout: 控制发送请求到后端服务器的超时时间,单位是秒,默认是60秒。

这三个参数都是在使用 nginx 作为反向代理时,用于限制与后端服务器通信的超时时间,从而避免代理服务器被后端服务器的响应阻塞而无法响应客户端的请求。例如,如果后端服务器出现了异常或网络故障,会导致响应的延迟或永远不返回,此时代理服务器会等待超时时间,然后返回错误响应。

注意:在使用这些超时设定时,应当考虑应用程序的网络和运行环境,以便确定适当的超时时间。超时时间设置过短可能导致请求失败,而设置过长可能导致前端网站的响应变慢。可以适当根据实际情况调整,并进行测试,以确保可靠性和性能。参数值也不是越大越好,对于确实响应慢的接口,要进行性能优化。

知识扩展: nginx配置参数

server{
    location / {
        proxy_ignore_client_abort  on;
        proxy_connect_timeout 200;
        proxy_send_timeout 200;
        proxy_read_timeout 200;
    }
}

proxy_ignore_client_abort: 用于实现“忽略客户端终止”功能。默认情况下,“nginx”会将与客户端的连接请求转发到后端服务器,但如果客户端中途断开请求服务,则通常会导致到后端的连接被提前关闭。这时,后端程序可能会继续执行一段时间,但已经无法将响应发送回代理服务器,因此可能导致代理服务器上的错误响应。

proxy_ignore_client_abort: off 默认配置,客户端断开连接会中止响应

proxy_ignore_client_abort: on 客户端断开连接不会中止响应,代理服务器将忽略客户端请求终止,并让后端服务器继续响应,直到响应完成。

http:{
    fastcgi_connect_timeout 200;
    fastcgi_send_timeout 200;
    fastcgi_read_timeout 200; 
}

以上参数当你的技术选型里有包含FastCGI,可以考虑开启上述fastcgi_xx_timeout参数。

如未接触过,我们来简单介绍下: FastCGI(Fast Common Gateway Interface)是一种 Web 应用程序的接口协议,它提出了一种新型的方式来处理动态 Web 内容。astCGI 和早期的 CGI 脚本处理方式不同,CGI 脚本在每次请求时都会启动新的进程,这可能造成性能损失和资源浪费。而 FastCGI 利用了一些进程复用技术,使得每个应用程序可以一直保持在内存中的状态,等待下一次请求,大大提高了性能。

Tomcat容器并未内置FastCGI功能,在标准的SpringBoot应用程序中,你需要特别安装、配置和/或使用第三方 FastCGI 库或框架来实现与 FastCGI 协议的通信。例如,可以使用 Mod_jk 来实现 Tomcat 与前端 Web 服务器之间的 FastCGI 通信。

http {
    client_max_body_size 500m; //限制客户端请求体超过配置的值,超过返回413
    client_body_buffer_size 10M; //
    # client_body_temp: /xx // 大于client_body_buffer_size是存储的磁盘目录
    keepalive_timeout  65s; //
    client_header_timeout 600s; //
    client_body_timeout  600s;  // 
    proxy_connect_timeout 200s;
    proxy_send_timeout    200s;
    proxy_read_timeout    200s;
    proxy_max_temp_file_size 0;
    limit_req_zone $binary_remote_addr zone=burstLimit:10m rate=40r/s;
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_types text/plain text/css application/json application/x-javascript application/javascript text/javascript appliaction/xml;
    gzip_comp_level 3;
    gzip_disable "MSIE [1-6].(?!.*SV1)";
    gzip_vary off;
}

client_max_body_size: 限制客户端请求体超过配置的值,超过返回413 Request Entity Too Large,在http,server,location均可配置。这个参数是针对单个请求体的大小,而不是控制所有请求的综合大小。

client_body_buffer_size: 客户端请求体数据到内存时缓存区分配的大小。如果请求的数据小于这个配置直接将数据先在存在内存,如果请求的值大于client_body_buffer_size小client_max_body_size,就会将数据先存储到临时文件中,临时文件默认路径是/tmp/,也可通过配置client_body_temp指定目录

client_body_temp: 当请求体大于client_body_buffer_size小于client_max_body_size是,配置这个参数存储到指定的磁盘路径,注意这个需要修改权限(chomd),否则会报Permission denied

keepalive_timeout: 当使用http/1.1协议是,可以使用keepalive复用tcp的连接,减少tcp三次握手四次挥手建立网络连接的时间。keepalive_time的意思是每次请求完毕后保持指定时间的连接,可以避免频繁创建和关闭连接的过程。默认值是75s,若设置为0,表示禁止keepalive连接

client_header_timeout: 客户端像服务端发送一个完整的request header的超时时间,默认60s,如果客户端在指定时间内没有发送一个完整的request header,nginx返回http 408(request time out)

client_body_timeout: 户端像服务端发送一个完整的request body的超时时间, 默认60s,如果客户端在指定时间内没有接受到请求体数据,注意不是整个请求提数据传输,是在接受到header后到开始传输body这个过程的超时时间(官方文档: The timeout is set only for a period between two successive read operations, not for the transmission of the whole request body If a client does not transmit anything within this time, the request is terminated with the 408 (Request Time-out) error.), nginx返回http 408(request time out)。

proxy_max_temp_file_size: 缓存到磁盘的文件大小,如果设置为0,则不缓存到磁盘。如果超过了设置的值,则nginx将与proxy的服务器同步的传递内容,则不在还缓冲到磁盘

limit_req_zone: nginx限流模块,$binary_remote_addr表明限制的目标,remote_addr记录的是ip信息占用7~15个字节,binary_remote_addr表示压缩的ip,仅占用4个字节。zone=name:size分配一个名为name的并且大小为size的内存空间,用来存储访问的频次信息;rate=40r/s表示同一个ip每秒只允许40个请求通过

gzip: on:开启gzip压缩静态资源, off关闭

gzip_min_length: 1k 配置开启压缩的大小,资源大于这个的才压缩,再小就不要压缩

gzip_buffers 4: 16k 缓冲,压缩在内存缓冲几块,每块多大

gzip_types: text/plain text/css application/json application/x-javascript application/javascript text/javascript appliaction/xml; 对那些类型的文件用压缩

gzip_comp_level: 3; 压缩级别([1-9]级别越高,压的越小,越耗费CPU计算时间)

gzip_disable: “MSIE [1-6].(?!.*SV1)”; 正则匹配什么样的uri不进行gzip压缩,此处表示ie6及一下不启用gzip(因为这些版本不支持)

gzip_vary: off 是否传输压缩标志

nginx增加健康检查

nginx开源版本没有自带负载均衡后端节点的健康检查,但是通过额外的nginx_upstream_check_module模块对后端节点做健康检查。

upstream name{
 server 192.168.0.1:80;
 server 192.168.0.2:80;
 check interval=3000 rise=2 fail=5 timeout=1000 type=http;
}

对name的这个upstream负载均衡,每个节点3s检测一次,请求2次正常则标记realserver状态为up,如果检测5次都失败,则标记ralserver状态为down,超时时间为1s.

各种负载均衡软硬件

ELB HAproxy nginx openresty F5 LVS

HaProxy: 一款负载均衡软件,与nginx角色一样,支持TCP/HTTP两种协议的负载均衡,使得其负载均衡功能非常丰富;支持8种左右的负载均衡算法,尤其是在http模式下,有非常多的实用的均衡算法;拥有一个功能出色的监控页面,实时了解系统当前的状态;功能强大的ACL支持,给用户极大的方便(ACL access control list访问控制列表: 符合ACL规则请求由backend指定的后端服务器池执行基于ACL规则的负载均衡,不符合的可以直接中断响应,也可以交由其他服务器执行);自带监控检查,nginx需要增加额外的模块支持健康检查。缺点是配置文件比较繁琐,需要一定的技术水平和经验进行部署和维护。

ELB: AWS提供的云软件负载均衡服务,实用云端的应用部署,有点易于使用;缺点是定制化自定义有限,对企业级需要可能不够全面

F5: 负载均衡硬件,性能非常好,每秒处理的请求数可以达到百万级,采购价格也非常贵十几万到百万人民币都有,适用于大型企业流量特别多的情况。

LVS: 软件负载均衡,由阿里的章文嵩博士研发,是国内最早的自由软件,配置方便,抗负载能力强;不足:不支持正则处理,不支持做动静分离,对网络环境比较依赖

openresty: 对nginx的扩展,自由度高支持实用lua及大量的第三方模块,方便的搭建能够处理高并发,扩展性极高的web应用,网关,从而将nginx从简单的负载均衡,变成一个强大的网关、通用的web应用平台。

参考

nginx官方文档 Module ngx_http_core_module

Nginx的超时keeplive_timeout配置详解

nginx限流方法一:limit_req&limit_req_zone限制处理速率

Haproxy 的 ACL 规则及实战案例

Nginx和HAProxy对比,各有什么优点与不足?

nginx负载均衡配置,宕机自动切换