Linux性能分析与诊断技术

深入探讨Linux性能分析工具和技术,从热点分析到内存泄漏检测的完整诊断流程

性能分析是系统优化的核心环节,通过科学的分析方法定位性能瓶颈,才能制定有效的优化策略。本文将深入探讨Linux性能分析的各种工具和技术,从CPU热点分析到内存泄漏检测,建立完整的性能诊断体系。

性能分析方法论

性能分析框架

Rendering diagram...

性能分析工具链

#!/bin/bash
# 性能分析工具链配置

# 安装基础性能工具
install_performance_tools() {
    echo "安装性能分析工具..."
    
    # Ubuntu/Debian
    if command -v apt-get &> /dev/null; then
     sudo apt-get update
     sudo apt-get install -y \
         perf \
         valgrind \
         strace \
         ltrace \
         sysstat \
         iotop \
         htop \
         iftop \
         tcpdump \
         wireshark \
         gdb \
         eBPF tools
    # CentOS/RHEL
    elif command -v yum &> /dev/null; then
     sudo yum install -y \
         perf \
         valgrind \
         strace \
         ltrace \
         sysstat \
         iotop \
         htop \
         iftop \
         tcpdump \
         wireshark \
         gdb
    fi
}

# 性能分析工具速查
performance_tools_reference() {
    echo "性能分析工具速查表"
    echo "============================="
    
    echo "CPU分析:"
    echo "  perf          Linux内核性能分析工具"
    echo "  top/htop      实时进程监控"
    echo "  mpstat        CPU统计信息"
    echo "  pidstat       进程CPU使用统计"
    
    echo "内存分析:"
    echo "  valgrind      内存错误和泄漏检测"
    echo "  smem          内存使用分析"
    echo "  slabtop        Slab缓存统计"
    echo "  pmap          进程内存映射"
    
    echo "I/O分析:"
    echo "  iotop         I/O监控"
    echo "  iostat        磁盘I/O统计"
    echo "  blktrace      块设备跟踪"
    echo "  sar           系统活动报告"
    
    echo "网络分析:"
    echo "  tcpdump       网络抓包"
    echo "  wireshark     网络协议分析"
    echo "  iftop         网络流量监控"
    echo "  ss            socket统计"
    
    echo "系统调用分析:"
    echo "  strace        系统调用跟踪"
    echo "  ltrace        库函数跟踪"
    echo "  ftrace        函数跟踪"
    echo "  eBPF          内核跟踪"
}

CPU性能分析

Perf深度应用

#!/bin/bash
# Perf性能分析脚本

# CPU热点分析
cpu_hotspot_analysis() {
    echo "=== CPU热点分析 ==="
    echo "采样60秒..."
    
    # 采样分析
    perf record -F 99 -g -- sleep 60
    
    # 生成火焰图
    echo "生成火焰图..."
    perf script | stackcollapse-perf.pl | flamegraph.pl > cpu_flamegraph.svg
    
    # 生成报告
    echo "生成性能报告..."
    perf report --stdio > perf_report.txt
    
    # 分析热点函数
    echo "热点函数Top 10:"
    perf report --stdio | head -20
}

# CPU缓存分析
cpu_cache_analysis() {
    echo "=== CPU缓存分析 ==="
    
    # 缓存命中率分析
    echo "缓存命中率:"
    perf stat -e cache-references,cache-misses,cycles,instructions,branch-misses \
     sleep 5
    
    # 缓存_miss分析
    echo "详细缓存分析:"
    perf record -e cache-misses sleep 10
    perf report --stdio --stdio | grep -A 5 "cache-misses"
    
    # 指令缓存分析
    echo "指令缓存分析:"
    perf record -e L1-dcache-load-misses,L1-dcache-loads sleep 10
    perf report --stdio
}

# CPU上下文切换分析
context_switch_analysis() {
    echo "=== 上下文切换分析 ==="
    
    # 上下文切换统计
    echo "上下文切换频率:"
    perf stat -e context-switches,cpu-migrations sleep 10
    
    # 上下文切换跟踪
    echo "上下文切换详情:"
    perf record -e sched:sched_switch sleep 5
    perf script | head -20
    
    # 进程调度分析
    echo "调度延迟分析:"
    perf sched latency
}

