本文目录导读:

在PHP项目中处理接口超时,需要从客户端发起请求和服务端处理请求两个层面分别设置,以下是详细的配置和处理方案:
客户端请求超时设置(发起HTTP请求时)
cURL 方式
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://api.example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 总超时时间10秒
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 连接超时5秒
// 高级设置:传输速度限制
curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 1024); // 1024字节/秒
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 10); // 持续10秒低于限速则超时
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
// 处理超时错误
if (curl_errno($ch) == CURLE_OPERATION_TIMEDOUT) {
echo "请求超时";
}
}
curl_close($ch);
Guzzle HTTP 客户端
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
$client = new Client([
'timeout' => 10, // 总超时
'connect_timeout' => 5, // 连接超时
'read_timeout' => 8, // 读取超时
]);
try {
$response = $client->get('http://api.example.com', [
'timeout' => 10,
'connect_timeout' => 5
]);
} catch (RequestException $e) {
if ($e->hasResponse()) {
$statusCode = $e->getResponse()->getStatusCode();
}
// 处理超时
if ($e instanceof ConnectException) {
echo "连接超时";
}
if ($e->getCode() == CURLE_OPERATION_TIMEDOUT) {
echo "请求超时";
}
}
file_get_contents 方式
<?php
$ctx = stream_context_create([
'http' => [
'timeout' => 10, // 超时时间(秒)
'method' => 'GET'
]
]);
$result = @file_get_contents('http://api.example.com', false, $ctx);
if ($result === false) {
echo "请求失败或超时";
}
服务端处理超时设置(PHP脚本执行)
set_time_limit() 函数
<?php // 设置脚本最大执行时间 set_time_limit(30); // 30秒 // 设置为0表示无限制(不推荐生产环境) // set_time_limit(0); // 处理耗时操作 processLongTask();
max_execution_time 配置(php.ini)
; 修改 php.ini 文件 max_execution_time = 30 ; 或者针对特定虚拟机 max_input_time = 60
使用 pcntl 实现更精确的控制
<?php
declare(ticks = 1);
// 超时回调函数
function timeout_handler($signo) {
throw new Exception('脚本执行超时');
}
// 设置超时信号
pcntl_signal(SIGALRM, 'timeout_handler');
pcntl_alarm(10); // 10秒后触发
try {
// 执行可能超时的操作
while (true) {
// 处理数据
}
} catch (Exception $e) {
echo "脚本执行超时: " . $e->getMessage();
} finally {
pcntl_alarm(0); // 取消闹钟
}
数据库查询超时设置
<?php
// MySQL 示例
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_TIMEOUT, 5); // 设置连接超时
// 执行超时查询
$stmt = $pdo->prepare('SELECT SLEEP(20)');
// MySQL 查询超时
$pdo->exec("SET SESSION MAX_EXECUTION_TIME = 1000"); // 1秒(MySQL 5.7+)
$stmt->execute();
} catch (PDOException $e) {
echo "数据库操作超时: " . $e->getMessage();
}
综合处理方案(推荐)
使用重试机制
<?php
function requestWithRetry($url, $maxRetries = 3, $timeout = 10) {
$retries = 0;
$success = false;
$result = null;
while (!$success && $retries < $maxRetries) {
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if (curl_errno($ch) == CURLE_OPERATION_TIMEDOUT) {
$retries++;
// 指数退避策略
$waitTime = pow(2, $retries);
sleep($waitTime);
continue;
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 200 && $httpCode < 300) {
$success = true;
}
curl_close($ch);
} catch (Exception $e) {
$retries++;
if ($retries >= $maxRetries) {
throw $e;
}
}
}
return $result;
}
使用消息队列处理
<?php
// 使用 Redis 或 RabbitMQ 实现异步处理
// 接口立即返回,后台异步处理
public function handleAsyncRequest() {
$jobData = ['type' => 'process', 'data' => $input];
// 推送到消息队列
Redis::lpush('queue:processing', json_encode($jobData));
return ['status' => 'accepted', 'message' => '请求已接收'];
}
最佳实践建议
-
分层设置超时:
- 客户端超时 < 服务端超时 < 负载均衡器超时
- 客户端10秒 < PHP 30秒 < Nginx 60秒
-
使用监控和报警:
// 记录超时日志 function logTimeout($service, $timeout) { $log = [ 'time' => date('Y-m-d H:i:s'), 'service' => $service, 'timeout' => $timeout, 'url' => $_SERVER['REQUEST_URI'] ?? '' ]; file_put_contents('/var/log/timeout.log', json_encode($log) . PHP_EOL, FILE_APPEND); } -
超时阈值设置建议:
- 普通API:5-10秒
- 文件上传:30-60秒
- 批量处理:根据数据量动态设置
- 长连接/推送:使用 WebSocket 或 SSE
-
性能优化:
// 使用异步非阻塞方式 // Swoole 或 ReactPHP 实现协程处理 go(function () { $result = Co::exec("curl -s http://api.example.com", 5); });
选择合适的超时处理方案需要根据具体的业务场景、系统架构和性能要求来决定,对于关键业务,建议同时使用多种策略组合(超时+重试+降级)。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播