本文目录导读:

在 PHP 中实现主动拨测(即主动发起 HTTP 请求测试目标服务是否可用、响应时间等),通常有以下几种常用方案,以下是具体的实现方式及示例代码:
使用 cURL 进行单次拨测(最常见)
<?php
function singleProbe($url, $timeout = 5) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_CONNECTTIMEOUT => $timeout,
CURLOPT_HEADER => false,
CURLOPT_NOBODY => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 3,
]);
$startTime = microtime(true);
$response = curl_exec($ch);
$endTime = microtime(true);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$totalTime = round(($endTime - $startTime) * 1000, 2); // 毫秒
curl_close($ch);
return [
'url' => $url,
'http_code' => $httpCode,
'response_time_ms' => $totalTime,
'success' => ($httpCode >= 200 && $httpCode < 400),
'error' => curl_error($ch) ?: null,
];
}
// 使用示例
$result = singleProbe('https://example.com/api/health');
print_r($result);
多目标并行拨测(提高效率)
<?php
function multiProbe(array $urls, $timeout = 5) {
$mh = curl_multi_init();
$curlHandles = [];
// 创建所有 cURL 句柄
foreach ($urls as $key => $url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_CONNECTTIMEOUT => $timeout,
CURLOPT_HEADER => false,
CURLOPT_NOBODY => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 3,
]);
curl_multi_add_handle($mh, $ch);
$curlHandles[$key] = $ch;
}
// 执行并行请求
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
// 收集结果
$results = [];
foreach ($curlHandles as $key => $ch) {
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$totalTime = curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000;
$results[$key] = [
'url' => $urls[$key],
'http_code' => $httpCode,
'response_time_ms' => round($totalTime, 2),
'success' => ($httpCode >= 200 && $httpCode < 400),
'error' => curl_error($ch) ?: null,
];
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
return $results;
}
// 使用示例
$urls = [
'site1' => 'https://example1.com',
'site2' => 'https://example2.com',
'api' => 'https://api.example.com/health',
];
$results = multiProbe($urls);
print_r($results);
带监控的拨测脚本(可定时执行)
<?php
// probe_monitor.php - 配合 cron 定时执行
require_once 'probe_functions.php';
$targets = [
['url' => 'https://service1.example.com', 'name' => '主服务'],
['url' => 'https://service2.example.com/api/ping', 'name' => 'API服务'],
['url' => 'https://db-admin.example.com', 'name' => '数据库管理'],
];
$results = [];
foreach ($targets as $target) {
$probeResult = singleProbe($target['url']);
$results[] = array_merge(['name' => $target['name']], $probeResult);
}
// 处理结果
$failed = array_filter($results, function($r) { return !$r['success']; });
if (!empty($failed)) {
// 发送告警(邮件/短信/钉钉等)
sendAlert($failed);
}
// 记录日志
file_put_contents('/var/log/probe.log',
date('Y-m-d H:i:s') . " " . json_encode($results) . "\n",
FILE_APPEND);
// 可选:推送到监控系统
// pushToPrometheus($results);
高级功能实现
1 添加 DNS 解析检测
function probeWithDns($url) {
$host = parse_url($url, PHP_URL_HOST);
$startTime = microtime(true);
$ip = gethostbyname($host);
$dnsTime = microtime(true) - $startTime;
$probeResult = singleProbe($url);
$probeResult['dns_resolve_time_ms'] = round($dnsTime * 1000, 2);
$probeResult['resolved_ip'] = $ip;
return $probeResult;
}
2 SSL 证书检测
function probeWithSslCheck($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_CERTINFO => true,
]);
curl_exec($ch);
$certInfo = curl_getinfo($ch, CURLINFO_CERTINFO);
$result = [
'url' => $url,
'ssl_valid' => false,
'ssl_expiry' => null,
];
if (!empty($certInfo[0])) {
$cert = $certInfo[0];
$expiryDate = date('Y-m-d', strtotime($cert['Expire date']));
$result['ssl_valid'] = (strtotime($cert['Expire date']) > time());
$result['ssl_expiry'] = $cert['Expire date'];
$result['ssl_issuer'] = $cert['Issuer'];
}
curl_close($ch);
return $result;
}
配合 Cron 定时执行
在 Linux 中添加定时任务:
# 每5分钟执行一次拨测 */5 * * * * /usr/bin/php /path/to/probe_monitor.php >> /var/log/probe_cron.log 2>&1
注意事项
- 超时设置:根据实际场景合理设置超时时间,避免阻塞
- 并发控制:批量拨测时使用 curl_multi 提高效率
- 错误处理:捕获网络异常、超时、DNS 解析失败等
- 日志记录:保存每次拨测结果用于分析和告警
- 资源限制:避免频繁拨测导致目标服务压力过大
推荐使用封装好的库,如 PHP HTTP Client 或 Guzzle,它们提供了更简洁的 API 和更好的异常处理。