http连接中客户端中断了请求,服务端会中断执行吗?超时时间设置?

由于http是基于tcp的,在tcp中,客户端中断了连接,服务端是无法感知的,只能通过发心跳包来检测,而显然我们的nginx是没有发心跳包的,所以,包括nginx,php-fpm都是不知道客户端已断开,而且web服务器也都没做这种中断机制,所以服务器依然会把客户端的请求走完,或者遇到某个超时设置才会停止执行。

测试代码:

<?php

$file = 'test-close.txt';

while(true){
	file_put_contents($file, date('Y-m-d H:i:s').PHP_EOL, FILE_APPEND);
	sleep(1);
}

在浏览器中访问

http://192.168.10.200/test.php

然后关掉这个请求

tail -f test-close.txt

可以看到,依然在不断写入,观察了5分钟,没有停下来的意思。

重启php-fpm就好了:service php-fpm restart

好了,没有再写入了。

突然想起一个问题,php.ini不是有超时时间设置吗,怎么没生效呢?

vi /etc/php.ini
看到如下:
	; Maximum execution time of each script, in seconds
	; http://php.net/max-execution-time
	; Note: This directive is hardcoded to 0 for the CLI SAPI
	max_execution_time = 30

而且phpinfo显示也是30s,说明php-fpm正确的加载了配置。

明明是有设置的,而且我使用的不是CLI模式
再看

php -i|grep max_execution_time
	max_execution_time => 0 => 0

这里又是什么设置?是因为在CLI SAPI模式下max_execution_time会被强制设置0,我们不参考这个。

再来看官网对于max_execution_time的提示:
The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real.

意思是 max_execution_time 计算的只是PHP脚本本身执行的时间,执行之外的时间都不会计算在内。哪些属于执行之外的时间呢?包含socket交互,系统调用(如sleep),系统操作等等。

设置 max_execution_time = 1,重启php-fpm
代码改为

<?php
$file = 'test-close.txt';
while(true){
	file_put_contents($file, date('Y-m-d H:i:s').PHP_EOL, FILE_APPEND);
	md5(md5(md5('aaaaaaaaaaaaaaaaaaaaaaaaaa')));
}

请求,关闭
程序1秒就终止了。

可见 max_execution_time 是生效的,只是之前sleep的系统调用一次次截断了执行时间而已,然后执行时间就变得很长了。

那么如何控制一个请求总的请求时间呢,即使你使用了sleep?

php-fpm的配置里也有请求处理时间的设置,意思就是当max_execution_time没生效时,这个超时会起作用。

vi /etc/php-fpm.d/www.conf
可以看到
; The timeout for serving a single request after which the worker process will
; be killed. This option should be used when the 'max_execution_time' ini option
; does not stop script execution for some reason. A value of '0' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_terminate_timeout = 0

这里没有设置,我来设置一下
request_terminate_timeout = 60

测试
1、重新请求,关闭,观察写入情况,发现写入一些之后就没有写了,时间短了很多。
2、CLI下 php test.php 观察十分钟也没停。ctrl+c关掉就好了。

在window的phpstudy测试,代码一样,一请求就关闭
结果是,严格按照php.ini配置的max_execution_time的秒数来执行的!!!

nginx的超时设置
keepalive_timeout 65; 该参数用于设置客户端连接保持会话的超时时间,超过这个时间服务器会关闭该连接

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 网络服务端发送RST包的原因可能有很多,其一些常见的原因如下: - 由于服务端收到了不合法的请求,例如非法协议或非法端口,所以需要立即终止连接。 - 服务端主动关闭连接。 - 服务端在收到客户端请求后,发现该请求是无效的或不能处理,需要立即终止连接。 - 由于服务端内部错误导致无法继续处理请求,需要立即终止连接。 ### 回答2: 网络服务端发送RST(重置)包通常有以下几种情况: 1. 拒绝连接:当服务端检测到某个连接请求是非法的、有安全威胁的或超过了服务端的处理能力时,服务端发送RST包,拒绝建立连接。 2. 处理错误:当服务端在处理连接过程发生错误,无法继续处理时,服务端可以发送RST包,告知对方连接中断,并且需要重新建立连接。 3. 超时:如果服务端在规定的时间内没有收到客户端的任何响应或数据包,可能认为连接已经失效或出现问题,因此发送RST包终止连接。 4. 异常终止连接:当服务端发现当前连接存在异常情况,例如对方占用过多资源、恶意攻击等,服务端可以发送RST包来迅速终止连接,以保护服务器的安全。 5. 服务端关闭:当服务端需要停止监听特定端口或关闭服务时,它发送RST包来关闭所有连接,通知客户端连接已经中断。 总之,服务端发送RST包的目的是为了管理连接、保障网络的稳定和安全性。在某些情况下,RST包可以快速终止连接,减少不必要的资源消耗和安全风险。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值