OpenHarmony KMP实现API性能监控 | 实时追踪与优化

目录
概述
在现代互联网应用中,API的性能直接影响用户体验和系统可靠性。API性能监控是确保系统稳定运行的关键手段,它帮助开发者实时了解API的响应时间、吞吐量、错误率等关键指标,及时发现和解决性能问题。本文档介绍如何在 Kotlin Multiplatform (KMP) 框架下,结合 OpenHarmony 鸿蒙操作系统,实现一个功能完整的API性能监控工具。
API性能监控工具是一个综合性的性能追踪平台,它不仅能够收集API调用的详细数据,还能够进行实时分析、生成性能报告、提供优化建议。通过KMP框架的跨端能力,这个工具可以在Android、iOS、Web和OpenHarmony等多个平台上运行,为开发者提供了一个强大的API性能分析和优化工具。
API性能监控的重要性
API性能监控在现代应用开发中的重要性日益凸显:
- 实时问题发现:通过实时监控,可以快速发现API性能下降或故障,及时采取措施。
- 用户体验优化:了解API的响应时间,可以优化用户体验,减少用户等待时间。
- 容量规划:通过监控吞吐量和并发数,可以进行合理的容量规划和资源分配。
- 故障排查:详细的监控数据可以帮助快速定位和解决问题。
- 性能基准:建立性能基准,持续监控和改进系统性能。
工具的核心价值
API性能监控工具提供以下价值:
- 实时监控:实时收集和展示API的性能数据
- 详细统计:提供响应时间、吞吐量、错误率等多维度统计
- 性能告警:当性能指标超过阈值时自动告警
- 趋势分析:分析性能数据的变化趋势,预测潜在问题
- 对比分析:支持不同时间段、不同API的性能对比
- 跨平台支持:一份代码可在多个平台运行,提高开发效率
性能监控基础
关键性能指标(KPI)
响应时间(Response Time):从发送请求到收到响应的时间。通常分为最小值、最大值、平均值、中位数等。响应时间是用户最直观感受到的性能指标。
吞吐量(Throughput):单位时间内处理的请求数,通常用请求/秒表示。吞吐量反映了系统的处理能力。
错误率(Error Rate):失败请求占总请求的比例。错误率是系统可靠性的重要指标。
并发数(Concurrency):同时处理的请求数。并发数反映了系统的并发处理能力。
可用性(Availability):系统正常运行的时间比例。可用性是系统稳定性的重要指标。
性能监控的层次
应用层监控:监控应用内部的API调用性能,包括网络请求、数据库查询等。
网络层监控:监控网络传输的性能,包括延迟、丢包率等。
系统层监控:监控系统资源的使用情况,包括CPU、内存、磁盘等。
业务层监控:监控业务相关的性能指标,如订单处理时间、支付成功率等。
监控数据的收集方式
主动监控:定期主动发送请求,监控API的可用性和性能。
被动监控:收集实际用户请求的性能数据。
合成监控:模拟真实用户的操作流程,监控端到端的性能。
核心功能
1. API调用追踪
系统需要能够追踪每个API调用的完整生命周期,包括请求发送、响应接收、数据处理等各个阶段。通过详细的追踪数据,可以准确定位性能瓶颈。
2. 性能数据收集
系统需要收集API调用的各种性能数据,包括响应时间、请求大小、响应大小、错误信息等。这些数据是后续分析的基础。
3. 实时分析
系统需要对收集的数据进行实时分析,计算各种统计指标,如平均响应时间、最大响应时间、错误率等。
4. 性能告警
当性能指标超过预设的阈值时,系统应该自动发出告警,提醒开发者注意。
5. 报告生成
系统需要能够生成详细的性能报告,包括性能统计、趋势分析、问题诊断等。
6. 性能优化建议
基于监控数据和分析结果,系统应该能够提供具体的性能优化建议。
Kotlin 源代码
// APIPerformanceMonitor.kt
import java.time.LocalDateTime
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicLong
import kotlin.math.*
data class APICall(
val id: String,
val apiName: String,
val method: String,
val url: String,
val requestSize: Long,
val responseSize: Long,
val responseTime: Long,
val statusCode: Int,
val timestamp: String,
val errorMessage: String = ""
)
data class PerformanceMetrics(
val apiName: String,
val totalCalls: Long,
val successCalls: Long,
val failedCalls: Long,
val averageResponseTime: Double,
val minResponseTime: Long,
val maxResponseTime: Long,
val medianResponseTime: Double,
val p95ResponseTime: Double,
val p99ResponseTime: Double,
val errorRate: Double,
val throughput: Double,
val averageRequestSize: Double,
val averageResponseSize: Double
)
data class PerformanceAlert(
val id: String,
val apiName: String,
val alertType: String,
val threshold: Double,
val actualValue: Double,
val severity: String,
val timestamp: String,
val message: String
)
class APIPerformanceMonitor {
private val apiCalls = mutableListOf<APICall>()
private val callIdCounter = AtomicLong(0)
private val alerts = mutableListOf<PerformanceAlert>()
private val alertIdCounter = AtomicLong(0)
// 记录API调用
fun recordAPICall(
apiName: String,
method: String,
url: String,
requestSize: Long,
responseSize: Long,
responseTime: Long,
statusCode: Int,
errorMessage: String = ""
): APICall {
val id = "CALL${callIdCounter.incrementAndGet()}"
val call = APICall(
id = id,
apiName = apiName,
method = method,
url = url,
requestSize = requestSize,
responseSize = responseSize,
responseTime = responseTime,
statusCode = statusCode,
timestamp = LocalDateTime.now().toString(),
errorMessage = errorMessage
)
apiCalls.add(call)
// 检查性能告警
checkPerformanceAlerts(apiName, responseTime, statusCode)
return call
}
// 获取特定API的性能指标
fun getPerformanceMetrics(apiName: String): PerformanceMetrics {
val calls = apiCalls.filter { it.apiName == apiName }
if (calls.isEmpty()) {
return PerformanceMetrics(
apiName = apiName,
totalCalls = 0,
successCalls = 0,
failedCalls = 0,
averageResponseTime = 0.0,
minResponseTime = 0,
maxResponseTime = 0,
medianResponseTime = 0.0,
p95ResponseTime = 0.0,
p99ResponseTime = 0.0,
errorRate = 0.0,
throughput = 0.0,
averageRequestSize = 0.0,
averageResponseSize = 0.0
)
}
val totalCalls = calls.size.toLong()
val successCalls = calls.count { it.statusCode in 200..299 }.toLong()
val failedCalls = totalCalls - successCalls
val responseTimes = calls.map { it.responseTime }.sorted()
val averageResponseTime = responseTimes.average()
val minResponseTime = responseTimes.minOrNull() ?: 0L
val maxResponseTime = responseTimes.maxOrNull() ?: 0L
val medianResponseTime = calculatePercentile(responseTimes, 50.0)
val p95ResponseTime = calculatePercentile(responseTimes, 95.0)
val p99ResponseTime = calculatePercentile(responseTimes, 99.0)
val errorRate = if (totalCalls > 0) (failedCalls.toDouble() / totalCalls) * 100 else 0.0
val throughput = totalCalls.toDouble() / 60.0 // 假设监控周期为60秒
val averageRequestSize = calls.map { it.requestSize }.average()
val averageResponseSize = calls.map { it.responseSize }.average()
return PerformanceMetrics(
apiName = apiName,
totalCalls = totalCalls,
successCalls = successCalls,
failedCalls = failedCalls,
averageResponseTime = averageResponseTime,
minResponseTime = minResponseTime,
maxResponseTime = maxResponseTime,
medianResponseTime = medianResponseTime,
p95ResponseTime = p95ResponseTime,
p99ResponseTime = p99ResponseTime,
errorRate = errorRate,
throughput = throughput,
averageRequestSize = averageRequestSize,
averageResponseSize = averageResponseSize
)
}
// 获取所有API的性能指标
fun getAllPerformanceMetrics(): List<PerformanceMetrics> {
val apiNames = apiCalls.map { it.apiName }.distinct()
return apiNames.map { getPerformanceMetrics(it) }
}
// 检查性能告警
private fun checkPerformanceAlerts(apiName: String, responseTime: Long, statusCode: Int) {
val metrics = getPerformanceMetrics(apiName)
// 检查响应时间告警
if (responseTime > 5000) { // 5秒阈值
createAlert(
apiName = apiName,
alertType = "SLOW_RESPONSE",
threshold = 5000.0,
actualValue = responseTime.toDouble(),
severity = if (responseTime > 10000) "CRITICAL" else "WARNING",
message = "API响应时间过长: ${responseTime}ms"
)
}
// 检查错误率告警
if (metrics.errorRate > 5.0) { // 5%错误率阈值
createAlert(
apiName = apiName,
alertType = "HIGH_ERROR_RATE",
threshold = 5.0,
actualValue = metrics.errorRate,
severity = if (metrics.errorRate > 10.0) "CRITICAL" else "WARNING",
message = "API错误率过高: ${String.format("%.2f", metrics.errorRate)}%"
)
}
}
// 创建告警
private fun createAlert(
apiName: String,
alertType: String,
threshold: Double,
actualValue: Double,
severity: String,
message: String
) {
val alert = PerformanceAlert(
id = "ALERT${alertIdCounter.incrementAndGet()}",
apiName = apiName,
alertType = alertType,
threshold = threshold,
actualValue = actualValue,
severity = severity,
timestamp = LocalDateTime.now().toString(),
message = message
)
alerts.add(alert)
}
// 获取告警列表
fun getAlerts(severity: String = ""): List<PerformanceAlert> {
return if (severity.isEmpty()) {
alerts.toList()
} else {
alerts.filter { it.severity == severity }
}
}
// 计算百分位数
private fun calculatePercentile(sortedValues: List<Long>, percentile: Double): Double {
if (sortedValues.isEmpty()) return 0.0
val index = ((percentile / 100.0) * (sortedValues.size - 1)).toInt()
return sortedValues[index].toDouble()
}
// 获取性能趋势
fun getPerformanceTrend(apiName: String, intervalMinutes: Int = 5): Map<String, Any> {
val calls = apiCalls.filter { it.apiName == apiName }
val now = LocalDateTime.now()
val trends = mutableMapOf<String, List<Double>>()
val responseTimes = mutableListOf<Double>()
val errorRates = mutableListOf<Double>()
for (i in 0 until 12) {
val intervalStart = now.minusMinutes((12 - i) * intervalMinutes.toLong())
val intervalEnd = now.minusMinutes((11 - i) * intervalMinutes.toLong())
val intervalCalls = calls.filter {
val callTime = LocalDateTime.parse(it.timestamp)
callTime.isAfter(intervalStart) && callTime.isBefore(intervalEnd)
}
if (intervalCalls.isNotEmpty()) {
responseTimes.add(intervalCalls.map { it.responseTime }.average())
val errorCount = intervalCalls.count { it.statusCode !in 200..299 }
errorRates.add((errorCount.toDouble() / intervalCalls.size) * 100)
}
}
trends["responseTimes"] = responseTimes
trends["errorRates"] = errorRates
return mapOf(
"apiName" to apiName,
"trends" to trends,
"interval" to intervalMinutes
)
}
// 生成性能报告
fun generatePerformanceReport(): Map<String, Any> {
val allMetrics = getAllPerformanceMetrics()
return mapOf(
"timestamp" to LocalDateTime.now().toString(),
"totalAPIs" to allMetrics.size,
"totalCalls" to allMetrics.sumOf { it.totalCalls },
"totalErrors" to allMetrics.sumOf { it.failedCalls },
"averageResponseTime" to allMetrics.map { it.averageResponseTime }.average(),
"overallErrorRate" to (allMetrics.sumOf { it.failedCalls }.toDouble() /
allMetrics.sumOf { it.totalCalls }) * 100,
"metrics" to allMetrics,
"alerts" to alerts.takeLast(10),
"recommendations" to generateRecommendations(allMetrics)
)
}
// 生成优化建议
private fun generateRecommendations(metrics: List<PerformanceMetrics>): List<String> {
val recommendations = mutableListOf<String>()
for (metric in metrics) {
if (metric.averageResponseTime > 2000) {
recommendations.add("API '${metric.apiName}' 响应时间过长(${metric.averageResponseTime}ms),建议优化数据库查询或添加缓存")
}
if (metric.errorRate > 5.0) {
recommendations.add("API '${metric.apiName}' 错误率较高(${metric.errorRate}%),建议检查错误日志并修复问题")
}
if (metric.p99ResponseTime > 10000) {
recommendations.add("API '${metric.apiName}' 的P99响应时间过长(${metric.p99ResponseTime}ms),可能存在性能波动")
}
}
return recommendations
}
// 清空数据
fun clearData() {
apiCalls.clear()
alerts.clear()
}
}
fun main() {
val monitor = APIPerformanceMonitor()
// 模拟API调用
monitor.recordAPICall(
apiName = "getUserInfo",
method = "GET",
url = "/api/users/123",
requestSize = 100,
responseSize = 500,
responseTime = 150,
statusCode = 200
)
monitor.recordAPICall(
apiName = "getUserInfo",
method = "GET",
url = "/api/users/124",
requestSize = 100,
responseSize = 520,
responseTime = 200,
statusCode = 200
)
monitor.recordAPICall(
apiName = "getUserInfo",
method = "GET",
url = "/api/users/125",
requestSize = 100,
responseSize = 480,
responseTime = 6000,
statusCode = 500,
errorMessage = "Database connection timeout"
)
// 获取性能指标
val metrics = monitor.getPerformanceMetrics("getUserInfo")
println("API性能指标:")
println("总调用数: ${metrics.totalCalls}")
println("成功调用: ${metrics.successCalls}")
println("失败调用: ${metrics.failedCalls}")
println("平均响应时间: ${metrics.averageResponseTime}ms")
println("错误率: ${String.format("%.2f", metrics.errorRate)}%")
// 获取报告
val report = monitor.generatePerformanceReport()
println("\n性能报告: $report")
}
Kotlin代码说明:这个Kotlin实现提供了完整的API性能监控功能。APIPerformanceMonitor 类能够记录API调用、计算性能指标、检测性能问题、生成告警和报告。通过使用数据类、集合操作和并发工具,代码既简洁又高效。系统支持多维度的性能分析,从单个API的详细指标到整体系统的性能趋势,为开发者提供了全面的性能监控能力。
JavaScript 编译代码
// APIPerformanceMonitor.js
class APICall {
constructor(id, apiName, method, url, requestSize, responseSize, responseTime, statusCode, timestamp, errorMessage = "") {
this.id = id;
this.apiName = apiName;
this.method = method;
this.url = url;
this.requestSize = requestSize;
this.responseSize = responseSize;
this.responseTime = responseTime;
this.statusCode = statusCode;
this.timestamp = timestamp;
this.errorMessage = errorMessage;
}
}
class PerformanceMetrics {
constructor(apiName, totalCalls, successCalls, failedCalls, averageResponseTime,
minResponseTime, maxResponseTime, medianResponseTime, p95ResponseTime,
p99ResponseTime, errorRate, throughput, averageRequestSize, averageResponseSize) {
this.apiName = apiName;
this.totalCalls = totalCalls;
this.successCalls = successCalls;
this.failedCalls = failedCalls;
this.averageResponseTime = averageResponseTime;
this.minResponseTime = minResponseTime;
this.maxResponseTime = maxResponseTime;
this.medianResponseTime = medianResponseTime;
this.p95ResponseTime = p95ResponseTime;
this.p99ResponseTime = p99ResponseTime;
this.errorRate = errorRate;
this.throughput = throughput;
this.averageRequestSize = averageRequestSize;
this.averageResponseSize = averageResponseSize;
}
}
class PerformanceAlert {
constructor(id, apiName, alertType, threshold, actualValue, severity, timestamp, message) {
this.id = id;
this.apiName = apiName;
this.alertType = alertType;
this.threshold = threshold;
this.actualValue = actualValue;
this.severity = severity;
this.timestamp = timestamp;
this.message = message;
}
}
class APIPerformanceMonitor {
constructor() {
this.apiCalls = [];
this.callIdCounter = 0;
this.alerts = [];
this.alertIdCounter = 0;
}
recordAPICall(apiName, method, url, requestSize, responseSize, responseTime, statusCode, errorMessage = "") {
const id = `CALL${++this.callIdCounter}`;
const call = new APICall(
id,
apiName,
method,
url,
requestSize,
responseSize,
responseTime,
statusCode,
new Date().toISOString(),
errorMessage
);
this.apiCalls.push(call);
this.checkPerformanceAlerts(apiName, responseTime, statusCode);
return call;
}
getPerformanceMetrics(apiName) {
const calls = this.apiCalls.filter(c => c.apiName === apiName);
if (calls.length === 0) {
return new PerformanceMetrics(apiName, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
const totalCalls = calls.length;
const successCalls = calls.filter(c => c.statusCode >= 200 && c.statusCode < 300).length;
const failedCalls = totalCalls - successCalls;
const responseTimes = calls.map(c => c.responseTime).sort((a, b) => a - b);
const averageResponseTime = responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length;
const minResponseTime = Math.min(...responseTimes);
const maxResponseTime = Math.max(...responseTimes);
const medianResponseTime = this.calculatePercentile(responseTimes, 50);
const p95ResponseTime = this.calculatePercentile(responseTimes, 95);
const p99ResponseTime = this.calculatePercentile(responseTimes, 99);
const errorRate = (failedCalls / totalCalls) * 100;
const throughput = totalCalls / 60;
const averageRequestSize = calls.reduce((sum, c) => sum + c.requestSize, 0) / calls.length;
const averageResponseSize = calls.reduce((sum, c) => sum + c.responseSize, 0) / calls.length;
return new PerformanceMetrics(
apiName,
totalCalls,
successCalls,
failedCalls,
averageResponseTime,
minResponseTime,
maxResponseTime,
medianResponseTime,
p95ResponseTime,
p99ResponseTime,
errorRate,
throughput,
averageRequestSize,
averageResponseSize
);
}
getAllPerformanceMetrics() {
const apiNames = [...new Set(this.apiCalls.map(c => c.apiName))];
return apiNames.map(name => this.getPerformanceMetrics(name));
}
checkPerformanceAlerts(apiName, responseTime, statusCode) {
const metrics = this.getPerformanceMetrics(apiName);
if (responseTime > 5000) {
this.createAlert(
apiName,
"SLOW_RESPONSE",
5000,
responseTime,
responseTime > 10000 ? "CRITICAL" : "WARNING",
`API响应时间过长: ${responseTime}ms`
);
}
if (metrics.errorRate > 5.0) {
this.createAlert(
apiName,
"HIGH_ERROR_RATE",
5.0,
metrics.errorRate,
metrics.errorRate > 10.0 ? "CRITICAL" : "WARNING",
`API错误率过高: ${metrics.errorRate.toFixed(2)}%`
);
}
}
createAlert(apiName, alertType, threshold, actualValue, severity, message) {
const alert = new PerformanceAlert(
`ALERT${++this.alertIdCounter}`,
apiName,
alertType,
threshold,
actualValue,
severity,
new Date().toISOString(),
message
);
this.alerts.push(alert);
}
getAlerts(severity = "") {
return severity ? this.alerts.filter(a => a.severity === severity) : this.alerts;
}
calculatePercentile(sortedValues, percentile) {
if (sortedValues.length === 0) return 0;
const index = Math.floor((percentile / 100) * (sortedValues.length - 1));
return sortedValues[index];
}
getPerformanceTrend(apiName, intervalMinutes = 5) {
const calls = this.apiCalls.filter(c => c.apiName === apiName);
const now = new Date();
const responseTimes = [];
const errorRates = [];
for (let i = 0; i < 12; i++) {
const intervalStart = new Date(now.getTime() - (12 - i) * intervalMinutes * 60000);
const intervalEnd = new Date(now.getTime() - (11 - i) * intervalMinutes * 60000);
const intervalCalls = calls.filter(c => {
const callTime = new Date(c.timestamp);
return callTime > intervalStart && callTime < intervalEnd;
});
if (intervalCalls.length > 0) {
const avgTime = intervalCalls.reduce((sum, c) => sum + c.responseTime, 0) / intervalCalls.length;
responseTimes.push(avgTime);
const errorCount = intervalCalls.filter(c => c.statusCode < 200 || c.statusCode >= 300).length;
errorRates.push((errorCount / intervalCalls.length) * 100);
}
}
return {
apiName: apiName,
trends: {
responseTimes: responseTimes,
errorRates: errorRates
},
interval: intervalMinutes
};
}
generatePerformanceReport() {
const allMetrics = this.getAllPerformanceMetrics();
const totalCalls = allMetrics.reduce((sum, m) => sum + m.totalCalls, 0);
const totalErrors = allMetrics.reduce((sum, m) => sum + m.failedCalls, 0);
return {
timestamp: new Date().toISOString(),
totalAPIs: allMetrics.length,
totalCalls: totalCalls,
totalErrors: totalErrors,
averageResponseTime: allMetrics.reduce((sum, m) => sum + m.averageResponseTime, 0) / allMetrics.length,
overallErrorRate: (totalErrors / totalCalls) * 100,
metrics: allMetrics,
alerts: this.alerts.slice(-10),
recommendations: this.generateRecommendations(allMetrics)
};
}
generateRecommendations(metrics) {
const recommendations = [];
for (const metric of metrics) {
if (metric.averageResponseTime > 2000) {
recommendations.push(`API '${metric.apiName}' 响应时间过长(${metric.averageResponseTime}ms),建议优化数据库查询或添加缓存`);
}
if (metric.errorRate > 5.0) {
recommendations.push(`API '${metric.apiName}' 错误率较高(${metric.errorRate}%),建议检查错误日志并修复问题`);
}
if (metric.p99ResponseTime > 10000) {
recommendations.push(`API '${metric.apiName}' 的P99响应时间过长(${metric.p99ResponseTime}ms),可能存在性能波动`);
}
}
return recommendations;
}
clearData() {
this.apiCalls = [];
this.alerts = [];
}
}
// 使用示例
const monitor = new APIPerformanceMonitor();
monitor.recordAPICall("getUserInfo", "GET", "/api/users/123", 100, 500, 150, 200);
monitor.recordAPICall("getUserInfo", "GET", "/api/users/124", 100, 520, 200, 200);
monitor.recordAPICall("getUserInfo", "GET", "/api/users/125", 100, 480, 6000, 500, "Database connection timeout");
const metrics = monitor.getPerformanceMetrics("getUserInfo");
console.log("API性能指标:");
console.log("总调用数:", metrics.totalCalls);
console.log("成功调用:", metrics.successCalls);
console.log("失败调用:", metrics.failedCalls);
console.log("平均响应时间:", metrics.averageResponseTime, "ms");
console.log("错误率:", metrics.errorRate.toFixed(2), "%");
const report = monitor.generatePerformanceReport();
console.log("\n性能报告:", report);
JavaScript代码说明:JavaScript版本是Kotlin代码的直接转译。我们使用ES6的class语法定义各个类,使用数组方法进行数据处理。整体逻辑和算法与Kotlin版本保持一致,确保跨平台的一致性。JavaScript的灵活性使得代码更加简洁,同时保持了清晰的结构和完整的功能。
ArkTS 调用代码
// APIMonitorPage.ets
import { APIPerformanceMonitor } from './APIPerformanceMonitor';
@Entry
@Component
struct APIMonitorPage {
@State apiName: string = '';
@State method: string = 'GET';
@State url: string = '';
@State requestSize: number = 100;
@State responseSize: number = 500;
@State responseTime: number = 150;
@State statusCode: number = 200;
@State selectedTab: number = 0;
@State metrics: any = null;
@State allMetrics: Array<any> = [];
@State alerts: Array<any> = [];
@State report: any = null;
@State isLoading: boolean = false;
@State errorMessage: string = '';
@State trend: any = null;
private monitor: APIPerformanceMonitor = new APIPerformanceMonitor();
private methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'];
recordAPICall() {
if (!this.apiName.trim() || !this.url.trim()) {
this.errorMessage = '请输入API名称和URL';
return;
}
this.isLoading = true;
this.errorMessage = '';
try {
this.monitor.recordAPICall(
this.apiName,
this.method,
this.url,
this.requestSize,
this.responseSize,
this.responseTime,
this.statusCode
);
this.metrics = this.monitor.getPerformanceMetrics(this.apiName);
this.allMetrics = this.monitor.getAllPerformanceMetrics();
this.alerts = this.monitor.getAlerts();
AlertDialog.show({
message: 'API调用已记录'
});
} catch (error) {
this.errorMessage = '记录失败: ' + error.message;
} finally {
this.isLoading = false;
}
}
generateReport() {
this.isLoading = true;
try {
this.report = this.monitor.generatePerformanceReport();
} catch (error) {
this.errorMessage = '生成报告失败: ' + error.message;
} finally {
this.isLoading = false;
}
}
getTrendData() {
if (!this.apiName.trim()) {
this.errorMessage = '请先输入API名称';
return;
}
try {
this.trend = this.monitor.getPerformanceTrend(this.apiName, 5);
} catch (error) {
this.errorMessage = '获取趋势数据失败: ' + error.message;
}
}
getStatusColor(statusCode: number): string {
if (statusCode >= 200 && statusCode < 300) return '#4CAF50';
if (statusCode >= 300 && statusCode < 400) return '#2196F3';
if (statusCode >= 400 && statusCode < 500) return '#FF9800';
return '#F44336';
}
getSeverityColor(severity: string): string {
switch (severity) {
case 'CRITICAL': return '#F44336';
case 'WARNING': return '#FF9800';
case 'INFO': return '#2196F3';
default: return '#999999';
}
}
build() {
Column() {
// 顶部标题
Text('API性能监控工具')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 20 })
// 标签页
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
Column() {
Text('记录API调用')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 15 })
Text('API名称:')
.fontSize(12)
.margin({ bottom: 5 })
TextInput({ placeholder: '例如: getUserInfo' })
.value(this.apiName)
.onChange((value: string) => {
this.apiName = value;
})
.height(40)
.padding(10)
.border({ width: 1, color: '#cccccc' })
.margin({ bottom: 15 })
Row() {
Column() {
Text('请求方法:')
.fontSize(12)
.margin({ bottom: 5 })
Select(this.methods.map(m => ({ value: m })))
.value(this.method)
.onSelect((index: number, value?: string) => {
this.method = value || 'GET';
})
}
.flex(1)
Column() {
Text('状态码:')
.fontSize(12)
.margin({ bottom: 5 })
TextInput({ placeholder: '200' })
.type(InputType.Number)
.value(this.statusCode.toString())
.onChange((value: string) => {
this.statusCode = parseInt(value) || 200;
})
.height(40)
.padding(10)
.border({ width: 1, color: '#cccccc' })
}
.flex(1)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Text('URL:')
.fontSize(12)
.margin({ bottom: 5 })
TextInput({ placeholder: '/api/users/123' })
.value(this.url)
.onChange((value: string) => {
this.url = value;
})
.height(40)
.padding(10)
.border({ width: 1, color: '#cccccc' })
.margin({ bottom: 15 })
Row() {
Column() {
Text('请求大小(B):')
.fontSize(12)
.margin({ bottom: 5 })
TextInput({ placeholder: '100' })
.type(InputType.Number)
.value(this.requestSize.toString())
.onChange((value: string) => {
this.requestSize = parseInt(value) || 100;
})
.height(40)
.padding(10)
.border({ width: 1, color: '#cccccc' })
}
.flex(1)
Column() {
Text('响应大小(B):')
.fontSize(12)
.margin({ bottom: 5 })
TextInput({ placeholder: '500' })
.type(InputType.Number)
.value(this.responseSize.toString())
.onChange((value: string) => {
this.responseSize = parseInt(value) || 500;
})
.height(40)
.padding(10)
.border({ width: 1, color: '#cccccc' })
}
.flex(1)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Text('响应时间(ms):')
.fontSize(12)
.margin({ bottom: 5 })
Slider({ value: this.responseTime, min: 10, max: 10000, step: 10 })
.onChange((value: number) => {
this.responseTime = value;
})
.margin({ bottom: 10 })
Text(`${this.responseTime}ms`)
.fontSize(12)
.fontColor('#2196F3')
.margin({ bottom: 15 })
Button('记录调用')
.width('100%')
.height(40)
.margin({ bottom: 15 })
.onClick(() => {
this.recordAPICall();
})
.enabled(!this.isLoading)
if (this.errorMessage) {
Text(this.errorMessage)
.fontSize(12)
.fontColor('#F44336')
.margin({ bottom: 15 })
}
}
.padding(15)
}
.tabBar('📝 记录调用')
TabContent() {
Column() {
if (this.metrics) {
Text('性能指标')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 15 })
Row() {
Column() {
Text('总调用数')
.fontSize(11)
.fontColor('#999999')
Text(this.metrics.totalCalls.toString())
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#2196F3')
.margin({ top: 5 })
}
.flex(1)
.alignItems(HorizontalAlign.Center)
.padding(10)
.backgroundColor('#F5F5F5')
.borderRadius(5)
Column() {
Text('成功调用')
.fontSize(11)
.fontColor('#999999')
Text(this.metrics.successCalls.toString())
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#4CAF50')
.margin({ top: 5 })
}
.flex(1)
.alignItems(HorizontalAlign.Center)
.padding(10)
.backgroundColor('#F5F5F5')
.borderRadius(5)
.margin({ left: 10 })
Column() {
Text('失败调用')
.fontSize(11)
.fontColor('#999999')
Text(this.metrics.failedCalls.toString())
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#F44336')
.margin({ top: 5 })
}
.flex(1)
.alignItems(HorizontalAlign.Center)
.padding(10)
.backgroundColor('#F5F5F5')
.borderRadius(5)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Column() {
Row() {
Text('平均响应时间:')
.fontSize(12)
Text(`${this.metrics.averageResponseTime.toFixed(2)}ms`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
.fontColor('#2196F3')
}
.margin({ bottom: 10 })
Row() {
Text('最小响应时间:')
.fontSize(12)
Text(`${this.metrics.minResponseTime}ms`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('最大响应时间:')
.fontSize(12)
Text(`${this.metrics.maxResponseTime}ms`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('P95响应时间:')
.fontSize(12)
Text(`${this.metrics.p95ResponseTime.toFixed(2)}ms`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('P99响应时间:')
.fontSize(12)
Text(`${this.metrics.p99ResponseTime.toFixed(2)}ms`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('错误率:')
.fontSize(12)
Text(`${this.metrics.errorRate.toFixed(2)}%`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
.fontColor(this.metrics.errorRate > 5 ? '#F44336' : '#4CAF50')
}
}
.padding(10)
.backgroundColor('#F5F5F5')
.borderRadius(5)
} else {
Text('请先记录API调用')
.fontSize(12)
.fontColor('#999999')
}
}
.padding(15)
}
.tabBar('📊 性能指标')
TabContent() {
Column() {
if (this.alerts.length > 0) {
Text('性能告警')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 15 })
List() {
ForEach(this.alerts, (alert: any) => {
ListItem() {
Column() {
Row() {
Text(alert.alertType)
.fontSize(12)
.fontWeight(FontWeight.Bold)
.flex(1)
Text(alert.severity)
.fontSize(11)
.fontColor('#FFFFFF')
.fontWeight(FontWeight.Bold)
.padding({ left: 8, right: 8, top: 4, bottom: 4 })
.backgroundColor(this.getSeverityColor(alert.severity))
.borderRadius(3)
}
.margin({ bottom: 8 })
Text(alert.message)
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 8 })
Text(alert.timestamp)
.fontSize(10)
.fontColor('#999999')
}
.padding(10)
.border({ width: 1, color: '#eeeeee' })
.borderRadius(5)
}
}, (alert: any) => alert.id)
}
} else {
Text('暂无告警')
.fontSize(12)
.fontColor('#999999')
}
}
.padding(15)
}
.tabBar('⚠️ 告警')
TabContent() {
Column() {
Button('生成报告')
.width('100%')
.height(40)
.margin({ bottom: 15 })
.onClick(() => {
this.generateReport();
})
if (this.report) {
Text('性能报告')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 15 })
Column() {
Row() {
Text('总API数:')
.fontSize(12)
Text(this.report.totalAPIs.toString())
.fontSize(12)
.fontWeight(FontWeight.Bold)
.fontColor('#2196F3')
}
.margin({ bottom: 10 })
Row() {
Text('总调用数:')
.fontSize(12)
Text(this.report.totalCalls.toString())
.fontSize(12)
.fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('总错误数:')
.fontSize(12)
Text(this.report.totalErrors.toString())
.fontSize(12)
.fontWeight(FontWeight.Bold)
.fontColor('#F44336')
}
.margin({ bottom: 10 })
Row() {
Text('平均响应时间:')
.fontSize(12)
Text(`${this.report.averageResponseTime.toFixed(2)}ms`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('总体错误率:')
.fontSize(12)
Text(`${this.report.overallErrorRate.toFixed(2)}%`)
.fontSize(12)
.fontWeight(FontWeight.Bold)
.fontColor(this.report.overallErrorRate > 5 ? '#F44336' : '#4CAF50')
}
}
.padding(10)
.backgroundColor('#F5F5F5')
.borderRadius(5)
.margin({ bottom: 15 })
if (this.report.recommendations && this.report.recommendations.length > 0) {
Text('优化建议:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
Column() {
ForEach(this.report.recommendations, (rec: string, index: number) => {
Row() {
Text('💡')
.fontSize(14)
.margin({ right: 10 })
Text(rec)
.fontSize(11)
.flex(1)
}
.padding(10)
.margin({ bottom: 8 })
.backgroundColor('#E8F5E9')
.borderRadius(5)
}, (rec: string, index: number) => index.toString())
}
}
}
}
.padding(15)
}
.tabBar('📈 报告')
}
.width('100%')
.flex(1)
}
.padding(10)
.width('100%')
.height('100%')
}
}
ArkTS代码说明:这个ArkTS实现展示了如何在OpenHarmony应用中集成API性能监控工具。通过使用标签页组件,用户可以在记录调用、查看性能指标、查看告警和生成报告之间切换。UI设计直观,提供了良好的用户体验。每个标签页都有不同的功能,用户可以全面地了解API的性能特性和问题。
监控指标详解
响应时间指标
平均响应时间:所有请求的平均响应时间,反映API的整体性能。
最小/最大响应时间:响应时间的极值,帮助了解性能的波动范围。
中位数响应时间:50%的请求在这个时间内完成,比平均值更能反映典型情况。
P95/P99响应时间:95%/99%的请求在这个时间内完成,反映性能的尾部情况。
可靠性指标
错误率:失败请求的比例,是系统可靠性的重要指标。
成功率:成功请求的比例,通常应该在99%以上。
吞吐量:单位时间内处理的请求数,反映系统的处理能力。
资源指标
平均请求大小:平均每个请求的数据量,影响网络带宽消耗。
平均响应大小:平均每个响应的数据量,影响网络带宽和客户端处理。
实战应用
应用场景1:电商平台API监控
在电商平台中,订单API、支付API等关键API的性能直接影响用户体验。通过API性能监控,可以实时发现性能问题,如支付API响应时间过长,可能导致用户放弃购买。通过监控数据,可以及时优化数据库查询、添加缓存等。
应用场景2:社交媒体API监控
在社交媒体应用中,用户信息API、消息API等高频调用的API需要特别关注。通过监控可以发现高峰期的性能下降,及时进行扩容或优化。
应用场景3:金融系统API监控
在金融系统中,交易API、账户查询API等关键API的可靠性至关重要。通过监控可以确保这些API的高可用性,及时发现和解决问题。
应用场景4:IoT系统API监控
在IoT系统中,大量设备同时调用API,需要监控API的吞吐量和并发处理能力。通过监控可以发现系统的瓶颈,进行相应的优化。
总结
API性能监控工具是现代应用开发中的重要工具。通过KMP框架和OpenHarmony操作系统的结合,我们可以实现一个功能完整、高效可靠的API性能监控工具。
这个工具不仅能够实时收集和分析API的性能数据,还能够自动检测性能问题、生成告警和报告、提供优化建议。通过本文介绍的Kotlin实现、JavaScript编译和ArkTS调用,开发者可以快速构建自己的API性能监控系统。
在实际应用中,API性能监控的价值远不止于此。从性能优化到故障排查,从容量规划到用户体验改进,API性能监控都发挥着重要的作用。通过持续监控和优化,可以构建更加高效和可靠的系统。
掌握好API性能监控的方法和工具,对于提升系统性能和用户体验都有重要的帮助。通过这个工具的学习和使用,希望能够帮助开发者更好地理解和优化自己的API,构建更加高效和可靠的系统。
更多推荐


所有评论(0)