Laravel健康检查怎么做

wen PHP项目 3

Laravel健康检查最佳实践:从零搭建高可用监控系统

📖 目录导读

  1. 什么是Laravel健康检查?为什么需要它?
  2. 主流方案对比:spatie/laravel-health vs Laravel内置方案
  3. 实战部署:从安装到自定义检查器
  4. 关键指标监控:数据库、缓存、队列、磁盘
  5. 可视化与告警集成:让健康检查“看得见、传得出”
  6. 常见问题与排坑指南(含问答)
  7. 安全加固与生产环境注意事项

什么是Laravel健康检查?为什么需要它?

Laravel健康检查(Health Check) 是一套系统自检机制,通过定期执行一系列检查项(如数据库连通性、缓存服务状态、磁盘空间、队列工作者存活等),来评估应用当前是否正常运行。

Laravel健康检查怎么做

为什么需要它?

  • 提前发现故障:在用户报错前,自动检测到Redis宕机、MySQL连接池耗尽等隐患
  • 辅助自动化运维:Kubernetes的Readiness Probe、AWS的ELB健康检查都需要HTTP端点响应
  • 满足SLA监控:生产环境中必须对外暴露/health接口,供负载均衡器或监控系统(如Prometheus、Datadog)调用

问答:健康检查跟日志监控有什么区别? A:日志监控是事后追溯,发现错误时问题已发生;健康检查是实时探测,在服务完全崩溃前发出预警,两者互补,不可替代。


主流方案对比:spatie/laravel-health vs Laravel内置方案

方案A:spatie/laravel-health(推荐)

特性 说明
安装方式 composer require spatie/laravel-health
检查项 内置数据库、Redis、队列、SSL证书、磁盘、Memcached等20+检查器
扩展性 可自定义检查器,支持异步检查(避免阻塞)
可视化 自带美观的仪表盘(辐射图/柱状图)
结果格式 JSON(供API) + 仪表盘视图(供人类)

方案B:Laravel内置路由+手动检查

Route::get('/health', function () {
    try {
        DB::connection()->getPdo(); // 数据库检查
        return response()->json(['status' => 'ok']);
    } catch (\Exception $e) {
        return response()->json(['status' => 'fail'], 500);
    }
});

缺点:代码零散、无标准化、无缓存/队列检查、无聚合数据。

生产环境建议使用spatie/laravel-health,它已是Laravel生态中最成熟、最广泛使用的健康检查包(GitHub 2.5k+ Star)。


实战部署:从安装到自定义检查器

步骤1:安装与发布配置文件

composer require spatie/laravel-health
php artisan vendor:publish --provider="Spatie\Health\HealthServiceProvider" --tag="health-config"
php artisan vendor:publish --provider="Spatie\Health\HealthServiceProvider" --tag="health-migrations"
php artisan migrate

步骤2:注册检查项(config/health.php)

return [
    'checks' => [
        \Spatie\Health\Checks\Checks\DatabaseCheck::class,
        \Spatie\Health\Checks\Checks\RedisCheck::class,
        \Spatie\Health\Checks\Checks\CacheCheck::class,
        \Spatie\Health\Checks\Checks\DiskSpaceCheck::class->warningStorage(80)->errorStorage(90),
    ],
    'result_stores' => [
        \Spatie\Health\ResultStores\EloquentHealthResultStore::class,
    ],
];

步骤3:添加路由与仪表盘

// routes/web.php
Route::health('/health');

访问http://your-domain/health即可看到JSON格式的健康报告;
访问/health/dashboard可查看可视化仪表盘。

步骤4:快速验证

curl http://localhost/health
# 返回示例:
# {
#   "status": "ok",
#   "checked_at": "2027-03-25T10:00:00Z",
#   "checks": [
#     {"name": "Database", "status": "ok", "message": "Connection successful"},
#     {"name": "Redis", "status": "ok"},
#     ...
#   ]
# }

问答:如何检查队列工作者(Queue Worker)是否存活? A:使用QueueCheck类,它会检测是否有活跃的队列进程在监听指定队列,配置示例:

\Spatie\Health\Checks\Checks\QueueCheck::new()
    ->onQueue('default')
    ->failWhenQueueIsEmpty(false) // 允许空队列不报错

关键指标监控:数据库、缓存、队列、磁盘

数据库检查

