php实现策略重发
PHP实现策略重发的方法
策略重发通常用于处理网络请求失败、API调用异常等情况,通过设定重试机制提高请求成功率。以下是几种常见的实现方式:
基础重试策略
使用简单的循环实现固定次数的重试:

function retryRequest($url, $maxAttempts = 3) {
$attempt = 0;
while ($attempt < $maxAttempts) {
try {
$response = file_get_contents($url);
if ($response !== false) {
return $response;
}
} catch (Exception $e) {
error_log("Attempt " . ($attempt + 1) . " failed: " . $e->getMessage());
}
$attempt++;
sleep(1); // 简单的延迟
}
throw new Exception("All attempts failed");
}
指数退避策略
更高级的实现采用指数退避算法,随着重试次数增加等待时间:

function retryWithBackoff($callable, $maxRetries = 5) {
$retryCount = 0;
$delay = 100; // 初始延迟100毫秒
while ($retryCount < $maxRetries) {
try {
return $callable();
} catch (Exception $e) {
$retryCount++;
if ($retryCount >= $maxRetries) {
throw $e;
}
usleep($delay * 1000);
$delay = min($delay * 2, 5000); // 最大延迟5秒
}
}
}
使用Guzzle的重试中间件
对于HTTP请求,Guzzle库提供了内置的重试中间件:
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
$stack = HandlerStack::create();
$stack->push(Middleware::retry(function(
$retries,
$request,
$response = null,
$exception = null
) {
return $retries < 3 && ($exception instanceof ConnectException || ($response && $response->getStatusCode() >= 500));
}));
$client = new Client(['handler' => $stack]);
$response = $client->get('https://api.example.com');
数据库操作重试
针对数据库连接问题,可以实现特定重试逻辑:
function retryDbQuery($query, $params = [], $maxRetries = 3) {
$pdo = null;
$retry = 0;
while ($retry < $maxRetries) {
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll();
} catch (PDOException $e) {
$retry++;
if ($retry >= $maxRetries) {
throw $e;
}
sleep(pow(2, $retry)); // 指数退避
}
}
}
注意事项
- 重试次数不宜过多,避免造成系统负担
- 对于非幂等操作要谨慎使用重试
- 考虑添加随机抖动(jitter)避免多个客户端同时重试
- 记录失败日志以便分析问题原因
以上方法可以根据具体业务需求组合使用,形成适合项目特点的重发策略。