# CPU分支预测分析
branch_prediction_analysis() {
    echo "=== 分支预测分析 ==="
    
    # 分支预测统计
    echo "分支预测统计:"
    perf stat -e branches,branch-misses sleep 10
    
    # 分支预测跟踪
    echo "分支预测详情:"
    perf record -e branches:u,branch-misses:u sleep 10
    perf report --stdio
}

火焰图生成与分析

#!/usr/bin/env python3
# 火焰图分析工具

import subprocess
import sys
import json
import re

class FlameGraphAnalyzer:
    def __init__(self,perf_data_file):
     self.perf_data_file = perf_data_file
     self.call_graph = self.parse_perf_data()
     
    def parse_perf_data(self):
     """解析perf数据生成调用图"""
     call_graph = {}
     
     try:
         # 使用perf script输出
         result = subprocess.run(
             ['perf','script','-i',self.perf_data_file],
             capture_output=True,text=True
         )
         
         for line in result.stdout.split('\n'):
             if line.strip():
                 # 解析调用栈
                 stack = self.parse_call_stack(line)
                 if stack:
                     self.update_call_graph(call_graph,stack)
                     
     except Exception as e:
         print(f"解析错误: {e}")
         return {}
         
     return call_graph
    
    def parse_call_stack(self,line):
     """解析单行调用栈"""
     try:
         # perf script输出格式示例:
         # java 12345 1234567890.123456: 12345 cycles:
         # 7f8a1b234567 java/lang/String.charAt (java.base)
         # 7f8a1b234890 java/lang/String.substring (java.base)
         
         match = re.search(r'cycles:',line)
         if match:
             return None
         
         parts = line.strip().split()
         if len(parts) >= 2:
             addr = parts[0]
             func_name = parts[1]
             return [func_name]
         
         return None
         
     except Exception:
         return None
    
    def update_call_graph(self,call_graph,stack):
     """更新调用图"""
     if not stack:
         return
         
     current = call_graph
     for func in stack:
         if func not in current:
             current[func] = {'count': 0,'children': {}}
         current[func]["count"] += 1
         current = current[func]["children"]
    
    def find_hot_paths(self,threshold=0.1):
     """查找热点路径"""
     total_samples = self.count_total_samples()
     threshold_count = total_samples * threshold
     
     hot_paths = []
     self.find_paths_recursive(self.call_graph,[],0,threshold_count,hot_paths)
     
     return sorted(hot_paths,key=lambda x: x[1],reverse=True)
    
    def find_paths_recursive(self,node,path,count,threshold,results):
     """递归查找热点路径"""
     if count > threshold:
         results.append((path.copy(),count))
         
     for func,data in node.items():
         new_path = path.copy()
         new_path.append(func)
         self.find_paths_recursive(data["children"],new_path,
                                data["count"],threshold,results)
    
    def count_total_samples(self):
     """计算总样本数"""
     def count_recursive(node):
         total = 0
         for data in node.values():
             total += data["count"]
             total += count_recursive(data["children"])
         return total
         
     return count_recursive(self.call_graph)
    
    def generate_html_flamegraph(self,output_file="flamegraph.html"):
     """生成HTML火焰图"""
     html_template = """
<!DOCTYPE html>
<html>
<head>
    <title>火焰图</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
    <style>
     body {{ font-family: Arial,sans-serif; margin: 20px; }}
     .node {{ cursor: pointer; }}
     .node:hover {{ opacity: 0.8; }}
     .title {{ font-size: 12px; fill: white; }}
    </style>
</head>
<body>
    <h1>CPU火焰图</h1>
    <div id="chart"></div>
    <script>
     // 火焰图数据
     var data = {data};
     
     var width = 960;
     var height = 600;
     
     var svg = d3.select("#chart")
         .append("svg")
         .attr("width",width)
         .attr("height",height);
     
     // 这里可以添加更复杂的D3.js可视化代码
     svg.append("text")
         .attr("x",width / 2)
         .attr("y",height / 2)
         .attr("text-anchor","middle")
         .text("火焰图可视化");
    </script>
</body>
</html>
"""
     
     # 转换数据格式
     flame_data = self.convert_to_flame_format()
     
     with open(output_file,'w') as f:
         f.write(html_template.format(data=json.dumps(flame_data)))
     
     print(f"火焰图已生成: {output_file}")
    
    def convert_to_flame_format(self):
     """转换为火焰图格式"""
     def convert_recursive(node,depth=0):
         result = []
         for func,data in node.items():
             item = {{
                 'name': func,
                 'value': data["count"],
                 'depth': depth,
                 'children': convert_recursive(data["children"],depth + 1)
             }}
             result.append(item)
         return result
         
     return convert_recursive(self.call_graph)

