nginx超时相关参数验证.md

一、环境简介

IP地址角色
192.168.1.16nginx
192.168.1.18后端

1.nginx配置

upstream backend {
        server 192.168.1.18;
}

server {
        listen 80;

        location / {
                proxy_pass http://backend;
        }

}

2 1.18配置

1.18的配置也安装一个nginx,首页内容如下:

<html>
<head>
	<meta charset="utf-8">
</head>
<body>
	<center><h1>backend server</h1></center>
</body>
</html>

二、502问题

1.后端宕机502

1.1.停止1.18的nginx

/usr/local/nginx/sbin/nginx -s stop

1.2.客户端在次访问

页面直接出现502。次502是1.16的nginx返回给用户的

502 Bad Gateway
----------------------
nginx/1.18.0

错误日志如下:

2024/04/23 02:32:55 [error] 9052#0: *55 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.1, server: , request: "GET / HTTP/1.1", upstream: "http://192.168.1.18:80/", host: "192.168.1.16"

1.3 配置502返回页面

mkdir -p /data/wwwroot/error

# 错误页面内容如下

vim error.html
<head>
	<meta charset="utf-8">
</head>
<body>
	<h1>服务器开小差</h1>
</body>

1.4 配置1.16的nginx

upstream backend {
	server 192.168.1.18;
}

server {
	listen 80;
	
	location / {
		proxy_pass http://backend;
	}
	
    # 加入以下配置, error_page和location 必须同时配置
	error_page   500 502 503 504  /error.html;	
	location = /error.html {
		root /data/wwwroot/error;
	}
}

2.防火墙引起502

2.1 启动1.18防火墙

systemctl start firewalld

2.2 前端报错

502 Bad Gateway
nginx/1.18.0

2.3 错误日志

2024/04/23 02:29:37 [error] 9052#0: *42 connect() failed (113: No route to host) while connecting to upstream, client: 192.168.1.1, server: , request: "GET / HTTP/1.1", upstream: "http://192.168.1.18:80/", host: "192.168.1.16"

3.连接后端超时502

3.1 目标地址不存在

后端的server 不存在,也会引起502

upstream backend {
        server 192.168.1.118;
}

前端报错

502 Bad Gateway
nginx/1.18.0

错误日志。错误日志和防火墙引起502的错误日志类型一样。

2024/04/23 21:30:01 [error] 8385#0: *5 connect() failed (113: No route to host) while connecting to upstream, client: 192.168.1.1, server: , request: "GET / HTTP/1.1", upstream: "http://192.168.1.118:80/", host: "192.168.1.16"

4.后端主动断开502

后端服务器返回数据时间过长,也会引起nginx502. 此时关闭nginx,使用一个python程序来模拟后端。这样比较好复现程序超时现象。

4.1 编写后端程序

[root@node4 test]# vim main.py

from flask import Flask
import json,time


app = Flask(__name__)

@app.route('/')
def main():
    data = {
	"message": "access success!!",
	"code": "200"
    }
    
    # 这里模拟 后端服务器处理任务超时
    time.sleep(2000)
    return json.dumps(data),data["code"]

if __name__ == "__main__":
	app.run(debug=True,host="0.0.0.0")

4.2 使用gunicorn启动

这里之所以是用gunicorn去启动python,没有使用nginx直接反向代理到flask是因为,直接反向代理的时候,只要修改了flask代码,前端使用浏览器材访问一下,就会卡一下(pending一会)。
不知道为什么,但是使用gunicorn就不会出现pending的问题。

gunicorn -w 2  -b 0.0.0.0:16868 main:app

4.3 修改nginx配置

upstream backend {
		# 这里修改1.18的python程序启动端口
        server 192.168.1.18:16868;
}

4.4 超时报错

502 Bad Gateway
nginx/1.18.0

4.5 注意:

(1)gunicore程序默认是30秒没有数据传输就会主动断开。
在1.18上的抓包结果也可以看出是1.18主动断开的。

