php项目统计长短传比例如何分布?

wen PHP项目 5

本文目录导读:

php项目统计长短传比例如何分布?

  1. 网络请求(HTTP请求)长短传统计
  2. 文件上传大小分布
  3. 数据库查询长短耗时统计
  4. API接口响应时间统计
  5. 使用Redis实时统计
  6. 可视化展示
  7. 使用建议

在PHP项目中统计长短传比例,主要取决于你的业务场景,以下是几种常见场景的解决方案:

网络请求(HTTP请求)长短传统计

<?php
class RequestTimeStats {
    private $db;
    public function __construct($db) {
        $this->db = $db;
    }
    // 记录请求耗时
    public function logRequestTime($requestTime) {
        $isLong = $requestTime > 1.0; // 1秒以上算长传
        $stmt = $this->db->prepare(
            "INSERT INTO request_stats (timestamp, duration, type) 
             VALUES (NOW(), ?, ?)"
        );
        $stmt->execute([
            $requestTime,
            $isLong ? 'long' : 'short'
        ]);
    }
    // 统计数据
    public function getStats($timeRange = 'today') {
        $where = '';
        if ($timeRange == 'today') {
            $where = "WHERE DATE(timestamp) = CURDATE()";
        } elseif ($timeRange == 'week') {
            $where = "WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
        }
        $sql = "SELECT 
                    type,
                    COUNT(*) as count,
                    AVG(duration) as avg_duration,
                    MIN(duration) as min_duration,
                    MAX(duration) as max_duration
                FROM request_stats 
                $where
                GROUP BY type";
        return $this->db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    }
}
?>

文件上传大小分布

<?php
class FileUploadStats {
    // 文件大小分类
    public function categorizeFiles($fileSize) {
        $categories = [
            'very_small' => 0,      // 0-10KB
            'small' => 1,           // 10KB-100KB
            'medium' => 2,          // 100KB-1MB
            'large' => 3,           // 1MB-10MB
            'very_large' => 4       // >10MB
        ];
        if ($fileSize < 10240) {
            return 'very_small';
        } elseif ($fileSize < 102400) {
            return 'small';
        } elseif ($fileSize < 1048576) {
            return 'medium';
        } elseif ($fileSize < 10485760) {
            return 'large';
        } else {
            return 'very_large';
        }
    }
    // 统计上传文件分布
    public function getUploadDistribution($startDate, $endDate) {
        $sql = "SELECT 
                    CASE 
                        WHEN file_size < 10240 THEN '0-10KB'
                        WHEN file_size < 102400 THEN '10KB-100KB'
                        WHEN file_size < 1048576 THEN '100KB-1MB'
                        WHEN file_size < 10485760 THEN '1MB-10MB'
                        ELSE '>10MB'
                    END as size_range,
                    COUNT(*) as count,
                    SUM(file_size) as total_size
                FROM uploads
                WHERE created_at BETWEEN ? AND ?
                GROUP BY size_range
                ORDER BY MIN(file_size)";
        return $this->db->query($sql, [$startDate, $endDate])->fetchAll();
    }
}
?>

数据库查询长短耗时统计

<?php
class QueryPerformanceStats {
    public function analyzeQueryPerformance() {
        // 启用慢查询日志
        $this->db->exec("SET GLOBAL slow_query_log = 'ON'");
        $this->db->exec("SET GLOBAL long_query_time = 1"); // 1秒以上
        // 从慢查询日志获取数据
        $logFile = ini_get('slow_query_log_file');
        $logs = file($logFile);
        $stats = [
            'long_queries' => 0,
            'short_queries' => 0,
            'total_queries' => 0,
            'long_query_details' => []
        ];
        foreach ($logs as $log) {
            if (preg_match('/Query_time:\s*([0-9.]+)/', $log, $matches)) {
                $stats['total_queries']++;
                if ((float)$matches[1] > 1.0) {
                    $stats['long_queries']++;
                    $stats['long_query_details'][] = [
                        'query_time' => $matches[1],
                        'query' => extractQuery($log)
                    ];
                } else {
                    $stats['short_queries']++;
                }
            }
        }
        // 计算比例
        $stats['long_ratio'] = $stats['total_queries'] > 0 
            ? ($stats['long_queries'] / $stats['total_queries']) * 100 
            : 0;
        return $stats;
    }
    private function extractQuery($logLine) {
        // 解析查询语句
        preg_match('/Query:\s*(.*)/', $logLine, $matches);
        return isset($matches[1]) ? $matches[1] : '';
    }
}
?>

