PHP 怎么PHP 主动拨测

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 主动拨测

  1. 使用 cURL 进行单次拨测(最常见)
  2. 多目标并行拨测(提高效率)
  3. 带监控的拨测脚本(可定时执行)
  4. 高级功能实现
  5. 配合 Cron 定时执行
  6. 注意事项

在 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

注意事项

  1. 超时设置:根据实际场景合理设置超时时间,避免阻塞
  2. 并发控制:批量拨测时使用 curl_multi 提高效率
  3. 错误处理:捕获网络异常、超时、DNS 解析失败等
  4. 日志记录:保存每次拨测结果用于分析和告警
  5. 资源限制:避免频繁拨测导致目标服务压力过大

推荐使用封装好的库,如 PHP HTTP Client 或 Guzzle,它们提供了更简洁的 API 和更好的异常处理。

抱歉,评论功能暂时关闭!