03:49:35.354454 IP 192.168.1.18.16868 > 192.168.1.16.44912: Flags [F.], seq 150174228, ack 3477334224, win 227, options [nop,nop,TS val 1310959 ecr 1360495], length 0
03:49:35.355370 IP 192.168.1.16.44912 > 192.168.1.18.16868: Flags [F.], seq 3477334224, ack 150174229, win 229, options [nop,nop,TS val 1391453 ecr 1310959], length 0
03:49:35.355421 IP 192.168.1.18.16868 > 192.168.1.16.44912: Flags [.], ack 3477334225, win 227, options [nop,nop,TS val 1310960 ecr 1391453], length 0

(2)在实际生产中,后端程序也会设置超时间,如果处理数据超时,就会抛异常,就会主动断开。nginx就会返回502。
当然前端会根据状态码进行友好提示。

4.6 -t 验证

给gunicore程序加上-t参数,设置后端的超时时间,来验证一下上述说法是否正确。
这里加了5秒的超时时间,也就是5秒内内有返回有效数据,guncrion就会超时,主动断开。

 gunicorn -w 2  -t 5 -b 0.0.0.0:16868 main:app

抓包也能看出,1.18主动断开了.
命令如下:

tcpdump -i any -nn -S host 192.168.1.16 and port 16868

结果如下:

04:04:30.132786 IP 192.168.1.18.16868 > 192.168.1.16.44920: Flags [F.], seq 471861193, ack 3371017224, win 235, options [nop,nop,TS val 2205737 ecr 2280783], length 0
04:04:30.133665 IP 192.168.1.16.44920 > 192.168.1.18.16868: Flags [.], ack 471861194, win 229, options [nop,nop,TS val 2286228 ecr 2205737], length 0
04:04:30.133914 IP 192.168.1.16.44920 > 192.168.1.18.16868: Flags [F.], seq 3371017224, ack 471861194, win 229, options [nop,nop,TS val 2286228 ecr 2205737], length 0
04:04:30.133938 IP 192.168.1.18.16868 > 192.168.1.16.44920: Flags [.], ack 3371017225, win 235, options [nop,nop,TS val 2205739 ecr 2286228], length 0

浏览器也是 加载5秒中就不在加载了,然后显示502 bad gateway了

三、504问题

1.nginx代理超时504

上边的后端处理超时,没有及时返回给前端数据,nginx就会返回浏览器502.
那么在后端处理数据的场景非常之多,不可能所有的超时场景程序员都能捕获到,然后手动抛回异常。
所有就有了意外得后端超时场景。这里手动模拟一下

1.1.程序超时设置

程序还是保留上边得超时时间

time.sleep(2000)

1.2.gunicorn设置超时

gunicorn -w 2  -t 2000 -b 0.0.0.0:16868 main:app

以上两台配置来模拟后端超时时间很长,并且不会在2000秒内主动断开连接。

1.3.浏览器访问

当浏览访问超过60秒 返回504了。

504 Gateway Time-out
nginx/1.18.0

这里得60秒超时时间就是nginx 反向代理后端得超时时间了。也就是说后端在60秒内没有返回给nginx数据,nginx就会主动断开连接。通过抓包也可以看出来。

1.4.设置代理超时时间

proxy_read_timeout 此参数得默认值就是60S,现在改成5秒。

server {
        listen 80;

        location / {
                proxy_pass http://backend;
                proxy_read_timeout 5;
        }
}

再次刷新浏览器,发现浏览器加载5秒后不在加载,然后通过抓包可以看到,nginx主动断开了连接。

1.5 总结

proxy_read_timeout 此参数得含义就是nginx等待后端返回数据得时间,超过这个时间就会返回504

2.连接超时504

连接超时504,一般出现在nginx 和后端server建立得时候产生得504.接下来模拟一下。

2.1.设置防火墙策略

在1.18上设置网络策略,来模拟网络问题

iptables -A OUTPUT -d 192.168.1.16 -j DROP

nignx还原默认配置

server {
        listen 80;

        location / {
                proxy_pass http://backend;
        }
}

2.2 验证

在浏览器发起访问,发现在建立三次握手得时候就没有成功,浏览器经过60秒后,不在加载。也返回

504 Gateway Time-out
nginx/1.18.0

2.2.设置连接超时时间

proxy_connect_timeout 参数就是设置连接后端server得时候得超时时间。
修改nginx配置,设置连接超时为5秒

upstream backend {
	server 192.168.1.18:16868;
}