API接口响应时间统计

<?php
class APIResponseStats {
    // 中间件/拦截器统计
    public function calculateResponseStats() {
        $sql = "SELECT 
                    DATE(created_at) as date,
                    route,
                    AVG(response_time) as avg_response,
                    MAX(response_time) as max_response,
                    MIN(response_time) as min_response,
                    SUM(CASE WHEN response_time > 2 THEN 1 ELSE 0 END) as long_requests,
                    SUM(CASE WHEN response_time <= 2 THEN 1 ELSE 0 END) as short_requests,
                    COUNT(*) as total_requests
                FROM api_logs
                GROUP BY DATE(created_at), route
                ORDER BY date DESC, total_requests DESC";
        return $this->db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    }
    // 生成统计报告
    public function generateReport() {
        $stats = $this->calculateResponseStats();
        $report = [
            'total_requests' => 0,
            'long_requests' => 0,
            'short_requests' => 0,
            'long_ratio' => 0,
            'by_route' => []
        ];
        foreach ($stats as $stat) {
            $report['total_requests'] += $stat['total_requests'];
            $report['long_requests'] += $stat['long_requests'];
            $report['short_requests'] += $stat['short_requests'];
            // 按路由统计
            if (!isset($report['by_route'][$stat['route']])) {
                $report['by_route'][$stat['route']] = [
                    'total' => 0,
                    'long' => 0,
                    'short' => 0
                ];
            }
            $report['by_route'][$stat['route']]['total'] += $stat['total_requests'];
            $report['by_route'][$stat['route']]['long'] += $stat['long_requests'];
            $report['by_route'][$stat['route']]['short'] += $stat['short_requests'];
        }
        // 计算总比例
        if ($report['total_requests'] > 0) {
            $report['long_ratio'] = $report['long_requests'] / $report['total_requests'] * 100;
            $report['short_ratio'] = 100 - $report['long_ratio'];
        }
        return $report;
    }
}
?>

使用Redis实时统计

<?php
class RealTimeStats {
    private $redis;
    public function __construct($redis) {
        $this->redis = $redis;
    }
    // 实时增加统计
    public function incrementStats($type) {
        $today = date('Y-m-d');
        // 使用Hash存储每日数据
        $key = "stats:request:{$today}";
        $this->redis->hIncrBy($key, 'total', 1);
        $this->redis->hIncrBy($key, $type, 1);
        // 设置过期时间(保留30天)
        $this->redis->expire($key, 86400 * 30);
    }
    // 获取实时统计
    public function getCurrentStats() {
        $today = date('Y-m-d');
        $key = "stats:request:{$today}";
        $data = $this->redis->hGetAll($key);
        $total = isset($data['total']) ? $data['total'] : 0;
        $long = isset($data['long']) ? $data['long'] : 0;
        $short = isset($data['short']) ? $data['short'] : 0;
        return [
            'total' => $total,
            'long' => $long,
            'short' => $short,
            'long_ratio' => $total > 0 ? ($long / $total) * 100 : 0,
            'short_ratio' => $total > 0 ? ($short / $total) * 100 : 0,
            'updated_at' => date('Y-m-d H:i:s')
        ];
    }
}
?>

可视化展示

// 生成饼图/柱状图数据
public function getChartData() {
    $stats = $this->getStats();
    return [
        'labels' => ['短传', '长传'],
        'datasets' => [
            [
                'data' => [$stats['short'], $stats['long']],
                'backgroundColor' => ['#36A2EB', '#FF6384'],
                'hoverBackgroundColor' => ['#36A2EB', '#FF6384']
            ]
        ]
    ];
}

使用建议

  1. 阈值定义:根据业务需求定义“长传”的标准(如超过1秒、超过1MB等)
  2. 存储方案:可以使用数据库、Redis或日志文件
  3. 实时监控:建议配合监控系统(如Prometheus + Grafana)
  4. 优化建议:根据统计结果优化相关代码或配置

这样可以根据实际需求选择合适的方法来统计长短传比例,你需要哪种具体场景的实现?

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