# 使用示例
def main():
    if len(sys.argv) < 2:
     print("使用方法: python flamegraph_analyzer.py <perf.data>")
     sys.exit(1)
    
    perf_data_file = sys.argv[1]
    analyzer = FlameGraphAnalyzer(perf_data_file)
    
    print("分析热点路径...")
    hot_paths = analyzer.find_hot_paths(threshold=0.05)
    
    print("热点路径Top 10:")
    for i,(path,count) in enumerate(hot_paths[:10],1):
     print(f"{i}. {' -> '.join(path)}: {count} 次")
    
    print("\n生成火焰图...")
    analyzer.generate_html_flamegraph()

if __name__ == "__main__":
    main()

内存性能分析

Valgrind内存分析

#!/bin/bash
# Valgrind内存分析脚本

# 内存泄漏检测
memory_leak_check() {
    local program=$1
    echo "=== 内存泄漏检测 ==="
    echo "程序: $program"
    
    # 运行Valgrind内存检查
    valgrind \
     --leak-check=full \
     --show-leak-kinds=all \
     --track-origins=yes \
     --log-file=valgrind_leak.log \
     --error-exitcode=1 \
     $program
    
    echo "详细报告已生成: valgrind_leak.log"
}

# 内存性能分析
memory_performance_check() {
    local program=$1
    echo "=== 内存性能分析 ==="
    
    # 缓存分析
    echo "缓存命中率分析:"
    valgrind \
     --tool=cachegrind \
     --cachegrind-out-file=cachegrind.out \
     $program
    
    # 生成缓存报告
    cg_annotate cachegrind.out
    
    # 堆分析
    echo "堆内存分配分析:"
    valgrind \
     --tool=massif \
     --massif-out-file=massif.out \
     $program
    
    # 生成堆使用图表
    ms_print massif.out > massif_report.txt
    echo "堆使用报告: massif_report.txt"
}

# 线程分析
thread_check() {
    local program=$1
    echo "=== 线程分析 ==="
    
    # Helgrind线程分析
    valgrind \
     --tool=helgrind \
     --log-file=helgrind.log \
     $program
    
    echo "线程分析报告: helgrind.log"
    
    # Drd数据竞争检测
    valgrind \
     --tool=drd \
     --log-file=drd.log \
     $program
    
    echo "数据竞争分析: drd.log"
}

# 内存模式分析
memory_pattern_analysis() {
    echo "=== 内存访问模式分析 ==="
    
    # 使用perf分析内存访问
    echo "内存访问统计:"
    perf stat -e mem-loads,mem-stores,mem-load-misses,mem-store-misses sleep 10
    
    # 内存带宽测试
    echo "内存带宽测试:"
    if command -v mbw &> /dev/null; then
     mbw 256
    fi
    
    # 内存延迟测试
    echo "内存延迟测试:"
    if command -v lmbench &> /dev/null; then
     lmbench lat_mem -N 10 -M 512
    fi
}

内存泄漏检测实战

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 内存泄漏示例程序
void memory_leak_example() {
    printf("内存泄漏示例\n");
    printf("=============================\n");
    
    // 故意的内存泄漏
    char *leak1 = malloc(1024);
    strcpy(leak1,"这个内存块泄漏了");
    
    char *leak2 = malloc(2048);
    strcpy(leak2,"这个内存块也泄漏了");
    
    // 正常的内存分配和释放
    char *normal = malloc(512);
    strcpy(normal,"这个内存块会被正常释放");
    printf("正常分配的内存: %s\n",normal);
    free(normal);
    
    // 循环中的内存泄漏
    for (int i = 0; i < 10; i++) {
     char *loop_leak = malloc(256);
     printf("循环泄漏第 %d 次\n",i + 1);
     // 故意不释放
    }
    
    printf("程序结束,存在多处内存泄漏\n");
}

// 使用后释放
void use_after_free_example() {
    printf("\n使用后释放示例\n");
    printf("=============================\n");
    
    int *ptr = malloc(sizeof(int));
    *ptr = 42;
    printf("原始值: %d\n",*ptr);
    
    free(ptr);
    
    // 使用后释放(错误操作)
    printf("释放后的值: %d\n",*ptr);  // 未定义行为
    
    // 重复释放(错误操作)
    free(ptr);  // 可能导致崩溃
}