server {
	listen 80;
	
	location / {
		proxy_pass http://backend;
		proxy_connect_timeout 5;
	}
	
}

在浏览器访问,发现浏览加载5秒,不会在在继续记载等待。

四、后端健康检测

说到后端健康检测,就说到了以下两个配置,
一个是max_fails,
另一个是fail_timeout

网上对max_fails得解释都一致,表示连接后端节点得次数。
fail_timeout具体表示什么意思,我也不知道,网上得解释众说纷纭。我是根据下边得配置来得到结论

1.后端超时

1.1 后端程序

[root@node4 test]# cat main.py 
from flask import Flask
import json,time


app = Flask(__name__)

@app.route('/')
def main():
    # 让程序休息200秒,模拟程序超时200秒
    time.sleep(200)
    return "<h1>port 16868<h1>"

if __name__ == "__main__":
	app.run(debug=True,host="0.0.0.0")

1.2 启动程序

gunicorn -w 1 -t 2000 -b 0.0.0.0:16868 main:app

1.3 配置nginx

upstream backend {
        server 192.168.1.18:16868 max_fails=2 fail_timeout=5;
}

server {
        listen 80;

        location / {
                proxy_pass http://backend;
        }

}

1.4 浏览器访问

使用浏览器访问,浏览器没有在5秒得时候,主动断开连接,这说明fail_timeout参数不是用户单次请求后端得超时间。浏览器依然是在默认得60s断开的。

1.5 增加超时配置

upstream backend {
	# 这里fail_timeout 调整到100
	server 192.168.1.18:16868 max_fails=2 fail_timeout=100;
}

server {
	listen 80;
	
	location / {
		proxy_pass http://backend;
		# 这里超时时间调整为1秒
		proxy_read_timeout 1;
	}
	
}

这里是单节点,发送了两次请求,1.18依然可以收到请求。nginx也依然会将请求转发到1.18

1.6 宕到1.18的16868服务

(1)当1.18的16868服务直接宕掉之后直接返回502.但是通过抓包,1.18依然可以收到nginx建立连接的请求。
(2)所以说明在单节点的情况下,这两个组合参数和不配置的区别的不大。
目前到这里依然没有明确fail_timeout参数的含义。

2.增加节点

upstream backend {
	server 192.168.1.18:16868 max_fails=3 fail_timeout=100;
	server 192.168.1.18 max_fails=3 fail_timeout=10;
}

server {
	listen 80;
	
	location / {
		proxy_pass http://backend;
		proxy_read_timeout 1;
	}
	
}

2.1 使用浏览器访问

2.1.1 访问现象

出现轮询显现,但是轮到到1.18的16868端口的时候,因为后端的程序会超时,所有在一直加载,但是在nginx中又设置了proxy_read_timeout 1,所有过了1秒就会断开。
虽然请求被负载到了16868端口上,但是页面一直停留在80端口的页面上。

2.1.2 结果

当1.18的16868端口累计断开了3次(max_fails次数)之后,通过抓包得知
(1)nginx在fail_timeout时间内不会再将请求转发给1.18的16868端口。
(2)在超过fail_timeout时间后,在刷新浏览器的时候,nginx只会发送一次(注意:是1次)请求 去连接后端16868端口是否存活。

2.2 使用nginx配置

upstream backend {
	# 这里由100改为10秒
	server 192.168.1.18:16868 max_fails=3 fail_timeout=10;
	server 192.168.1.18 max_fails=3 fail_timeout=10;
}

server {
	listen 80;
	
	location / {
		proxy_pass http://backend;
		# 删除超时
	}
}

2.3 取消程序超时

删除 time.sleep(1)代码

2.4 验证

再次使用浏览器访问,出现正常的轮询状态。

2.5 停止1.18的16868服务

通过抓包依然得到如上结论:

2.5.1 访问现象

当1.18的16868服务停止后,页面一直停留在80端口的页面,没有跳转到80的报错页面
但是通过tcpdump抓包得知,请求依然被转发到了16868端口。

listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
# 一次连接
21:59:31.395083 IP 192.168.1.16.50124 > 192.168.1.18.16868: Flags [S], seq 1025926583, win 29200, 
21:59:31.395123 IP 192.168.1.18.16868 > 192.168.1.16.50124: Flags [R.], seq 0, ack 1025926584, win 0, 

