我有一个大错误类,它挂接到set_error_handler()
, set_exception_handler()
,甚至 register_shutdown_function()
(运行 error_get_last()
)以捕获每个可能的错误。这非常重要,因为这是一个必须只输出 JSON 的 API,因此错误类会拦截所有 PHP 错误并将它们添加到响应 JSON 中。
但是,由于某种原因,当网关超时时,我仍然收到标准的非 JSON 响应。在本例中,超时是由于 MySQL 响应时间过长(>60 秒)造成的。
错误可能会以某种方式传递回 Nginx,但是我不确定如何确认是否发生了这种情况。
我的问题:如何在 PHP 中捕获网关超时?
我可以确认的是:
- 语法完全正确。
- 如果查询及时执行,API 会正常响应。
- 在运行查询时,PHP fatal error 、异常和其他错误都会在同一个文件中被正确捕获。
环境:
操作系统: Fedora 27
PHP: PHP-FPM 运行 PHP 7.2
网络服务器: Nginx 1.12.1
数据库: MySQL 5.6.27
最佳答案
简短的回答:你不能在 PHP 中做到这一点。
长答案:你不应该用 PHP 来做这件事。这适用于任何后端系统。传递 JSON 的唯一可靠方法是让 Nginx 服务器处理它。如果您的后端出现问题,例如服务器重载、磁盘空间不足或负载过大,您将无法编写任何 PHP 代码来解决此问题。它不会运行。无法运行。
这意味着更改 Nginx 配置以拥有一个基于 JSON 的错误文档,如果您的脚本花费太长时间,可以发出该文档。
您可以使用自定义 error_page
指令来执行此操作。
另一件需要考虑的事情是打开 Nginx 等待 PHP 响应的时间窗口,这样它就不会不耐烦并过早终止您的请求。
根据您分派(dispatch)这些调用的方式,您需要调整 fastcgi_read_timeout
或 proxy_read_timeout
。还有其他类似与尝试将请求转发到 PHP 相关的 proxy_connect_timeout
和 proxy_send_timeout
以及 client_header_timeout
和 client_body_timeout
当客户端本身在完成请求之前停止时发生。
关于php - 在 PHP 中捕获网关超时的困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47873743/