添加whatshub工单

This commit is contained in:
root
2026-06-20 04:47:34 +08:00
parent a6c87e8e25
commit d5a0ffa6db
271 changed files with 9377 additions and 303 deletions
@@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
namespace app\common\service;
/**
* Node Puppeteer 服务健康与队列负载探测
*/
class SplitNodeHealthService
{
/**
* 拉取 /api/stats,失败返回 null(不阻断同步,由后续请求快速失败)
*
* @return array<string, mixed>|null
*/
public static function fetchStats(): ?array
{
$url = SplitSyncConfigService::getNodeHost() . '/api/stats';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
$response = curl_exec($ch);
if (curl_errno($ch)) {
curl_close($ch);
return null;
}
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
return null;
}
$decoded = json_decode((string) $response, true);
return is_array($decoded) ? $decoded : null;
}
/**
* 当前是否适合向 Node 提交新 Browser 任务
*/
public static function canAcceptWork(): bool
{
$stats = self::fetchStats();
if ($stats === null) {
return true;
}
if (!empty($stats['shuttingDown'])) {
return false;
}
$queue = is_array($stats['queue'] ?? null) ? $stats['queue'] : [];
$config = is_array($stats['config'] ?? null) ? $stats['config'] : [];
$queued = (int) ($queue['queued'] ?? 0);
$active = (int) ($queue['active'] ?? 0);
$max = max(1, (int) ($config['maxConcurrentBrowsers'] ?? ($queue['max'] ?? 4)));
$threshold = SplitSyncConfigService::getNodeQueueSkipThreshold();
if ($queued >= $threshold) {
return false;
}
return $active < $max;
}
/**
* @return array{queued:int,active:int,max:int}
*/
public static function getQueueSnapshot(): array
{
$stats = self::fetchStats();
if ($stats === null) {
return ['queued' => 0, 'active' => 0, 'max' => 0];
}
$queue = is_array($stats['queue'] ?? null) ? $stats['queue'] : [];
$config = is_array($stats['config'] ?? null) ? $stats['config'] : [];
return [
'queued' => (int) ($queue['queued'] ?? 0),
'active' => (int) ($queue['active'] ?? 0),
'max' => max(1, (int) ($config['maxConcurrentBrowsers'] ?? ($queue['max'] ?? 4))),
];
}
/**
* Node 侧 Real Browser / Captcha 是否就绪(供同步失败日志可读性)
*
* @return array{realBrowserReady:bool,captchaConfigured:bool}
*/
public static function getAntiBotSnapshot(): array
{
$stats = self::fetchStats();
if ($stats === null) {
return ['realBrowserReady' => false, 'captchaConfigured' => false];
}
return [
'realBrowserReady' => !empty($stats['realBrowserReady']),
'captchaConfigured' => !empty($stats['captchaConfigured']),
];
}
}