# 两次次连接
21:59:34.016791 IP 192.168.1.16.50130 > 192.168.1.18.16868: Flags [S], seq 3104815423, win 29200, 
21:59:34.016824 IP 192.168.1.18.16868 > 192.168.1.16.50130: Flags [R.], seq 0, ack 3104815424, win 0, 

# 三次连接
21:59:36.915576 IP 192.168.1.16.50136 > 192.168.1.18.16868: Flags [S], seq 1161735139, win 29200, 
21:59:36.915605 IP 192.168.1.18.16868 > 192.168.1.16.50136: Flags [R.], seq 0, ack 1161735140, win 0, 

2.5.2 结果

当16868端口失败连接次数累计达到3次(max_fails次数)之后。

(1)nginx在fail_timeout时间内不会再将请求转发给1.18的16868端口。
(2)在超过fail_timeout时间后,在刷新浏览器的时候,nginx只会发送一次(注意:是1次)请求 去连接后端16868端口是否存活。

2.6.恢复16868端口

当16868端口恢复后,nginx不会立即去探测它的存活,依然会等到fail_timeout过后再去探测它是否存活。

3.默认配置

如果upstream中的server中采用了默认配置

upstream backend {
	server 192.168.1.18:16868;
	server 192.168.1.18;
}

那么

max_fails的默认值为1
fail_timeout的默认值为10秒

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/578078.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c++多文件,cmakelist编写简单示例

记录下c多文件cmakelist编写流程&#xff1a; 目录结构大致如下&#xff1a; 1、swap.h #include <iostream> #include <vector> #include <string> using namespace std;void swap(int *a,int *b); 2、swap.cpp #include "swap.h"void swap(…

【Linux学习】​​学习Linux的准备工作和Linux的基本指令

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

iOS - 多线程-读写安全

文章目录 iOS - 多线程-读写安全1. 多读单写1.1 场景1.2 实现方案1.2.1 pthread_rwlock&#xff1a;读写锁1.2.1.1 示例 1.2.2 dispatch_barrier_async&#xff1a;异步栅栏调用1.2.2.1 示例 iOS - 多线程-读写安全 假设有一个文件&#xff0c;A线程进行读取操作&#xff0c;B…

【Linux】基础指令

文章目录 基础指令1. pwd 指令2. cd 指令3. ls 指令4. touch 指令5. mkdir 指令6. rmdir 和 rm 指令7. man 指令8. cp 指令9. mv 指令10. cat 指令11. more 和 less 指令12. head 和 tail 指令13. date 指令14. cal 指令15. find 指令16. grep 指令18. zip 和 unzip 指令19. ta…

Unity打开Android文件管理器并加载文件

1、在AssetStore商店中加入免费插件 2、调用代码 3、使用UnityWebRequest加载路径数据

RabbitMQ(高级)笔记

一、生产者可靠性 &#xff08;1&#xff09;生产者重连&#xff08;不建议使用&#xff09; logging:pattern:dateformat: MM-dd HH:mm:ss:SSSspring:rabbitmq:virtual-host: /hamllport: 5672host: 192.168.92.136username: hmallpassword: 123listener:simple:prefetch: 1c…

【问题实操】银河高级服务器操作系统实例分享,配置hugepages启动异常

1.问题现象 某运营商国产服务器操作系统项目&#xff0c;部署Kylin-Server-0524-aarch64服务器系统&#xff0c;内核从4.19.90-24.4升级到4.19.90-25.14。在grub中配置huagepages大页内存后&#xff0c;系统在内核启动阶段黑屏&#xff0c;只显示一个光标。grub配置如下图&…

Springboot+Vue项目-基于Java+MySQL的商业辅助决策系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

深度学习论文: MobileNetV4 - Universal Models for the Mobile Ecosystem及其PyTorch实现

深度学习论文: MobileNetV4 - Universal Models for the Mobile Ecosystem及其PyTorch实现 MobileNetV4 - Universal Models for the Mobile Ecosystem PDF: https://arxiv.org/pdf/2404.10518.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: ht…

Post请求中常见的Content-Type类型

