修复:隔离上游数据库连接探测
This commit is contained in:
parent
204a7f373a
commit
a364d857b4
@ -6,6 +6,8 @@ use Illuminate\Support\Facades\Log;
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
||||
use Symfony\Component\Process\PhpExecutableFinder;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
/**
|
||||
* 按来源隔离的 SQL Server PDO_ODBC 连接管理。
|
||||
@ -41,6 +43,67 @@ class UpstreamOdbcConnection
|
||||
}
|
||||
|
||||
public static function probeConfiguration(array $connection, string $label, string $source = 'custom'): void
|
||||
{
|
||||
try {
|
||||
$payload = json_encode([
|
||||
'connection' => $connection,
|
||||
'label' => $label,
|
||||
'source' => $source,
|
||||
], JSON_THROW_ON_ERROR);
|
||||
$php = (new PhpExecutableFinder())->find(false);
|
||||
|
||||
if (! is_string($php) || $php === '') {
|
||||
throw new \RuntimeException('PHP CLI 不可用。');
|
||||
}
|
||||
|
||||
$script = <<<'PHP'
|
||||
require getcwd() . '/vendor/autoload.php';
|
||||
$app = require getcwd() . '/bootstrap/app.php';
|
||||
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||
$kernel->bootstrap();
|
||||
$payload = json_decode(stream_get_contents(STDIN), true, 512, JSON_THROW_ON_ERROR);
|
||||
Modules\EcommerceFinance\Services\UpstreamOdbcConnection::probeConfigurationInProcess(
|
||||
(array) $payload['connection'],
|
||||
(string) $payload['label'],
|
||||
(string) $payload['source'],
|
||||
);
|
||||
PHP;
|
||||
$connectTimeout = min(max((int) ($connection['connect_timeout'] ?? 5), 1), 30);
|
||||
$process = new Process(
|
||||
[$php, '-d', 'display_errors=0', '-r', $script],
|
||||
base_path(),
|
||||
null,
|
||||
$payload,
|
||||
min(max($connectTimeout + 3, 5), 15),
|
||||
);
|
||||
$process->run();
|
||||
|
||||
if ($process->isSuccessful()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::warning('上游数据库隔离探测失败。', [
|
||||
'source' => $source,
|
||||
'source_label' => $label,
|
||||
'exit_code' => $process->getExitCode(),
|
||||
]);
|
||||
} catch (\Throwable $exception) {
|
||||
Log::warning('上游数据库隔离探测无法完成。', [
|
||||
'source' => $source,
|
||||
'source_label' => $label,
|
||||
'exception' => $exception::class,
|
||||
]);
|
||||
}
|
||||
|
||||
throw new ServiceUnavailableHttpException(60, '上游数据库连接探测失败,请检查配置。');
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅由隔离的 PHP CLI 子进程调用,避免 ODBC 原生崩溃拖垮 Web 请求进程。
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function probeConfigurationInProcess(array $connection, string $label, string $source = 'custom'): void
|
||||
{
|
||||
$pdo = self::open($connection, $source, $label);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user