PHP 怎么PHP 就绪检查

wen PHP项目 3

本文目录导读:

PHP 怎么PHP 就绪检查

  1. 基础就绪检查 endpoint
  2. 在 Laravel 中实现
  3. 在 Symfony 中实现
  4. 使用框架内置的健康检查
  5. 进阶:自定义健康检查类
  6. 容器环境中的就绪检查
  7. 最佳实践

在 PHP 中,“就绪检查”(Health Check / Readiness Check)通常用于判断应用是否已完全初始化(如数据库连接、缓存、配置加载等),并能正常处理请求,这在容器化部署、负载均衡、Kubernetes 等场景中非常重要。

以下是几种常见的 PHP 就绪检查实现方式:

基础就绪检查 endpoint

创建一个简单的路由或文件,检查核心依赖是否可用。

<?php
// health.php 或 readiness.php
$checks = [
    'database' => false,
    'cache'    => false,
    'config'   => false,
];
try {
    // 检查数据库连接
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    $checks['database'] = true;
} catch (PDOException $e) {
    $checks['database'] = false;
}
try {
    // 检查 Redis 缓存
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    $checks['cache'] = true;
} catch (Exception $e) {
    $checks['cache'] = false;
}
// 检查配置文件是否加载
$checks['config'] = defined('APP_ENV') && file_exists(__DIR__ . '/config.php');
// 设定响应头
header('Content-Type: application/json');
http_response_code(200);
$allReady = !in_array(false, $checks, true);
if (!$allReady) {
    http_response_code(503); // Service Unavailable
}
echo json_encode([
    'status'  => $allReady ? 'ready' : 'not ready',
    'checks'  => $checks,
    'time'    => time()
]);

在 Laravel 中实现

Laravel 提供了更优雅的方式,可以注册健康检查路由:

// routes/web.php 或 routes/api.php
Route::get('/health', function () {
    $health = new \App\Services\HealthCheckService();
    try {
        // 检查数据库
        \DB::connection()->getPdo();
        // 检查缓存
        \Cache::store('redis')->get('health_check_key');
        return response()->json([
            'status' => 'healthy',
            'database' => true,
            'cache' => true,
            'timestamp' => now()->toIso8601String()
        ]);
    } catch (\Exception $e) {
        return response()->json([
            'status' => 'unhealthy',
            'error' => $e->getMessage(),
            'timestamp' => now()->toIso8601String()
        ], 503);
    }
});

在 Symfony 中实现

Symfony 有专门的 Health Check 组件:

// src/Controller/HealthController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\DBAL\Connection;
class HealthController extends AbstractController
{
    #[Route('/health', name: 'health_check')]
    public function healthCheck(Connection $connection): JsonResponse
    {
        try {
            $connection->executeQuery('SELECT 1');
            return $this->json([
                'status' => 'healthy',
                'database' => true
            ]);
        } catch (\Exception $e) {
            return $this->json([
                'status' => 'unhealthy',
                'database' => false,
                'error' => $e->getMessage()
            ], 503);
        }
    }
}

使用框架内置的健康检查

许多现代 PHP 框架已经有内置的健康检查功能:

Laravel Horizon (队列监控)

php artisan horizon:status

Lumen/Laravel 的路由服务监控

// Kernel.php 中添加中间件
protected $middlewareGroups = [
    'api' => [
        \App\Http\Middleware\HealthCheck::class,
        // ...
    ],
];

进阶:自定义健康检查类

创建一个可复用的健康检查服务:

<?php
class HealthCheckService
{
    private array $checks = [];
    private array $results = [];
    public function addCheck(string $name, callable $check): self
    {
        $this->checks[$name] = $check;
        return $this;
    }
    public function run(): array
    {
        foreach ($this->checks as $name => $check) {
            try {
                $result = $check();
                $this->results[$name] = [
                    'status' => $result ? 'pass' : 'fail',
                    'message' => $result ? 'OK' : 'Check failed'
                ];
            } catch (\Exception $e) {
                $this->results[$name] = [
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }
        return $this->results;
    }
    public function isReady(): bool
    {
        foreach ($this->results as $result) {
            if ($result['status'] !== 'pass') {
                return false;
            }
        }
        return true;
    }
}
// 使用示例
$health = new HealthCheckService();
$health->addCheck('database', function() {
    // 检查数据库
    return true;
});
$health->addCheck('queue', function() {
    // 检查队列连接
    return true;
});
$results = $health->run();
if ($health->isReady()) {
    http_response_code(200);
    echo json_encode(['status' => 'ready', 'checks' => $results]);
} else {
    http_response_code(503);
    echo json_encode(['status' => 'not ready', 'checks' => $results]);
}

容器环境中的就绪检查

在 Docker / Kubernetes 中,可以配置就绪探针:

# Docker Compose
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost/health"]
  interval: 30s
  timeout: 10s
  retries: 3
# Kubernetes Deployment
readinessProbe:
  httpGet:
    path: /health
    port: 80
  initialDelaySeconds: 5
  periodSeconds: 10

最佳实践

  1. 不检查不必要的服务:只检查当前请求需要的关键服务
  2. 快速响应:健康检查应该快速完成,避免长时间等待
  3. 添加缓存:检查结果可以短暂缓存,避免频繁检查影响性能
  4. 区分就绪和存活
    • 就绪检查:应用是否准备好接收流量
    • 存活检查:应用是否活着(可能死锁了)
  5. 日志记录:记录健康检查失败的原因,便于排查

PHP 的就绪检查核心是验证:

  • 数据库连接是否正常
  • 缓存服务是否可用
  • 配置文件是否加载
  • 关键依赖是否存在

你可以根据项目规模选择简单实现或使用框架特性,对于生产环境,建议结合容器编排工具的探针机制,实现自动化的健康管理和流量切换。

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