// 缓冲区溢出
void buffer_overflow_example() {
    printf("\n缓冲区溢出示例\n");
    printf("=============================\n");
    
    char buffer[10];
    strcpy(buffer,"123456789");  // 正常
    printf("正常复制: %s\n",buffer);
    
    // 缓冲区溢出(错误操作)
    strcpy(buffer,"12345678901234567890");  // 溢出
    printf("溢出后的内容: %s\n",buffer);
}

// 双重释放
void double_free_example() {
    printf("\n双重释放示例\n");
    printf("=============================\n");
    
    int *ptr = malloc(sizeof(int));
    *ptr = 100;
    
    printf("第一次释放\n");
    free(ptr);
    
    printf("第二次释放(错误)\n");
    free(ptr);  // 双重释放错误
}

// 内存访问越界
void out_of_bounds_access() {
    printf("\n内存访问越界示例\n");
    printf("=============================\n");
    
    int array[10];
    
    // 正常访问
    for (int i = 0; i < 10; i++) {
     array[i] = i;
    }
    
    // 越界访问(错误操作)
    printf("正常访问最后一个元素: %d\n",array[9]);
    printf("越界访问: %d\n",array[10]);  // 未定义行为
    printf("越界访问: %d\n",array[100]); // 严重越界
}

int main() {
    printf("内存错误分析示例程序\n");
    printf("这些示例包含各种内存错误,用于演示Valgrind的检测能力\n\n");
    
    memory_leak_example();
    use_after_free_example();
    buffer_overflow_example();
    double_free_example();
    out_of_bounds_access();
    
    printf("\n使用Valgrind检测这些错误:\n");
    printf("valgrind --leak-check=full --show-leak-kinds=all ./a.out\n");
    
    return 0;
}

I/O性能分析

系统调用跟踪分析

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>

// I/O密集型操作示例
void io_intensive_operations() {
    printf("I/O密集型操作示例\n");
    printf("=============================\n");
    
    // 文件写入测试
    const char *filename = "io_test.dat";
    int fd = open(filename,O_WRONLY | O_CREAT | O_TRUNC,0644);
    if (fd < 0) {
     perror("open");
     return;
    }
    
    // 同步写入(性能较差)
    char buffer[4096];
    memset(buffer,'A',sizeof(buffer));
    
    printf("开始同步写入...\n");
    for (int i = 0; i < 10000; i++) {
     write(fd,buffer,sizeof(buffer));
    }
    printf("同步写入完成\n");
    
    // 随机读取(性能较差)
    printf("开始随机读取...\n");
    char read_buffer[4096];
    for (int i = 0; i < 1000; i++) {
     off_t offset = (rand() % 10000) * 4096;
     lseek(fd,offset,SEEK_SET);
     read(fd,read_buffer,sizeof(read_buffer));
    }
    printf("随机读取完成\n");
    
    // 文件状态检查
    printf("文件状态检查...\n");
    struct stat file_stat;
    fstat(fd,&file_stat);
    printf("文件大小: %ld 字节\n",file_stat.st_size);
    printf("文件块大小: %ld 字节\n",file_stat.st_blksize);
    printf("文件块数: %ld\n",file_stat.st_blocks);
    
    close(fd);
    unlink(filename);
}

// 系统调用统计
void system_call_profiling() {
    printf("\n系统调用性能分析建议\n");
    printf("=============================\n");
    
    printf("使用strace分析系统调用:\n");
    printf("  strace -c ./your_program\n");
    printf("  strace -T -tt -e trace=read,write ./your_program\n");
    
    printf("\n使用ltrace分析库函数调用:\n");
    printf("  ltrace -c ./your_program\n");
    printf("  ltrace -T ./your_program\n");
    
    printf("\n使用perf分析系统调用:\n");
    printf("  perf stat -e syscalls:sys_enter_read,syscalls:sys_exit_read ./your_program\n");
    printf("  perf record -e 'syscalls:sys_enter_*' ./your_program\n");
}

int main() {
    io_intensive_operations();
    system_call_profiling();
    
    return 0;
}

eBPF性能跟踪

#!/bin/bash
# eBPF性能跟踪脚本