Post请求中常见的Content-Type类型的结构 &#xff08;1&#xff09;application/x-www-form-urlencoded 这是浏览器原生的form表单类型&#xff0c;或者说是表单默认的类型。 下面是一个请求实例&#xff1a; 请求报文&#xff1a; 可以看得出&#xff0c;post将请求参数以k…

配置jupyter的启动路径

jupyter的安装参考&#xff1a;python环境安装jupyter-CSDN博客 1&#xff0c;背景 继上一篇python环境安装jupyter&#xff0c;里面有一个问题&#xff0c;就是启动jupyter&#xff08;命令jupyter notebook&#xff09;之后&#xff0c;页面默认显示的是启动时候的路径。 …

HarmonyOS开发案例:【使用List组件实现设置项】

介绍 在本篇CodeLab中&#xff0c;我们将使用List组件、Toggle组件以及Router接口&#xff0c;实现一个简单的设置页&#xff0c;点击将跳转到对应的详细设置页面。效果图如下&#xff1a; 相关概念 [CustomDialog]&#xff1a;CustomDialog装饰器用于装饰自定义弹窗。[List]…

RabbitMQ工作模式(4) - 路由模式

概念 路由模式&#xff08;Routing&#xff09;是 RabbitMQ 中的一种消息传递模式&#xff0c;也称为直连模式。它允许生产者将消息发送到一个交换机&#xff0c;并指定一个或多个路由键&#xff08;routing key&#xff09;&#xff0c;交换机根据路由键将消息路由到与之匹配的…

【介绍下Chrome插件开发】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

使用 NVM 动态切node版本

一、安装nvm 官网链接&#xff1a; Release 1.1.9 coreybutler/nvm-windows GitHub 无脑安装直接下一步 安装完之后验证一下&#xff1a; #打开命令行输入命令 nvm 这样就是安装好了&#xff0c;然后我们开始安装node。 二、使用nvm安装node 1、去node官网获取版本号 …

【算法】人工蜂群算法,解决多目标车间调度问题,柔性车间调度问题

文章目录 复现论文什么是柔性作业车间调度问题&#xff1f;数据处理ABC算法编码解码种群初始化雇佣蜂操作IPOX交叉多点交叉 观察蜂操作侦察蜂操作算法流程 结果程序截图问询、帮助 复现论文 什么是柔性作业车间调度问题&#xff1f; 也叫多目标车间调度问题。 柔性作业车间调…

什么是pytest自动化测试框架?如何安装和使用呢?

一、pytest是什么&#xff1f; pytest是一款强大的Python测试工具&#xff0c;可以胜任各种类型或级别的软件测试工作。实际上&#xff0c;越来越多的项目在使用pytest。因为pytest会提供更丰富的功能&#xff0c;包括assert重写、第三方插件&#xff0c;以及其他测试工具无法…

数字IC后端先进工艺设计实现之TSMC 12nm 6Track工艺数字IC后端实现重点难点盘点

大家知道咱们社区近期TSMC 12nm ARM Cortexa-A72(1P9M 6Track Metal Stack)已经开班。这里小编要强调一点:不要认为跑了先进工艺的项目就会很有竞争力&#xff01;如果你仅仅是跑个先进工艺的flow&#xff0c;不懂先进工艺在数字IC后端实现上的不同点&#xff0c;为何有这样的不…

Kali Linux中抓包工具Burp Suite安装教程_kali burpsuite抓包教程

目录 安装环境 一、Kali Linux系统信息 ​编辑 二、安装及配置 1.下载Burp Suite 2.安装 3.配置proxy代理 安装环境 主机&#xff1a;MacBooPro 2021 M1 Pro 系统&#xff1a;Ventura 13.1 虚拟机软件&#xff1a;Parallels Desktop 虚拟机系统&#xff1a;Kali Linux…

文件类型的活码怎么制作?文件二维码在线生成的方法

文件的二维码现在很常见&#xff0c;通过这种方式来分享文件有很多的好处&#xff0c;比如文件的安全性更高&#xff0c;可以多人同时查看&#xff0c;有利于传播分享&#xff0c;而且这种方式的成本比较低&#xff0c;生成一个长期有效的活码二维码可以一直使用。 活码二维码…
最新文章