同步请求的脚本超时要略小于反向代理超时并留出余量,离线任务按其近段时间P95耗时上浮到1.5至2倍,且任何时候都要小于调用方(上游)的超时。 把这三条守住了,再谈具体数字才有意义。
超时其实分三层,只调脚本那一层等于白调
很多人一上来就改 max_execution_time,改完发现还是502,问题往往不在脚本本身,一次请求从用户点击到返回,路上至少经过三道“计时器”。
客户端与网关层
浏览器、App、SDK 自己带超时;Nginx、负载均衡、API 网关又是一层,任何一层先到点,后面的脚本就算是正常运行,用户看到的也是报错,业内专家指出,线上超时故障里相当一部分是各层超时值拼不起来造成的,而不是某一层设得太短。
反向代理层
Nginx 常见的几个参数:
proxy_connect_timeout:连后端多久算失败,一般 3 到 5 秒proxy_read_timeout:等待后端响应的时间,默认 60 秒fastcgi_read_timeout:PHP-FPM 场景下的读取超时
脚本运行时层
- PHP:
max_execution_time、php-fpm 的request_terminate_timeout - Python:Gunicorn 的
timeout、requests 的timeout=参数 - Node:
server.setTimeout()、各 HTTP 客户端的 timeout - Shell:
timeout命令、systemd 的TimeoutSec
判断顺序很简单:谁的计时器先响,谁就决定最终结果,所以配置原则是从外到内逐层递减,最外层最长,最内层最短。
| 层级 | 典型参数 | 建议取值逻辑 |
|---|---|---|
| 网关/代理 | proxy_read_timeout | 业务最长耗时的 1.2 倍以上 |
| 应用服务 | Gunicorn timeout、request_terminate_timeout | 小于等于代理超时 |
| 脚本运行时 | max_execution_time | 小于应用服务超时 |
| 单次下游调用 | 数据库/HTTP 客户端 timeout | 显著小于脚本超时 |
服务器脚本超时时间设置多少合适?按任务类型分档
“多少合适”这个问题的答案是分场景的,下面这几档是实践中比较稳的参考区间。
同步 Web 请求:别超过用户忍耐线
用户等待一个页面的耐心通常只有十几秒,一个同步接口跑30秒才返回,即使不报错,体验也已经崩了,这类脚本常见做法是:
- 普通查询、表单提交:10 到 30 秒
- 涉及第三方接口的聚合页:30 到 60 秒
- 报表生成、大文件导出:不要同步做,改成异步任务加轮询
关键动作是把长任务搬走,而不是把超时调大。
批处理与定时任务:按耗时分布定,不按感觉定
行业共识认为,定时脚本的超时应该由数据说话,实操路径:
- 在脚本里记录开始时间和结束时间,日志里保留耗时字段
- 跑一到两周,统计 P95 耗时(大部分任务的实际上限)
- 超时值取 P95 的 1.5 到 2 倍,再和上游调度平台的超时对齐
比如一个每天凌晨跑的统计脚本,最近一周最慢28分钟,那超时设在45到60分钟是合理的,设成10分钟只会天天失败,设成24小时等于没设。
外部 API 调用:单次必须短,重试要有上限
调第三方接口时,timeout 参数建议显式写成 3 到 10 秒,并区分连接超时和读取超时,很多语言默认不设超时或设得极长,下游卡住时脚本就一起挂住。
Linux服务器脚本超时时间配置方法:三种常见入口
用 timeout 命令包一层
最省事的做法,适合 cron 里跑的 Shell 脚本和单条命令:
timeout -k 10 300 /opt/scripts/sync.sh
意思是跑满300秒先发 TERM,再等10秒发 KILL,注意被强杀的脚本可能留下半截文件或未提交的事务,所以脚本里要处理信号,或者把中途状态写进临时目录再原子替换。
systemd 服务与定时器
用 systemd 托管时,在 unit 文件里加:
[Service]
TimeoutStartSec=300
TimeoutStopSec=30
定时器场景用 Type=oneshot,配 TimeoutStartSec 控制单次执行上限。
php-fpm 的 FPM 层兜底
request_terminate_timeout 是 FPM 层面的硬上限,优先级高于 max_execution_time,它适合防住那些 set_time_limit(0) 的失控代码,但设置过小会把正常的慢接口杀掉,一般略大于业务最长耗时即可。
PHP脚本执行超时时间怎么调:别忽略CLI和FPM的差异
这是被问得最多的具体场景。
Web 模式下生效,CLI 模式下常常不生效
max_execution_time 的默认值在 php.ini 里是30秒,但它在 CLI 模式下默认被设为0(不限),所以很多人在命令行跑脚本时发现设了值也没用,原因就在这里,要在 CLI 里限制,用:
php -d max_execution_time=600 script.php
或者直接在脚本里 set_time_limit(600),注意这个函数只能延长,不能缩短,且在 safe_mode 等受限环境里可能被禁用。
时间算的是CPU时间,不完全是墙钟时间
在部分运行模式下,max_execution_time 统计的是脚本自身消耗的时间,不包含 sleep()、数据库查询等待、外部网络等待,也就是说,一个卡在等数据库的脚本可能超过30秒也不会被这个参数杀掉。真正兜底要靠 FPM 的 request_terminate_timeout 或上游网关。
一组常见写法
- Web 普通页面:
max_execution_time = 30,FPM 层 60 - 后台接口:
max_execution_time = 120,FPM 层 180 - 导入导出:改队列任务,CLI 下显式设 600 到 1800
- Nginx 配合:
fastcgi_read_timeout要比 FPM 的request_terminate_timeout稍大
云服务器脚本超时时间设置会影响费用吗?会
近几年 Serverless 和函数计算普及之后,超时配置多了一层成本含义。
主流云函数平台的单次执行时长都有硬上限,不同厂商和运行环境在十几分钟这个量级,具体数值以各厂商公开文档为准,在这个上限内,计费通常按实际执行时长乘以配置的内存规格计算,超时设置本身不直接收费,但它决定了“失败前烧掉多少钱”。
场景很直观:一个函数因为超时设成最大值,在下游接口卡死时反复重跑,每次都要付费,账单就会白白多出一截,所以更合理的做法是:
- 把超时压到合理值,让失败尽早暴露
- 给重试次数设上限,并且用退避策略
- 长任务拆分成多个短函数,用队列串起来
云主机(ECS这类)则不同,超时不直接影响计费,但失控脚本会长期占满CPU和连接数,间接推高扩容成本,这类环境更该给脚本加 timeout,而不是加硬件。
调超时最容易踩的四个坑
- 只改脚本,不改上游:脚本能跑10分钟,网关60秒就断了,用户侧永远看到超时。
- 超时值全站一个数:查询接口和导出任务共用一个配置,要么短的误杀,要么长的掩盖问题。
- 用调大超时掩盖慢查询:真正的病根在缺少索引或全表扫描,超时只是警报器。
- 重试不留间隔:超时加立即重试,等于给下游加压,雪崩往往这么来的。
一个可执行的检查清单:登录服务器,grep -n "max_execution_time" /etc/php.ini 看脚本层,grep -n "request_terminate_timeout" /etc/php-fpm.d/.conf 看FPM层,再翻 Nginx 的 fastcgi_read_timeout 和 proxy_read_timeout,三处对齐,才算真正配完。
服务器脚本超时时间设置常见问题
问:超时时间设得越大越安全吗?
不是,超时是失败兜底,不是性能参数,设得过大,故障发现被推迟,连接池和线程被长时间占用,一个卡住的脚本可能拖垮整个服务,合理值应该贴着业务真实耗时上限,而不是贴着平台最大值。
问:网关超时和脚本超时,哪个该更短?
脚本层更短,让脚本先自己失败并记录日志,比让网关断开连接更好排查,如果反过来,网关先断,脚本还在后台跑,既浪费资源,日志里又看不出完整原因。
问:数据库查询超时要不要单独设?
要,而且要比脚本超时小一个量级,通常单条查询的超时设在几秒到十几秒,配合慢查询日志,把超过阈值的语句单独治理,脚本超时是最后一道防线,不是第一道。