# I/O延迟跟踪
io_latency_tracking() {
    echo "=== I/O延迟跟踪 ==="
    
    # 使用bcc工具跟踪块I/O延迟
    if command -v biosnoop &> /dev/null; then
     echo "块I/O跟踪:"
     sudo biosnoop
    fi
    
    # 使用bcc工具跟踪文件I/O延迟
    if command -v filetop &> /dev/null; then
     echo "文件I/O统计:"
     sudo filetop
    fi
    
    # 使用bcc工具跟踪vfs延迟
    if command -v vfsstat &> /dev/null; then
     echo "VFS统计:"
     sudo vfsstat
    fi
}

# 网络延迟跟踪
network_latency_tracking() {
    echo "=== 网络延迟跟踪 ==="
    
    # TCP连接跟踪
    if command -v tcpconnect &> /dev/null; then
     echo "TCP连接跟踪:"
     sudo tcpconnect
    fi
    
    # TCP延迟跟踪
    if command -v tcplife &> /dev/null; then
     echo "TCP生命周期跟踪:"
     sudo tcplife
    fi
    
    # 网络延迟直方图
    if command -v tcpretransmit &> /dev/null; then
     echo "TCP重传跟踪:"
     sudo tcpretransmit
    fi
}

# 应用性能跟踪
application_performance_tracking() {
    echo "=== 应用性能跟踪 ==="
    
    # 函数延迟跟踪
    if command -v funclatency &> /dev/null; then
     echo "函数延迟统计:"
     sudo funclatency -p $$  # 跟踪当前shell的子进程
    fi
    
    # 线程性能跟踪
    if command -v offcputime &> /dev/null; then
     echo "离线CPU时间跟踪:"
     sudo offcputime
    fi
    
    # 调度延迟跟踪
    if command -v runqlat &> /dev/null; then
     echo "运行队列延迟:"
     sudo runqlat
    fi
}

综合性能分析案例

Web服务器性能分析

#!/usr/bin/env python3
# Web服务器性能分析工具

import subprocess
import time
import json
import requests

