本文目录导读:

我来为您设计一个完整的PHP业务监控指标采集方案,包括核心代码实现和最佳实践。
基础监控类
1 指标采集器基类
<?php
namespace App\Monitor;
/**
* 监控指标采集器基类
*/
abstract class BaseCollector
{
protected array $metrics = [];
protected float $startTime;
protected float $endTime;
public function start(): void
{
$this->startTime = microtime(true);
}
public function end(): void
{
$this->endTime = microtime(true);
}
abstract public function collect(): array;
protected function duration(): float
{
return round(($this->endTime - $this->startTime) * 1000, 2);
}
}
2 请求监控采集器
<?php
namespace App\Monitor\Collectors;
use App\Monitor\BaseCollector;
/**
* HTTP请求监控
*/
class RequestCollector extends BaseCollector
{
private array $requestData;
public function __construct(array $requestData)
{
$this->requestData = $requestData;
$this->start();
}
public function collect(): array
{
$this->end();
return [
'type' => 'request',
'timestamp' => time(),
'duration_ms' => $this->duration(),
'method' => $this->requestData['method'] ?? 'GET',
'path' => $this->requestData['path'] ?? '/',
'status_code' => $this->requestData['status_code'] ?? 200,
'ip' => $this->requestData['ip'] ?? '',
'user_agent' => substr($this->requestData['user_agent'] ?? '', 0, 200),
'memory_usage' => memory_get_usage(true),
'memory_peak' => memory_get_peak_usage(true),
];
}
}
3 数据库查询监控
<?php
namespace App\Monitor\Collectors;
use App\Monitor\BaseCollector;
/**
* 数据库查询监控
*/
class DatabaseCollector extends BaseCollector
{
private array $queryLog = [];
private int $queryCount = 0;
private float $totalTime = 0;
public function addQuery(string $sql, array $bindings, float $time): void
{
$this->queryCount++;
$this->totalTime += $time;
$this->queryLog[] = [
'sql' => $sql,
'bindings' => $bindings,
'time_ms' => $time
];
}
public function collect(): array
{
return [
'type' => 'database',
'timestamp' => time(),
'query_count' => $this->queryCount,
'total_time_ms' => round($this->totalTime, 2),
'avg_time_ms' => $this->queryCount > 0 ? round($this->totalTime / $this->queryCount, 2) : 0,
'slow_queries' => $this->getSlowQueries(),
'queries' => $this->queryLog
];
}
private function getSlowQueries(int $threshold = 100): array
{
return array_filter($this->queryLog, fn($q) => $q['time_ms'] > $threshold);
}
}
4 缓存监控
<?php
namespace App\Monitor\Collectors;
use App\Monitor\BaseCollector;
/**
* 缓存监控
*/
class CacheCollector extends BaseCollector
{
private array $cacheStats = [
'hits' => 0,
'misses' => 0,
'writes' => 0,
'deletes' => 0,
'hit_keys' => [],
'miss_keys' => []
];
public function addHit(string $key): void
{
$this->cacheStats['hits']++;
$this->cacheStats['hit_keys'][] = $key;
}
public function addMiss(string $key): void
{
$this->cacheStats['misses']++;
$this->cacheStats['miss_keys'][] = $key;
}
public function addWrite(string $key): void
{
$this->cacheStats['writes']++;
}
public function addDelete(string $key): void
{
$this->cacheStats['deletes']++;
}
public function collect(): array
{
$total = $this->cacheStats['hits'] + $this->cacheStats['misses'];
return [
'type' => 'cache',
'timestamp' => time(),
'hits' => $this->cacheStats['hits'],
'misses' => $this->cacheStats['misses'],
'hit_rate' => $total > 0 ? round($this->cacheStats['hits'] / $total * 100, 2) : 0,
'writes' => $this->cacheStats['writes'],
'deletes' => $this->cacheStats['deletes'],
'recent_hit_keys' => array_slice($this->cacheStats['hit_keys'], -10),
'recent_miss_keys' => array_slice($this->cacheStats['miss_keys'], -10)
];
}
}
业务指标监控
1 业务指标管理器
<?php
namespace App\Monitor;
/**
* 业务监控中心
*/
class BusinessMonitor
{
private static ?BusinessMonitor $instance = null;
private array $counters = [];
private array $gauges = [];
private array $timers = [];
private array $histograms = [];
private array $events = [];
private function __construct() {}
private function __clone() {}
public static function getInstance(): BusinessMonitor
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 计数器增加
*/
public function increment(string $name, int $value = 1, array $labels = []): void
{
$key = $this->buildKey($name, $labels);
if (!isset($this->counters[$key])) {
$this->counters[$key] = [
'name' => $name,
'labels' => $labels,
'value' => 0
];
}
$this->counters[$key]['value'] += $value;
}
/**
* 设置瞬时值
*/
public function gauge(string $name, $value, array $labels = []): void
{
$key = $this->buildKey($name, $labels);
$this->gauges[$key] = [
'name' => $name,
'labels' => $labels,
'value' => $value,
'updated_at' => time()
];
}
/**
* 计时器记录
*/
public function timing(string $name, float $duration, array $labels = []): void
{
$key = $this->buildKey($name, $labels);
if (!isset($this->timers[$key])) {
$this->timers[$key] = [
'name' => $name,
'labels' => $labels,
'values' => []
];
}
$this->timers[$key]['values'][] = $duration;
// 限制保留最近1000个值
if (count($this->timers[$key]['values']) > 1000) {
array_shift($this->timers[$key]['values']);
}
}
/**
* 直方图记录
*/
public function histogram(string $name, $value, array $labels = []): void
{
$key = $this->buildKey($name, $labels);
if (!isset($this->histograms[$key])) {
$this->histograms[$key] = [
'name' => $name,
'labels' => $labels,
'values' => []
];
}
$this->histograms[$key]['values'][] = $value;
}
/**
* 记录业务事件
*/
public function event(string $name, array $data = []): void
{
$this->events[] = [
'name' => $name,
'data' => $data,
'timestamp' => time()
];
// 保留最近100个事件
if (count($this->events) > 100) {
array_shift($this->events);
}
}
/**
* 获取所有指标
*/
public function getMetrics(): array
{
return [
'counters' => array_values($this->counters),
'gauges' => array_values($this->gauges),
'timers' => array_map([$this, 'processTimers'], $this->timers),
'histograms' => array_map([$this, 'processHistograms'], $this->histograms),
'events' => $this->events
];
}
/**
* 重置所有指标
*/
public function reset(): void
{
$this->counters = [];
$this->gauges = [];
$this->timers = [];
$this->histograms = [];
$this->events = [];
}
private function buildKey(string $name, array $labels): string
{
return $name . ':' . json_encode($labels);
}
private function processTimers(array $timer): array
{
$values = $timer['values'];
$count = count($values);
return [
'name' => $timer['name'],
'labels' => $timer['labels'],
'count' => $count,
'sum' => array_sum($values),
'avg' => $count > 0 ? array_sum($values) / $count : 0,
'min' => $count > 0 ? min($values) : 0,
'max' => $count > 0 ? max($values) : 0,
'p50' => $this->percentile($values, 50),
'p95' => $this->percentile($values, 95),
'p99' => $this->percentile($values, 99)
];
}
private function processHistograms(array $histogram): array
{
$values = $histogram['values'];
$count = count($values);
return [
'name' => $histogram['name'],
'labels' => $histogram['labels'],
'count' => $count,
'sum' => array_sum($values),
'avg' => $count > 0 ? array_sum($values) / $count : 0,
'min' => $count > 0 ? min($values) : 0,
'max' => $count > 0 ? max($values) : 0,
'buckets' => $this->createBuckets($values)
];
}
private function percentile(array $values, int $percentile): float
{
if (empty($values)) return 0;
sort($values);
$index = ceil($percentile / 100 * count($values)) - 1;
return $values[$index];
}
private function createBuckets(array $values): array
{
$buckets = [];
$limits = [
10, 25, 50, 100, 250, 500, 1000, 2500, 5000
];
foreach ($limits as $limit) {
$buckets[$limit] = count(array_filter($values, fn($v) => $v <= $limit));
}
// 超过最大限制的值
$buckets['+Inf'] = count($values);
return $buckets;
}
}
监控数据导出
1 Prometheus格式导出
<?php
namespace App\Monitor\Exporters;
use App\Monitor\BusinessMonitor;
/**
* Prometheus格式导出器
*/
class PrometheusExporter
{
private BusinessMonitor $monitor;
public function __construct(BusinessMonitor $monitor)
{
$this->monitor = $monitor;
}
public function export(): string
{
$metrics = $this->monitor->getMetrics();
$output = '';
// 导出计数器
foreach ($metrics['counters'] as $counter) {
$output .= $this->formatCounter($counter);
}
// 导出Gauges
foreach ($metrics['gauges'] as $gauge) {
$output .= $this->formatGauge($gauge);
}
// 导出Timers
foreach ($metrics['timers'] as $timer) {
$output .= $this->formatTimer($timer);
}
// 导出Histograms
foreach ($metrics['histograms'] as $histogram) {
$output .= $this->formatHistogram($histogram);
}
return $output;
}
private function formatLabels(array $labels): string
{
if (empty($labels)) return '';
$pairs = [];
foreach ($labels as $key => $value) {
$pairs[] = sprintf('%s="%s"', $key, $value);
}
return '{' . implode(',', $pairs) . '}';
}
private function formatCounter(array $counter): string
{
$line = sprintf(
"# TYPE %s counter\n%s%s %d\n",
$counter['name'],
$counter['name'],
$this->formatLabels($counter['labels']),
$counter['value']
);
return $line;
}
private function formatGauge(array $gauge): string
{
$line = sprintf(
"# TYPE %s gauge\n%s%s %s\n",
$gauge['name'],
$gauge['name'],
$this->formatLabels($gauge['labels']),
$gauge['value']
);
return $line;
}
private function formatTimer(array $timer): string
{
$output = '';
// 主指标
$output .= sprintf(
"# TYPE %s_seconds summary\n",
$timer['name']
);
$output .= sprintf(
"%s_sum%s %f\n",
$timer['name'],
$this->formatLabels($timer['labels']),
$timer['sum']
);
$output .= sprintf(
"%s_count%s %d\n",
$timer['name'],
$this->formatLabels($timer['labels']),
$timer['count']
);
// 百分位数
foreach (['p50' => 0.5, 'p95' => 0.95, 'p99' => 0.99] as $percent => $quantile) {
$output .= sprintf(
"%s%s{%s,quantile=\"%s\"} %f\n",
$timer['name'],
'_seconds',
$this->formatLabels($timer['labels']),
$quantile,
$timer[$percent]
);
}
return $output;
}
private function formatHistogram(array $histogram): string
{
$output = '';
$labels = $this->formatLabels($histogram['labels']);
$output .= sprintf(
"# TYPE %s histogram\n",
$histogram['name']
);
// 桶数据
foreach ($histogram['buckets'] as $le => $count) {
$output .= sprintf(
"%s_bucket{%s,le=\"%s\"} %d\n",
$histogram['name'],
$labels,
$le,
$count
);
}
// 计数和总和
$output .= sprintf(
"%s_bucket{%s,le=\"+Inf\"} %d\n",
$histogram['name'],
$labels,
$histogram['count']
);
$output .= sprintf(
"%s_sum%s %f\n",
$histogram['name'],
$labels,
$histogram['sum']
);
$output .= sprintf(
"%s_count%s %d\n",
$histogram['name'],
$labels,
$histogram['count']
);
return $output;
}
}
2 JSON导出器
<?php
namespace App\Monitor\Exporters;
use App\Monitor\BusinessMonitor;
/**
* JSON格式导出器
*/
class JsonExporter
{
private BusinessMonitor $monitor;
public function __construct(BusinessMonitor $monitor)
{
$this->monitor = $monitor;
}
public function export(bool $pretty = false): string
{
$metrics = $this->monitor->getMetrics();
// 添加系统资源信息
$metrics['system'] = [
'memory' => [
'usage' => memory_get_usage(true),
'peak' => memory_get_peak_usage(true),
'limit' => ini_get('memory_limit')
],
'cpu' => [
'usage' => sys_getloadavg()
],
'server_time' => date('c'),
'php_version' => PHP_VERSION
];
return json_encode(
$metrics,
$pretty ? JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE : 0
);
}
}
集成示例
1 中间件集成
<?php
namespace App\Http\Middleware;
use Closure;
use App\Monitor\BusinessMonitor;
use App\Monitor\Collectors\RequestCollector;
use App\Monitor\Collectors\DatabaseCollector;
use Illuminate\Support\Facades\DB;
/**
* 监控中间件
*/
class MonitorMiddleware
{
private BusinessMonitor $monitor;
private RequestCollector $requestCollector;
private DatabaseCollector $dbCollector;
public function __construct(BusinessMonitor $monitor)
{
$this->monitor = $monitor;
$this->requestCollector = new RequestCollector(request()->all());
$this->dbCollector = new DatabaseCollector();
// 启用数据库查询日志
DB::enableQueryLog();
}
public function handle($request, Closure $next)
{
$startTime = microtime(true);
// 记录请求开始
$this->monitor->increment('http_requests_total');
// 处理业务
$response = $next($request);
// 收集数据库查询
$this->collectDatabaseMetrics();
// 收集请求指标
$this->collectRequestMetrics($response);
// 将监控数据附加到响应
$this->attachMetricsToResponse($response);
return $response;
}
private function collectDatabaseMetrics(): void
{
$queries = DB::getQueryLog();
foreach ($queries as $query) {
$this->dbCollector->addQuery(
$query['query'],
$query['bindings'],
$query['time']
);
}
$metrics = $this->dbCollector->collect();
// 记录到全局监控
$this->monitor->gauge('db_query_count', $metrics['query_count']);
$this->monitor->gauge('db_total_time', $metrics['total_time_ms']);
$this->monitor->gauge('db_avg_time', $metrics['avg_time_ms']);
if (!empty($metrics['slow_queries'])) {
$this->monitor->event('slow_queries', [
'count' => count($metrics['slow_queries']),
'queries' => $metrics['slow_queries']
]);
}
}
private function collectRequestMetrics($response): void
{
$duration = microtime(true) - $this->requestCollector->startTime;
// 按状态码分类
$statusCode = $response->getStatusCode();
$this->monitor->increment(
'http_requests_total',
1,
['status_code' => $statusCode]
);
// 记录请求耗时
$this->monitor->timing(
'http_request_duration_seconds',
$duration,
['method' => request()->method(), 'status_code' => $statusCode]
);
// 记录内存使用
$this->monitor->gauge('memory_usage', memory_get_usage(true));
$this->monitor->gauge('memory_peak', memory_get_peak_usage(true));
}
private function attachMetricsToResponse($response): void
{
if (method_exists($response, 'headers')) {
$metrics = $this->monitor->getMetrics();
$response->headers->set('X-Monitor-Timestamp', time());
$response->headers->set('X-Monitor-Duration',
round((microtime(true) - $this->requestCollector->startTime) * 1000, 2)
);
}
}
}
2 业务逻辑监控示例
<?php
namespace App\Services;
use App\Monitor\BusinessMonitor;
/**
* 订单服务 - 业务监控示例
*/
class OrderService
{
private BusinessMonitor $monitor;
public function __construct()
{
$this->monitor = BusinessMonitor::getInstance();
}
public function createOrder(array $orderData)
{
$startTime = microtime(true);
try {
// 业务处理
$order = $this->processOrder($orderData);
// 监控成功
$this->monitor->increment('orders_created_total');
$this->monitor->increment('orders_total', 1, [
'type' => $order['type'],
'channel' => $order['channel']
]);
// 记录订单金额
$this->monitor->histogram(
'order_amount',
$order['amount'],
['currency' => $order['currency']]
);
// 记录处理时间
$duration = microtime(true) - $startTime;
$this->monitor->timing('order_create_duration', $duration);
// 监控订单状态
$this->monitor->gauge('active_orders', $this->getActiveOrders());
return $order;
} catch (\Exception $e) {
// 监控失败
$this->monitor->increment('orders_failed_total', 1, [
'error' => get_class($e),
'stage' => 'create'
]);
// 记录异常事件
$this->monitor->event('order_error', [
'order_id' => $orderData['id'] ?? null,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
throw $e;
}
}
public function cancelOrder(int $orderId)
{
// 监控取消操作
$this->monitor->increment('orders_cancelled_total');
$reason = request()->input('reason', 'unknown');
$this->monitor->increment('orders_cancelled_total', 1, [
'reason' => $reason
]);
// 其他业务逻辑...
}
private function processOrder(array $orderData)
{
// 模拟订单处理
return array_merge($orderData, [
'id' => rand(1000, 9999),
'status' => 'created',
'created_at' => time()
]);
}
private function getActiveOrders()
{
// 模拟获取活跃订单数
return rand(10, 100);
}
}
3 监控端点路由
<?php
// routes/web.php 或 routes/api.php
use App\Monitor\BusinessMonitor;
use App\Monitor\Exporters\PrometheusExporter;
use App\Monitor\Exporters\JsonExporter;
// 监控指标端点(需要认证)
Route::get('/metrics', function () {
// 认证检查
if (!auth()->user()->isAdmin()) {
abort(403);
}
$monitor = BusinessMonitor::getInstance();
$exporter = new PrometheusExporter($monitor);
return response($exporter->export(), 200, [
'Content-Type' => 'text/plain; version=0.0.4'
]);
})->middleware('auth');
// JSON格式监控端点
Route::get('/metrics/json', function () {
if (!auth()->user()->isAdmin()) {
abort(403);
}
$monitor = BusinessMonitor::getInstance();
$exporter = new JsonExporter($monitor);
return response($exporter->export(true), 200, [
'Content-Type' => 'application/json'
]);
})->middleware('auth');
// 监控端点(用于Prometheus)
Route::get('/health', function () {
return response()->json([
'status' => 'ok',
'timestamp' => time(),
'memory' => memory_get_usage(true),
'load' => sys_getloadavg()
]);
});
自动化部署和集成
1 Docker部署监控
version: '3.8'
services:
app:
image: php:8.2-fpm
volumes:
- ./:/var/www/html
environment:
- APP_MONITOR_ENABLED=true
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
prometheus_data:
grafana_data:
2 Prometheus配置
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: []
rule_files:
- "alerts.yml"
scrape_configs:
- job_name: 'php-app'
static_configs:
- targets: ['app:8080']
metrics_path: /metrics
scrape_interval: 10s
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'docker'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'mysql'
static_configs:
- targets: ['mysql-exporter:9104']
3 监控告警规则
# alerts.yml
groups:
- name: php_alerts
rules:
- alert: HighErrorRate
expr: sum(rate(http_requests_total{status_code=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "High HTTP error rate"
description: "Error rate is {{ $value }}%"
- alert: SlowResponse
expr: histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 2
for: 5m
labels:
severity: warning
annotations:
summary: "Slow HTTP responses"
description: "P95 response time is over 2 seconds"
- alert: HighMemoryUsage
expr: memory_usage / memory_peak > 0.8
for: 10m
labels:
severity: warning
annotations:
summary: "High memory usage"
description: "Memory usage is {{ $value }}%"
配置和最佳实践
1 配置文件
<?php
// config/monitor.php
return [
'enabled' => env('APP_MONITOR_ENABLED', true),
'export' => [
'format' => env('MONITOR_EXPORT_FORMAT', 'prometheus'),
'endpoint' => '/metrics',
'auth' => [
'enabled' => true,
'token' => env('MONITOR_AUTH_TOKEN')
]
],
'collectors' => [
'request' => true,
'database' => true,
'cache' => true,
'business' => true
],
'thresholds' => [
'slow_query' => 100, // ms
'slow_request' => 500, // ms
'error_rate' => 0.05 // 5%
],
'storage' => [
'driver' => 'redis', // redis, file, array
'ttl' => 86400, // 24 hours
'path' => storage_path('monitor') // for file driver
]
];
2 最佳实践清单
<?php
/**
* 监控最佳实践
*/
class MonitorBestPractices
{
/**
* 1. 命名规范
*/
public function namingConventions(): void
{
// 计数器:_total 后缀
$this->monitor->increment('http_requests_total');
// 时间:_duration_seconds 后缀
$this->monitor->timing('order_create_duration_seconds', $duration);
// 数值:_count 后缀
$this->monitor->gauge('active_orders_count', $count);
// 非官方但常用:_total, _sum, _bucket
// 使用 namespace: 应用名_模块名_指标名
$this->monitor->increment('app_checkout_orders_total');
}
/**
* 2. 标签使用
*/
public function labelUsage(): void
{
// 少用标签,但要有足够维度
$this->monitor->increment('orders_total', 1, [
'channel' => 'mobile', // 渠道
'status' => 'paid' // 状态
]);
// 避免高基数标签
// 不要使用:order_id, uuid, timestamp
// 预定义标签
$this->monitor->increment('requests_total', 1, [
'method' => 'GET',
'path' => '/api/orders',
'status' => '200'
]);
}
/**
* 3. 采样策略
*/
public function samplingStrategy(): void
{
// 1% 采样
if (rand(1, 100) === 1) {
$this->monitor->timing('payment_duration', $duration);
}
// 错误全量记录
if ($error) {
$this->monitor->increment('errors_total');
$this->monitor->event('error_details', $errorData);
}
}
/**
* 4. 性能考虑
*/
public function performanceConsiderations(): void
{
// 使用内存存储,异步导出
$monitor = BusinessMonitor::getInstance();
// 限制数据结构大小
// - 计数器:无限制
// - Gauges:数量控制
// - Timers:保留最近1000个
// - Events:保留最近100个
// 避免在循环中调用监控
foreach ($largeArray as $item) {
// 批量处理,而不是逐条记录
}
// 批量导出
if ($batchSize >= 100) {
$this->flushToStorage();
}
}
/**
* 5. 错误处理
*/
public function errorHandling(): void
{
try {
// 业务代码
} catch (\Exception $e) {
// 记录错误但不影响业务
try {
$this->monitor->increment('errors_total', 1, [
'type' => get_class($e)
]);
} catch (\Throwable $monitorError) {
// 监控失败不应影响主流程
error_log('Monitor error: ' . $monitorError->getMessage());
}
throw $e;
}
}
/**
* 6. 数据保护
*/
public function dataProtection(): void
{
// 不记录敏感数据
$this->monitor->event('user_login', [
// 'password' => $password, // NEVER!
// 'ssn' => $ssn, // NEVER!
'user_id' => $userId,
'ip' => $ip
]);
// 对用户数据进行脱敏
$safeEmail = substr($email, 0, 3) . '***@' . substr(strrchr($email, '@'), 1);
}
}
这个完整的PHP业务监控方案包括:
- 基础监控采集器 - 请求、数据库、缓存监控
- 业务指标管理器 - 计数器、计时器、直方图等
- 多种导出格式 - Prometheus、JSON
- 集成示例 - 中间件、业务服务
- 自动化和部署 - Docker、Prometheus、Grafana
- 最佳实践 - 命名、标签、采样、安全性
您可以根据实际需求选择使用的组件,并进行适当调整。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播