// 默认检查连接是否正常,可自定义超时
DatabaseCheck::new()->connectionName('mysql')->timeout(5)

缓存检查

// 检测缓存驱动(Redis/Memcached/File)能否正常读写
CacheCheck::new()->driver('redis')->expectedTtl(60)

磁盘空间

DiskSpaceCheck::new()
    ->warningWhenPercentageUsedIsAbove(75)  // 磁盘使用>75%触发警告
    ->failWhenPercentageUsedIsAbove(90)     // >90%触发故障

SSL证书有效期

SslCertificateCheck::new()
    ->url('https://your-domain.com')
    ->failWhenCertificateExpiringInDays(14) // 证书14天内过期则告警

邮件发送服务

// 需自定义检查器,检测SMTP连接
class MailCheck extends \Spatie\Health\Checks\Check
{
    public function run(): CheckResult
    {
        try {
            Mail::raw('test', fn($msg) => $msg->to('test@example.com'));
            return CheckResult::ok();
        } catch (\Exception $e) {
            return CheckResult::failed()->comment($e->getMessage());
        }
    }
}

可视化与告警集成:让健康检查“看得见、传得出”

内置仪表盘

访问/health/dashboard,以辐射图、进度条等方式展示所有检查项状态。
支持设置定时自动刷新(每30秒一次)。

集成Slack/钉钉/邮件告警

利用Laravel的通知系统:

// config/health.php
'notifications' => [
    \Spatie\Health\Notifications\CheckFailedNotification::class => [
        'mail' => ['admin@your-company.com'],
        'slack' => [
            'webhook_url' => env('SLACK_HEALTH_WEBHOOK'),
        ],
    ],
],

对接Prometheus

安装扩展包:composer require spatie/laravel-health-prometheus
然后暴露/health/prometheus端点,供Grafana抓取并绘制指标。


常见问题与排坑指南(含问答)

Q1:健康检查频繁超时,影响正常请求怎么办?
A:启用异步检查,将config/health.php中的queue_runner设为true

'queue_runner' => [
    'enabled' => true,
    'queue' => 'default',
    'connection' => 'redis',
],

检查任务会排队异步执行,不阻塞HTTP响应。

Q2:如何排除某些路由?比如健康检查数据不想被外部访问?
A:结合Laravel的中间件或IP白名单:

Route::middleware(['auth.basic', 'throttle:60,1'])->health('/health');

或通过配置config/health.phpmiddleware数组。

Q3:DiskSpaceCheck在Linux容器中报告错误的磁盘使用率?
A:因为容器内df命令看到的往往是宿主机文件系统,解决方案:

  • 使用->filesystem('/app')指定要监控的目录路径
  • 或者自定义检查器调用disk_free_space('/app')函数

Q4:如何检查某个外部API是否可访问?
A:创建自定义检查器:

class ExternalApiCheck extends Check
{
    protected string $url = 'https://third-party.com/api/ping';
    public function run(): CheckResult
    {
        $response = Http::timeout(5)->get($this->url);
        return $response->successful() 
            ? CheckResult::ok() 
            : CheckResult::failed("Status code: " . $response->status());
    }
}

Q5:数据库连接检查正常,但业务SQL报错,怎么发现?
A:健康检查是“浅层检测”,只能验证连接性,深层业务错误需结合应用性能监控(APM),如Sentry、New Relic。


安全加固与生产环境注意事项

  1. 隐藏仪表盘:仅允许内网IP访问/health/dashboard,生产环境可通过php artisan down维护时禁用仪表盘。
  2. 请求频率限制:对健康检查端点添加throttle中间件,防止恶意刷请求。
  3. 敏感信息保护:自定义检查器中避免输出数据库密码、Redis密码等敏感信息。
  4. 多环境适配:本地环境可开启全部检查,生产环境建议只保留核心检查项(数据库、Redis、磁盘)。
  5. 结果持久化:启用EloquentHealthResultStore,将历史检查数据存入数据库,便于趋势分析。

一个生产级的Laravel健康检查应该具备实时性、全面性、可扩展性,通过spatie/laravel-health,你可以在10分钟内完成部署,后续通过自定义检查器覆盖业务特有需求,再结合告警系统形成完整的“发现-通知-响应”闭环,健康检查不是“做完一次就完事”,而是需要持续维护检查项、调整阈值,让它随着业务演进不断优化。

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