Laravel任务监控用Prometheus吗

wen PHP项目 16

本文目录导读:

Laravel任务监控用Prometheus吗

  1. 为什么选择 Prometheus
  2. 常见监控指标
  3. 实现方案
  4. 队列长度监控(关键)
  5. 与 Laravel Horizon 结合
  6. Grafana 面板配置示例
  7. 部署建议
  8. 替代方案

是的,Laravel 项目可以使用 Prometheus 进行任务监控,这是一种非常流行且强大的组合,以下是一些实现方案和核心思路:

为什么选择 Prometheus

  • 成熟的指标系统:天然适合监控任务队列(Queue)、调度任务(Schedule)等
  • 强大的查询语言:PromQL 可以灵活聚合和分析任务指标
  • 丰富的可视化:与 Grafana 搭配可以构建专业监控面板

常见监控指标

队列任务(Queue)

# 任务处理数量(计数)
laravel_jobs_processed_total{queue="default",job="SendEmail"} 1234
# 当前队列长度(Gauge)
laravel_queue_size{queue="high"} 5
# 处理时间直方图
laravel_job_duration_seconds_bucket{le="0.1",queue="default"} 100
laravel_job_duration_seconds_sum{queue="default"} 45.2
laravel_job_duration_seconds_count{queue="default"} 500

调度任务(Schedule)

# 调度执行时间
laravel_schedule_duration_seconds{task="app:report"} 12.3
# 调度成功/失败计数
laravel_schedule_results_total{task="app:cleanup",status="success"} 10

实现方案

使用扩展包(推荐)

spatie/laravel-prometheus

composer require spatie/laravel-prometheus

配置示例

// config/prometheus.php
return [
    'default_metrics' => [
        'queue_size' => [
            'type' => 'gauge',
            'name' => 'laravel_queue_size',
            'help' => 'Current queue size',
            'labels' => ['queue'],
        ],
        'job_duration' => [
            'type' => 'histogram',
            'name' => 'laravel_job_duration_seconds',
            'help' => 'Job processing duration',
            'buckets' => [0.1, 0.5, 1, 2, 5],
        ],
    ],
];

收集中间件

// app/Http/Middleware/PrometheusMiddleware.php
class PrometheusMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        // 暴露 /metrics 端点
        if ($request->path() === 'metrics') {
            return response(app('prometheus')->render());
        }
        return $response;
    }
}

手动实现

创建 Prometheus 服务类

namespace App\Services;
use Prometheus\CollectorRegistry;
use Prometheus\Storage\Redis;
class MetricsService
{
    private CollectorRegistry $registry;
    public function __construct()
    {
        $adapter = new Redis(['host' => env('REDIS_HOST')]);
        $this->registry = new CollectorRegistry($adapter);
    }
    public function trackJob(string $queue, string $job, float $duration): void
    {
        // 任务处理计数
        $counter = $this->registry->getOrRegisterCounter(
            'laravel',
            'jobs_processed_total',
            'Total processed jobs',
            ['queue', 'job']
        );
        $counter->incBy(1, [$queue, $job]);
        // 处理时间
        $histogram = $this->registry->getOrRegisterHistogram(
            'laravel',
            'job_duration_seconds',
            'Job duration in seconds',
            ['queue', 'job'],
            [0.1, 0.5, 1, 2, 5, 10]
        );
        $histogram->observe($duration, [$queue, $job]);
    }
}

集成到队列系统

自定义 Job 基类

namespace App\Jobs;
use App\Services\MetricsService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
abstract class MonitoredJob implements ShouldQueue
{
    use Queueable;
    protected MetricsService $metrics;
    public function __construct()
    {
        $this->metrics = app(MetricsService::class);
    }
    public function handleWithMonitoring($callback): void
    {
        $start = microtime(true);
        try {
            $callback();
            $success = true;
        } catch (\Exception $e) {
            $success = false;
            throw $e;
        } finally {
            $duration = microtime(true) - $start;
            $this->metrics->trackJob($this->queue, static::class, $duration);
            $this->metrics->trackResult($this->queue, static::class, $success);
        }
    }
}

队列长度监控(关键)

使用 Redis 或数据库查询队列大小:

// 在调度任务中定期收集
$schedule->call(function () {
    $metrics = app(MetricsService::class);
    foreach (['default', 'high', 'low'] as $queue) {
        $size = Queue::size($queue);
        $metrics->setQueueSize($queue, $size);
    }
})->everyMinute();

与 Laravel Horizon 结合

如果使用 Horizon,可以直接监控 Horizon 提供的指标:

// app/Providers/HorizonServiceProvider.php
public function boot(): void
{
    parent::boot();
    Horizon::routeMetrics('/horizon/metrics');
    // 自定义 Prometheus 适配器
    Horizon::registerMetrics([
        new QueueSizeMetric(),
        new JobThroughputMetric(),
    ]);
}

Grafana 面板配置示例

# grafana/dashboards/laravel-jobs.json
panels: '作业处理速率'
    targets:
      - expr: 'rate(laravel_jobs_processed_total[5m])'
        legendFormat: '{{queue}} - {{job}}'
    type: graph
     '队列长度'
    targets:
      - expr: 'laravel_queue_size'
        legendFormat: '{{queue}}'
    type: singlestat

部署建议

  1. 使用 Redis 作为存储后端:保证多进程/多 Worker 的数据一致性
  2. 设置合理的 Histogram Buckets:根据业务延迟范围配置
  3. 避免指标基数爆炸:控制标签(labels)的维度
  4. 配置独立 /metrics 端点:使用 Nginx 限制访问

替代方案

  • Laravel Telescope:内置的任务监控,但仅适合开发和调试
  • Laravel Pulse:Laravel 11 的新监控工具,更轻量
  • ClickHouse + Vector:适合大规模日志分析场景

对于生产环境,Prometheus + Grafana 是最稳定且灵活的方案,特别适合微服务和容器化部署,如果只关注队列监控,也可以考虑用 Horizon 的仪表盘 + 基础的健康检查。

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