class WebServerPerformanceAnalyzer:
    def __init__(self,url,duration=60):
     self.url = url
     self.duration = duration
     self.metrics = {}
     
    def collect_system_metrics(self):
     """收集系统指标"""
     print("收集系统指标...")
     
     # CPU使用率
     cpu_usage = self.get_cpu_usage()
     self.metrics["cpu_usage"] = cpu_usage
     
     # 内存使用率
     memory_usage = self.get_memory_usage()
     self.metrics["memory_usage"] = memory_usage
     
     # I/O统计
     io_stats = self.get_io_stats()
     self.metrics["io_stats"] = io_stats
     
     # 网络统计
     network_stats = self.get_network_stats()
     self.metrics["network_stats"] = network_stats
     
    def get_cpu_usage(self):
     """获取CPU使用率"""
     try:
         result = subprocess.run(['top',"-bn1"],capture_output=True,text=True)
         for line in result.stdout.split('\n'):
             if 'Cpu(s)' in line:
                 # 解析CPU使用率
                 usage = line.split(',')[0].strip()
                 return usage
     except Exception as e:
         print(f"获取CPU使用率错误: {e}")
     return "0.0%"
    
    def get_memory_usage(self):
     """获取内存使用率"""
     try:
         result = subprocess.run(['free',"-m"],capture_output=True,text=True)
         lines = result.stdout.split('\n')
         if len(lines) >= 2:
             mem_line = lines[1].split()
             total = float(mem_line[1])
             used = float(mem_line[2])
             return f"{(used/total*100):.2f}%"
     except Exception as e:
         print(f"获取内存使用率错误: {e}")
     return "0.0%"
    
    def get_io_stats(self):
     """获取I/O统计"""
     try:
         result = subprocess.run(['iostat','-x','1',"1"],capture_output=True,text=True)
         lines = result.stdout.split('\n')
         stats = []
         for line in lines[2:]:  # 跳过前两行
             if line.strip():
                 stats.append(line)
         return stats
     except Exception as e:
         print(f"获取I/O统计错误: {e}")
     return []
    
    def get_network_stats(self):
     """获取网络统计"""
     try:
         result = subprocess.run(['netstat',"-an"],capture_output=True,text=True)
         lines = result.stdout.split('\n')
         
         established = 0
         time_wait = 0
         listen = 0
         
         for line in lines:
             if 'ESTABLISHED' in line:
                 established += 1
             elif 'TIME_WAIT' in line:
                 time_wait += 1
             elif 'LISTEN' in line:
                 listen += 1
         
         return {
             'established': established,
             'time_wait': time_wait,
             'listen': listen
         }
     except Exception as e:
         print(f"获取网络统计错误: {e}")
     return {}
    
    def benchmark_web_server(self):
     """Web服务器性能测试"""
     print(f"开始性能测试,持续 {self.duration} 秒...")
     
     total_requests = 0
     success_requests = 0
     failed_requests = 0
     total_time = 0
     
     start_time = time.time()
     end_time = start_time + self.duration
     
     while time.time() < end_time:
         try:
             request_start = time.time()
             response = requests.get(self.url,timeout=5)
             request_time = time.time() - request_start
             
             total_requests += 1
             total_time += request_time
             
             if response.status_code == 200:
                 success_requests += 1
             else:
                 failed_requests += 1
                 
         except Exception as e:
             failed_requests += 1
     
     actual_duration = time.time() - start_time
     
     # 计算性能指标
     self.metrics["total_requests"] = total_requests
     self.metrics["success_requests"] = success_requests
     self.metrics["failed_requests"] = failed_requests
     self.metrics["success_rate"] = (success_requests / total_requests * 100) if total_requests > 0 else 0
     self.metrics["requests_per_second"] = total_requests / actual_duration
     self.metrics["average_response_time"] = total_time / success_requests if success_requests > 0 else 0
     
    def generate_report(self):
     """生成性能报告"""
     print("\n性能分析报告")
     print("=" * 50)
     
     print("\n系统资源:")
     print(f"  CPU使用率: {self.metrics.get('cpu_usage','N/A')}")
     print(f"  内存使用率: {self.metrics.get('memory_usage','N/A')}")
     
     print("\n网络状态:")
     net_stats = self.metrics.get('network_stats',{})
     print(f"  ESTABLISHED连接: {net_stats.get('established',0)}")
     print(f"  TIME_WAIT连接: {net_stats.get('time_wait',0)}")
     print(f"  LISTEN连接: {net_stats.get('listen',0)}")
     
     print("\n性能指标:")
     print(f"  总请求数: {self.metrics.get('total_requests',0)}")
     print(f"  成功请求数: {self.metrics.get('success_requests',0)}")
     print(f"  失败请求数: {self.metrics.get('failed_requests',0)}")
     print(f"  成功率: {self.metrics.get('success_rate',0):.2f}%")
     print(f"  吞吐量: {self.metrics.get('requests_per_second',0):.2f} req/s")
     print(f"  平均响应时间: {self.metrics.get('average_response_time',0):.4f} 秒")
     
     # 性能评估
     print("\n性能评估:")
     rps = self.metrics.get('requests_per_second',0)
     avg_time = self.metrics.get('average_response_time',0)
     
     if rps > 10000:
         print("  ✓ 吞吐量优秀")
     elif rps > 1000:
         print("  △ 吞吐量良好")
     else:
         print("  ✗ 吞吐量较低")
     
     if avg_time < 0.1:
         print("  ✓ 响应时间优秀")
     elif avg_time < 1.0:
         print("  △ 响应时间良好")
     else:
         print("  ✗ 响应时间较高")
     
    def save_report_to_json(self,filename="performance_report.json"):
     """保存报告到JSON文件"""
     with open(filename,'w') as f:
         json.dump(self.metrics,f,indent=2)
     
     print(f"\n详细报告已保存到: {filename}")

def main():
    if len(sys.argv) < 2:
     print("使用方法: python web_analyzer.py <url>")
     print("示例: python web_analyzer.py http://localhost:8080")
     sys.exit(1)
    
    url = sys.argv[1]
    duration = 60  # 测试时长60秒
    
    analyzer = WebServerPerformanceAnalyzer(url,duration)
    
    try:
     # 运行性能测试
     analyzer.benchmark_web_server()
     
     # 收集系统指标
     analyzer.collect_system_metrics()
     
     # 生成报告
     analyzer.generate_report()
     
     # 保存详细报告
     analyzer.save_report_to_json()
     
    except KeyboardInterrupt:
     print("\n测试被用户中断")
     analyzer.generate_report()
    except Exception as e:
     print(f"测试过程中发生错误: {e}")

if __name__ == "__main__":
    main()

通过建立完善的性能分析体系,结合科学的分析方法和先进的工具,可以准确定位系统性能瓶颈,为后续的优化工作提供明确的指导方向。