资源管理
资源管理是 AI Builder 应用运维的重要组成部分,包括云函数、数据库、存储、CDN 等资源的监控、优化和管理。有效的资源管理能够确保应用稳定运行、控制成本、提升性能。
概述
资源管理涵盖以下核心领域:
- 📊 资源监控:实时监控各项资源使用情况
- 💰 成本控制:优化资源配置,控制运营成本
- 🔧 性能优化:提升应用性能和用户体验
- 🛡️ 安全管理:确保资源和数据安全
- 📈 扩容管理:根据业务需求调整资源规模
资源概览
1. 资源类型
计算资源:
- 云函数实例
- 函数执行时长
- 内存使用量
- 并发请求数
存储资源:
- 数据库存储空间
- 文件存储空间
- 读写操作次数
- 数据传输量
网络资源:
- CDN 流量
- 带宽使用量
- 请求次数
- 缓存命中率
2. 资源监控面板
控制台概览:
// 资源监控数据结构
const resourceMetrics = {
functions: {
totalInvocations: 125000,
totalDuration: 3600000, // 毫秒
averageMemoryUsage: 128, // MB
errorRate: 0.02, // 2%
concurrentExecutions: 50
},
database: {
storageUsed: 2.5, // GB
readOperations: 50000,
writeOperations: 15000,
indexSize: 0.3 // GB
},
storage: {
totalFiles: 1200,
storageUsed: 5.8, // GB
downloadCount: 8500,
uploadCount: 1200
},
cdn: {
totalRequests: 180000,
bandwidth: 45.2, // GB
cacheHitRate: 0.85, // 85%
averageResponseTime: 120 // 毫秒
}
};
云函数管理
1. 函数监控
性能指标监控:
// functions/monitoring/metrics.js
const cloud = require('@cloudbase/node-sdk');
class FunctionMetrics {
constructor() {
this.app = cloud.init({
env: cloud.SYMBOL_CURRENT_ENV
});
this.db = this.app.database();
}
// 记录函数执行指标
async recordMetrics(functionName, startTime, endTime, memoryUsed, success) {
const duration = endTime - startTime;
const metrics = {
functionName,
duration,
memoryUsed,
success,
timestamp: new Date(),
date: new Date().toISOString().split('T')[0]
};
try {
await this.db.collection('function_metrics').add(metrics);
} catch (error) {
console.error('记录指标失败:', error);
}
}
// 获取函数性能统计
async getFunctionStats(functionName, days = 7) {
const startDate = new Date();
startDate.setDate(startDate.getDate() - days);
const result = await this.db.collection('function_metrics')
.aggregate()
.match({
functionName,
timestamp: this.db.command.gte(startDate)
})
.group({
_id: '$date',
totalInvocations: { $sum: 1 },
averageDuration: { $avg: '$duration' },
maxDuration: { $max: '$duration' },
averageMemory: { $avg: '$memoryUsed' },
successRate: {
$avg: {
$cond: ['$success', 1, 0]
}
}
})
.sort({ _id: 1 })
.end();
return result.data;
}
}
// 在云函数中使用
exports.main = async (event, context) => {
const startTime = Date.now();
const metrics = new FunctionMetrics();
try {
// 业务逻辑
const result = await processTask(event);
// 记录成功指标
await metrics.recordMetrics(
context.functionName,
startTime,
Date.now(),
context.memoryLimitInMB,
true
);
return {
code: 0,
data: result
};
} catch (error) {
// 记录失败指标
await metrics.recordMetrics(
context.functionName,
startTime,
Date.now(),
context.memoryLimitInMB,
false
);
throw error;
}
};
2. 函数优化
内存配置优化:
// scripts/optimize-functions.js
const cloud = require('@cloudbase/node-sdk');
class FunctionOptimizer {
constructor() {
this.app = cloud.init({
env: process.env.TCB_ENV
});
}
// 分析函数内存使用情况
async analyzeMemoryUsage(functionName) {
const stats = await this.getFunctionStats(functionName, 30);
const memoryStats = {
average: stats.reduce((sum, day) => sum + day.averageMemory, 0) / stats.length,
max: Math.max(...stats.map(day => day.maxMemory)),
p95: this.calculatePercentile(stats.map(day => day.maxMemory), 95)
};
// 推荐内存配置
const recommendedMemory = Math.ceil(memoryStats.p95 * 1.2 / 64) * 64; // 向上取整到64MB
return {
current: await this.getCurrentMemoryConfig(functionName),
recommended: recommendedMemory,
stats: memoryStats
};
}
// 自动调整函数配置
async optimizeFunctionConfig(functionName) {
const analysis = await this.analyzeMemoryUsage(functionName);
if (analysis.recommended !== analysis.current) {
console.log(`建议调整 ${functionName} 内存配置:`);
console.log(`当前: ${analysis.current}MB`);
console.log(`推荐: ${analysis.recommended}MB`);
// 这里可以调用 API 自动更新配置
// await this.updateFunctionConfig(functionName, {
// memory: analysis.recommended
// });
}
}
calculatePercentile(values, percentile) {
const sorted = values.sort((a, b) => a - b);
const index = Math.ceil(sorted.length * percentile / 100) - 1;
return sorted[index];
}
}
// 定期运行优化
const optimizer = new FunctionOptimizer();
optimizer.optimizeFunctionConfig('getTasks');
optimizer.optimizeFunctionConfig('createTask');
3. 错误监控和告警
错误收集系统:
// functions/monitoring/errorCollector.js
class ErrorCollector {
constructor() {
this.app = cloud.init({
env: cloud.SYMBOL_CURRENT_ENV
});
this.db = this.app.database();
}
// 记录错误信息
async logError(error, context, event) {
const errorLog = {
functionName: context.functionName,
errorMessage: error.message,
errorStack: error.stack,
requestId: context.requestId,
event: JSON.stringify(event),
timestamp: new Date(),
severity: this.classifyError(error)
};
try {
await this.db.collection('error_logs').add(errorLog);
// 严重错误立即告警
if (errorLog.severity === 'critical') {
await this.sendAlert(errorLog);
}
} catch (logError) {
console.error('记录错误日志失败:', logError);
}
}
// 错误分类
classifyError(error) {
if (error.message.includes('timeout')) {
return 'warning';
}
if (error.message.includes('permission') || error.message.includes('auth')) {
return 'critical';
}
if (error.message.includes('database')) {
return 'error';
}
return 'info';
}
// 发送告警
async sendAlert(errorLog) {
// 这里可以集成邮件、短信、钉钉等告警方式
console.log('🚨 严重错误告警:', errorLog.errorMessage);
// 示例:发送邮件告警
// await this.sendEmail({
// to: 'admin@yourcompany.com',
// subject: `[严重错误] ${errorLog.functionName}`,
// body: `错误信息: ${errorLog.errorMessage}\n\n堆栈: ${errorLog.errorStack}`
// });
}
// 获取错误统计
async getErrorStats(hours = 24) {
const startTime = new Date();
startTime.setHours(startTime.getHours() - hours);
const result = await this.db.collection('error_logs')
.aggregate()
.match({
timestamp: this.db.command.gte(startTime)
})
.group({
_id: {
functionName: '$functionName',
severity: '$severity'
},
count: { $sum: 1 },
latestError: { $max: '$timestamp' }
})
.end();
return result.data;
}
}
// 在云函数中使用
const errorCollector = new ErrorCollector();
exports.main = async (event, context) => {
try {
// 业务逻辑
return await processRequest(event);
} catch (error) {
// 记录错误
await errorCollector.logError(error, context, event);
// 重新抛出错误
throw error;
}
};
数据库管理
1. 存储监控
数据库使用情况分析:
// scripts/database-analysis.js
class DatabaseAnalyzer {
constructor() {
this.app = cloud.init({
env: process.env.TCB_ENV
});
this.db = this.app.database();
}
// 分析集合大小
async analyzeCollections() {
const collections = ['users', 'tasks', 'categories', 'logs'];
const analysis = [];
for (const collectionName of collections) {
try {
const stats = await this.getCollectionStats(collectionName);
analysis.push({
collection: collectionName,
...stats
});
} catch (error) {
console.error(`分析集合 ${collectionName} 失败:`, error);
}
}
return analysis;
}
// 获取集合统计信息
async getCollectionStats(collectionName) {
const collection = this.db.collection(collectionName);
// 获取文档数量
const countResult = await collection.count();
const documentCount = countResult.total;
// 获取最新和最旧的文档
const latestDoc = await collection
.orderBy('_createTime', 'desc')
.limit(1)
.get();
const oldestDoc = await collection
.orderBy('_createTime', 'asc')
.limit(1)
.get();
// 估算存储大小(简化计算)
const sampleDocs = await collection.limit(100).get();
const avgDocSize = sampleDocs.data.length > 0
? JSON.stringify(sampleDocs.data).length / sampleDocs.data.length
: 0;
const estimatedSize = (avgDocSize * documentCount) / (1024 * 1024); // MB
return {
documentCount,
estimatedSizeMB: Math.round(estimatedSize * 100) / 100,
oldestDocument: oldestDoc.data[0]?._createTime,
latestDocument: latestDoc.data[0]?._createTime,
avgDocumentSize: Math.round(avgDocSize)
};
}
// 数据清理建议
async getCleanupRecommendations() {
const recommendations = [];
// 检查日志数据
const logStats = await this.getCollectionStats('logs');
if (logStats.documentCount > 100000) {
recommendations.push({
type: 'cleanup',
collection: 'logs',
reason: '日志数据过多,建议清理30天前的数据',
action: 'DELETE_OLD_LOGS'
});
}
// 检查临时数据
const tempDataCount = await this.db.collection('temp_data')
.where({
_createTime: this.db.command.lt(new Date(Date.now() - 7 * 24 * 60 * 60 * 1000))
})
.count();
if (tempDataCount.total > 0) {
recommendations.push({
type: 'cleanup',
collection: 'temp_data',
reason: `发现 ${tempDataCount.total} 条过期临时数据`,
action: 'DELETE_EXPIRED_TEMP_DATA'
});
}
return recommendations;
}
}
// 定期运行分析
const analyzer = new DatabaseAnalyzer();
analyzer.analyzeCollections().then(analysis => {
console.log('数据库分析结果:', analysis);
});
2. 索引优化
索引性能分析:
// scripts/index-optimizer.js
class IndexOptimizer {
constructor() {
this.app = cloud.init({
env: process.env.TCB_ENV
});
this.db = this.app.database();
}
// 分析查询性能
async analyzeQueryPerformance() {
const slowQueries = await this.db.collection('query_logs')
.where({
duration: this.db.command.gt(1000), // 超过1秒的查询
timestamp: this.db.command.gte(new Date(Date.now() - 24 * 60 * 60 * 1000))
})
.orderBy('duration', 'desc')
.limit(50)
.get();
// 分析慢查询模式
const queryPatterns = this.analyzeQueryPatterns(slowQueries.data);
// 生成索引建议
const indexRecommendations = this.generateIndexRecommendations(queryPatterns);
return {
slowQueries: slowQueries.data,
patterns: queryPatterns,
recommendations: indexRecommendations
};
}
// 分析查询模式
analyzeQueryPatterns(queries) {
const patterns = {};
queries.forEach(query => {
const key = `${query.collection}_${JSON.stringify(query.where)}`;
if (!patterns[key]) {
patterns[key] = {
collection: query.collection,
whereClause: query.where,
count: 0,
totalDuration: 0,
avgDuration: 0
};
}
patterns[key].count++;
patterns[key].totalDuration += query.duration;
patterns[key].avgDuration = patterns[key].totalDuration / patterns[key].count;
});
return Object.values(patterns)
.sort((a, b) => b.avgDuration - a.avgDuration)
.slice(0, 10);
}
// 生成索引建议
generateIndexRecommendations(patterns) {
const recommendations = [];
patterns.forEach(pattern => {
const whereFields = Object.keys(pattern.whereClause);
if (whereFields.length > 0) {
recommendations.push({
collection: pattern.collection,
fields: whereFields,
reason: `查询频率高且耗时较长 (平均 ${Math.round(pattern.avgDuration)}ms)`,
priority: pattern.avgDuration > 2000 ? 'high' : 'medium',
createIndexCommand: this.generateCreateIndexCommand(pattern.collection, whereFields)
});
}
});
return recommendations;
}
// 生成创建索引的命令
generateCreateIndexCommand(collection, fields) {
const indexSpec = fields.map(field => `{ name: '${field}', direction: 1 }`).join(', ');
return `db.collection('${collection}').createIndex({ keys: [${indexSpec}] })`;
}
}
// 使用示例
const optimizer = new IndexOptimizer();
optimizer.analyzeQueryPerformance().then(analysis => {
console.log('查询性能分析:', analysis);
if (analysis.recommendations.length > 0) {
console.log('\n索引优化建议:');
analysis.recommendations.forEach((rec, index) => {
console.log(`${index + 1}. ${rec.collection} 集合`);
console.log(` 字段: ${rec.fields.join(', ')}`);
console.log(` 原因: ${rec.reason}`);
console.log(` 命令: ${rec.createIndexCommand}`);
console.log('');
});
}
});
3. 数据备份
自动备份策略:
// scripts/backup-manager.js
class BackupManager {
constructor() {
this.app = cloud.init({
env: process.env.TCB_ENV
});
this.db = this.app.database();
this.storage = this.app.storage();
}
// 执行数据备份
async performBackup() {
const backupId = `backup_${Date.now()}`;
const backupPath = `backups/${backupId}`;
console.log(`开始执行备份: ${backupId}`);
try {
const collections = ['users', 'tasks', 'categories'];
const backupData = {};
// 备份每个集合
for (const collectionName of collections) {
console.log(`备份集合: ${collectionName}`);
const data = await this.backupCollection(collectionName);
backupData[collectionName] = data;
}
// 保存备份文件
const backupContent = JSON.stringify(backupData, null, 2);
const fileName = `${backupPath}/data.json`;
await this.storage.uploadFile({
cloudPath: fileName,
fileContent: Buffer.from(backupContent, 'utf8')
});
// 记录备份信息
await this.recordBackup({
backupId,
fileName,
size: backupContent.length,
collections: Object.keys(backupData),
documentCounts: Object.fromEntries(
Object.entries(backupData).map(([name, data]) => [name, data.length])
),
timestamp: new Date()
});
console.log(`备份完成: ${fileName}`);
return { success: true, backupId, fileName };
} catch (error) {
console.error('备份失败:', error);
return { success: false, error: error.message };
}
}
// 备份单个集合
async backupCollection(collectionName) {
const collection = this.db.collection(collectionName);
const batchSize = 1000;
let allData = [];
let lastDoc = null;
while (true) {
let query = collection.limit(batchSize);
if (lastDoc) {
query = query.where({
_id: this.db.command.gt(lastDoc._id)
});
}
const result = await query.orderBy('_id', 'asc').get();
if (result.data.length === 0) {
break;
}
allData = allData.concat(result.data);
lastDoc = result.data[result.data.length - 1];
console.log(`已备份 ${collectionName}: ${allData.length} 条记录`);
}
return allData;
}
// 记录备份信息
async recordBackup(backupInfo) {
await this.db.collection('backup_logs').add(backupInfo);
}
// 清理旧备份
async cleanupOldBackups(retentionDays = 30) {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
// 查找过期备份
const oldBackups = await this.db.collection('backup_logs')
.where({
timestamp: this.db.command.lt(cutoffDate)
})
.get();
console.log(`发现 ${oldBackups.data.length} 个过期备份`);
// 删除过期备份文件和记录
for (const backup of oldBackups.data) {
try {
// 删除存储文件
await this.storage.deleteFile({
fileList: [backup.fileName]
});
// 删除备份记录
await this.db.collection('backup_logs').doc(backup._id).remove();
console.log(`已删除过期备份: ${backup.backupId}`);
} catch (error) {
console.error(`删除备份失败: ${backup.backupId}`, error);
}
}
}
// 恢复数据
async restoreFromBackup(backupId) {
console.log(`开始恢复备份: ${backupId}`);
try {
// 查找备份记录
const backupRecord = await this.db.collection('backup_logs')
.where({ backupId })
.get();
if (backupRecord.data.length === 0) {
throw new Error('备份记录不存在');
}
const backup = backupRecord.data[0];
// 下载备份文件
const fileResult = await this.storage.downloadFile({
fileID: backup.fileName
});
const backupData = JSON.parse(fileResult.fileContent.toString());
// 恢复每个集合
for (const [collectionName, data] of Object.entries(backupData)) {
console.log(`恢复集合: ${collectionName}`);
await this.restoreCollection(collectionName, data);
}
console.log('数据恢复完成');
return { success: true };
} catch (error) {
console.error('数据恢复失败:', error);
return { success: false, error: error.message };
}
}
// 恢复单个集合
async restoreCollection(collectionName, data) {
const collection = this.db.collection(collectionName);
const batchSize = 100;
for (let i = 0; i < data.length; i += batchSize) {
const batch = data.slice(i, i + batchSize);
// 批量插入数据
const promises = batch.map(doc => {
const { _id, ...docData } = doc;
return collection.doc(_id).set(docData);
});
await Promise.all(promises);
console.log(`已恢复 ${collectionName}: ${Math.min(i + batchSize, data.length)}/${data.length}`);
}
}
}
// 定期备份任务
const backupManager = new BackupManager();
// 每天凌晨2点执行备份
const scheduleBackup = () => {
const now = new Date();
const tomorrow = new Date(now);
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(2, 0, 0, 0);
const timeUntilBackup = tomorrow.getTime() - now.getTime();
setTimeout(async () => {
await backupManager.performBackup();
await backupManager.cleanupOldBackups();
// 安排下一次备份
scheduleBackup();
}, timeUntilBackup);
};
// 启动定期备份
scheduleBackup();
存储管理
1. 文件存储监控
存储使用分析:
// scripts/storage-analyzer.js
class StorageAnalyzer {
constructor() {
this.app = cloud.init({
env: process.env.TCB_ENV
});
this.storage = this.app.storage();
this.db = this.app.database();
}
// 分析存储使用情况
async analyzeStorageUsage() {
console.log('开始分析存储使用情况...');
const analysis = {
totalFiles: 0,
totalSize: 0,
fileTypes: {},
largeFIles: [],
oldFiles: [],
duplicateFiles: []
};
// 获取所有文件信息
const files = await this.getAllFiles();
files.forEach(file => {
analysis.totalFiles++;
analysis.totalSize += file.size;
// 按文件类型分类
const extension = this.getFileExtension(file.name);
if (!analysis.fileTypes[extension]) {
analysis.fileTypes[extension] = { count: 0, size: 0 };
}
analysis.fileTypes[extension].count++;
analysis.fileTypes[extension].size += file.size;
// 识别大文件 (>10MB)
if (file.size > 10 * 1024 * 1024) {
analysis.largeFIles.push({
name: file.name,
size: file.size,
sizeFormatted: this.formatFileSize(file.size),
lastModified: file.lastModified
});
}
// 识别旧文件 (>1年)
const oneYearAgo = new Date();
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
if (file.lastModified < oneYearAgo) {
analysis.oldFiles.push({
name: file.name,
size: file.size,
lastModified: file.lastModified
});
}
});
// 排序大文件
analysis.largeFIles.sort((a, b) => b.size - a.size);
// 排序旧文件
analysis.oldFiles.sort((a, b) => a.lastModified - b.lastModified);
return analysis;
}
// 获取所有文件信息
async getAllFiles() {
// 这里需要根据实际的云存储 API 来实现
// 示例实现
const files = [];
let marker = null;
do {
const result = await this.storage.listFiles({
prefix: '',
marker,
maxKeys: 1000
});
files.push(...result.files);
marker = result.nextMarker;
} while (marker);
return files;
}
// 获取文件扩展名
getFileExtension(filename) {
const parts = filename.split('.');
return parts.length > 1 ? parts.pop().toLowerCase() : 'unknown';
}
// 格式化文件大小
formatFileSize(bytes) {
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
let size = bytes;
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${Math.round(size * 100) / 100} ${units[unitIndex]}`;
}
// 清理建议
async getCleanupRecommendations(analysis) {
const recommendations = [];
// 大文件建议
if (analysis.largeFIles.length > 0) {
const totalLargeFileSize = analysis.largeFIles.reduce((sum, file) => sum + file.size, 0);
recommendations.push({
type: 'large_files',
count: analysis.largeFIles.length,
totalSize: this.formatFileSize(totalLargeFileSize),
suggestion: '检查是否需要压缩或删除大文件',
files: analysis.largeFIles.slice(0, 10) // 只显示前10个
});
}
// 旧文件建议
if (analysis.oldFiles.length > 0) {
const totalOldFileSize = analysis.oldFiles.reduce((sum, file) => sum + file.size, 0);
recommendations.push({
type: 'old_files',
count: analysis.oldFiles.length,
totalSize: this.formatFileSize(totalOldFileSize),
suggestion: '考虑归档或删除长期未使用的文件',
files: analysis.oldFiles.slice(0, 10)
});
}
// 文件类型建议
const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
const totalImageSize = imageTypes.reduce((sum, type) => {
return sum + (analysis.fileTypes[type]?.size || 0);
}, 0);
if (totalImageSize > 100 * 1024 * 1024) { // 超过100MB
recommendations.push({
type: 'image_optimization',
totalSize: this.formatFileSize(totalImageSize),
suggestion: '考虑压缩图片文件以节省存储空间'
});
}
return recommendations;
}
}
// 使用示例
const analyzer = new StorageAnalyzer();
analyzer.analyzeStorageUsage().then(async analysis => {
console.log('存储分析结果:');
console.log(`总文件数: ${analysis.totalFiles}`);
console.log(`总大小: ${analyzer.formatFileSize(analysis.totalSize)}`);
console.log('\n文件类型分布:');
Object.entries(analysis.fileTypes)
.sort((a, b) => b[1].size - a[1].size)
.forEach(([type, info]) => {
console.log(` ${type}: ${info.count} 个文件, ${analyzer.formatFileSize(info.size)}`);
});
const recommendations = await analyzer.getCleanupRecommendations(analysis);
if (recommendations.length > 0) {
console.log('\n清理建议:');
recommendations.forEach((rec, index) => {
console.log(`${index + 1}. ${rec.suggestion}`);
console.log(` 影响: ${rec.count} 个文件, ${rec.totalSize}`);
});
}
});
成本优化
1. 成本分析
资源成本计算:
// scripts/cost-analyzer.js
class CostAnalyzer {
constructor() {
this.pricing = {
functions: {
invocations: 0.0000002, // 每次调用
gbSeconds: 0.000016667, // 每GB-秒
outboundTraffic: 0.12 // 每GB流出流量
},
database: {
storage: 0.07, // 每GB每月
reads: 0.0000015, // 每次读操作
writes: 0.0000015 // 每次写操作
},
storage: {
storage: 0.043, // 每GB每月
downloads: 0.12, // 每GB下载流量
requests: 0.0004 // 每1000次请求
},
cdn: {
traffic: 0.18 // 每GB流量
}
};
}
// 计算云函数成本
calculateFunctionCosts(metrics) {
const invocationCost = metrics.totalInvocations * this.pricing.functions.invocations;
const computeCost = (metrics.totalDuration / 1000) * (metrics.averageMemoryUsage / 1024) * this.pricing.functions.gbSeconds;
const trafficCost = metrics.outboundTraffic * this.pricing.functions.outboundTraffic;
return {
invocations: invocationCost,
compute: computeCost,
traffic: trafficCost,
total: invocationCost + computeCost + trafficCost
};
}
// 计算数据库成本
calculateDatabaseCosts(metrics) {
const storageCost = metrics.storageUsed * this.pricing.database.storage;
const readCost = metrics.readOperations * this.pricing.database.reads;
const writeCost = metrics.writeOperations * this.pricing.database.writes;
return {
storage: storageCost,
reads: readCost,
writes: writeCost,
total: storageCost + readCost + writeCost
};
}
// 计算存储成本
calculateStorageCosts(metrics) {
const storageCost = metrics.storageUsed * this.pricing.storage.storage;
const downloadCost = metrics.downloadTraffic * this.pricing.storage.downloads;
const requestCost = (metrics.totalRequests / 1000) * this.pricing.storage.requests;
return {
storage: storageCost,
downloads: downloadCost,
requests: requestCost,
total: storageCost + downloadCost + requestCost
};
}
// 计算 CDN 成本
calculateCDNCosts(metrics) {
const trafficCost = metrics.bandwidth * this.pricing.cdn.traffic;
return {
traffic: trafficCost,
total: trafficCost
};
}
// 生成成本报告
generateCostReport(resourceMetrics) {
const functionCosts = this.calculateFunctionCosts(resourceMetrics.functions);
const databaseCosts = this.calculateDatabaseCosts(resourceMetrics.database);
const storageCosts = this.calculateStorageCosts(resourceMetrics.storage);
const cdnCosts = this.calculateCDNCosts(resourceMetrics.cdn);
const totalCost = functionCosts.total + databaseCosts.total + storageCosts.total + cdnCosts.total;
return {
functions: functionCosts,
database: databaseCosts,
storage: storageCosts,
cdn: cdnCosts,
total: totalCost,
breakdown: {
functions: (functionCosts.total / totalCost * 100).toFixed(1),
database: (databaseCosts.total / totalCost * 100).toFixed(1),
storage: (storageCosts.total / totalCost * 100).toFixed(1),
cdn: (cdnCosts.total / totalCost * 100).toFixed(1)
}
};
}
// 成本优化建议
generateOptimizationSuggestions(costReport, resourceMetrics) {
const suggestions = [];
// 云函数优化建议
if (costReport.functions.total > costReport.total * 0.4) {
suggestions.push({
category: 'functions',
priority: 'high',
suggestion: '云函数成本占比较高,建议优化函数执行时间和内存配置',
potentialSavings: costReport.functions.total * 0.2,
actions: [
'优化代码逻辑,减少执行时间',
'调整内存配置,避免过度分配',
'使用连接池减少数据库连接时间',
'启用函数预热减少冷启动'
]
});
}
// 数据库优化建议
if (resourceMetrics.database.readOperations > resourceMetrics.database.writeOperations * 10) {
suggestions.push({
category: 'database',
priority: 'medium',
suggestion: '读操作频率较高,建议使用缓存减少数据库访问',
potentialSavings: costReport.database.reads * 0.5,
actions: [
'实现 Redis 缓存层',
'使用应用级缓存',
'优化查询语句',
'建立合适的索引'
]
});
}
// 存储优化建议
if (costReport.storage.downloads > costReport.storage.storage * 2) {
suggestions.push({
category: 'storage',
priority: 'medium',
suggestion: '下载流量成本较高,建议启用 CDN 加速',
potentialSavings: costReport.storage.downloads * 0.3,
actions: [
'启用 CDN 加速',
'优化图片压缩',
'使用适当的缓存策略',
'清理不必要的文件'
]
});
}
return suggestions;
}
}
// 使用示例
const costAnalyzer = new CostAnalyzer();
// 模拟资源使用数据
const resourceMetrics = {
functions: {
totalInvocations: 125000,
totalDuration: 3600000,
averageMemoryUsage: 128,
outboundTraffic: 2.5
},
database: {
storageUsed: 2.5,
readOperations: 50000,
writeOperations: 15000
},
storage: {
storageUsed: 5.8,
downloadTraffic: 12.3,
totalRequests: 25000
},
cdn: {
bandwidth: 45.2
}
};
const costReport = costAnalyzer.generateCostReport(resourceMetrics);
const suggestions = costAnalyzer.generateOptimizationSuggestions(costReport, resourceMetrics);
console.log('成本分析报告:');
console.log(`总成本: $${costReport.total.toFixed(2)}/月`);
console.log('\n成本分布:');
console.log(`云函数: $${costReport.functions.total.toFixed(2)} (${costReport.breakdown.functions}%)`);
console.log(`数据库: $${costReport.database.total.toFixed(2)} (${costReport.breakdown.database}%)`);
console.log(`存储: $${costReport.storage.total.toFixed(2)} (${costReport.breakdown.storage}%)`);
console.log(`CDN: $${costReport.cdn.total.toFixed(2)} (${costReport.breakdown.cdn}%)`);
if (suggestions.length > 0) {
console.log('\n优化建议:');
suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion.suggestion}`);
console.log(` 预计节省: $${suggestion.potentialSavings.toFixed(2)}/月`);
console.log(` 优先级: ${suggestion.priority}`);
console.log(` 行动项目:`);
suggestion.actions.forEach(action => {
console.log(` - ${action}`);
});
console.log('');
});
}
告警和通知
1. 告警规则配置
告警系统:
// monitoring/alerting.js
class AlertingSystem {
constructor() {
this.app = cloud.init({
env: cloud.SYMBOL_CURRENT_ENV
});
this.db = this.app.database();
// 告警规则配置
this.alertRules = [
{
name: '函数错误率过高',
type: 'function_error_rate',
threshold: 0.05, // 5%
duration: 300, // 5分钟
severity: 'critical'
},
{
name: '数据库连接数过高',
type: 'database_connections',
threshold: 80, // 80%
duration: 60, // 1分钟
severity: 'warning'
},
{
name: '存储空间不足',
type: 'storage_usage',
threshold: 0.9, // 90%
duration: 0, // 立即
severity: 'critical'
},
{
name: 'CDN 缓存命中率低',
type: 'cdn_hit_rate',
threshold: 0.7, // 70%
duration: 1800, // 30分钟
severity: 'warning'
}
];
}
// 检查告警条件
async checkAlerts() {
const alerts = [];
for (const rule of this.alertRules) {
const isTriggered = await this.evaluateRule(rule);
if (isTriggered) {
const alert = {
ruleName: rule.name,
type: rule.type,
severity: rule.severity,
threshold: rule.threshold,
currentValue: isTriggered.value,
message: this.generateAlertMessage(rule, isTriggered.value),
timestamp: new Date()
};
alerts.push(alert);
await this.sendAlert(alert);
}
}
return alerts;
}
// 评估告警规则
async evaluateRule(rule) {
const endTime = new Date();
const startTime = new Date(endTime.getTime() - rule.duration * 1000);
switch (rule.type) {
case 'function_error_rate':
return await this.checkFunctionErrorRate(startTime, endTime, rule.threshold);
case 'database_connections':
return await this.checkDatabaseConnections(rule.threshold);
case 'storage_usage':
return await this.checkStorageUsage(rule.threshold);
case 'cdn_hit_rate':
return await this.checkCDNHitRate(startTime, endTime, rule.threshold);
default:
return false;
}
}
// 检查函数错误率
async checkFunctionErrorRate(startTime, endTime, threshold) {
const result = await this.db.collection('function_metrics')
.aggregate()
.match({
timestamp: this.db.command.gte(startTime).and(this.db.command.lte(endTime))
})
.group({
_id: null,
totalInvocations: { $sum: 1 },
errorCount: {
$sum: {
$cond: [{ $eq: ['$success', false] }, 1, 0]
}
}
})
.end();
if (result.data.length > 0) {
const stats = result.data[0];
const errorRate = stats.errorCount / stats.totalInvocations;
if (errorRate > threshold) {
return { value: errorRate };
}
}
return false;
}
// 检查数据库连接数
async checkDatabaseConnections(threshold) {
// 这里需要根据实际的监控 API 来实现
// 示例实现
const currentConnections = 75; // 假设当前连接数
const maxConnections = 100; // 最大连接数
const usage = currentConnections / maxConnections;
if (usage > threshold) {
return { value: usage };
}
return false;
}
// 检查存储使用率
async checkStorageUsage(threshold) {
// 获取存储使用情况
const storageStats = await this.getStorageStats();
const usage = storageStats.used / storageStats.total;
if (usage > threshold) {
return { value: usage };
}
return false;
}
// 检查 CDN 缓存命中率
async checkCDNHitRate(startTime, endTime, threshold) {
const result = await this.db.collection('cdn_metrics')
.aggregate()
.match({
timestamp: this.db.command.gte(startTime).and(this.db.command.lte(endTime))
})
.group({
_id: null,
totalRequests: { $sum: '$requests' },
cacheHits: { $sum: '$cacheHits' }
})
.end();
if (result.data.length > 0) {
const stats = result.data[0];
const hitRate = stats.cacheHits / stats.totalRequests;
if (hitRate < threshold) {
return { value: hitRate };
}
}
return false;
}
// 生成告警消息
generateAlertMessage(rule, currentValue) {
const formatValue = (value) => {
if (rule.type.includes('rate') || rule.type.includes('usage')) {
return `${(value * 100).toFixed(1)}%`;
}
return value.toString();
};
return `${rule.name}: 当前值 ${formatValue(currentValue)}, 阈值 ${formatValue(rule.threshold)}`;
}
// 发送告警
async sendAlert(alert) {
console.log(`🚨 ${alert.severity.toUpperCase()} 告警: ${alert.message}`);
// 记录告警历史
await this.db.collection('alert_history').add(alert);
// 根据严重程度选择通知方式
switch (alert.severity) {
case 'critical':
await this.sendEmailAlert(alert);
await this.sendSMSAlert(alert);
break;
case 'warning':
await this.sendEmailAlert(alert);
break;
case 'info':
// 只记录,不发送通知
break;
}
}
// 发送邮件告警
async sendEmailAlert(alert) {
// 这里集成邮件服务
console.log(`📧 发送邮件告警: ${alert.message}`);
}
// 发送短信告警
async sendSMSAlert(alert) {
// 这里集成短信服务
console.log(`📱 发送短信告警: ${alert.message}`);
}
// 获取存储统计信息
async getStorageStats() {
// 这里需要根据实际的存储 API 来实现
return {
used: 8.5, // GB
total: 10 // GB
};
}
}
// 定期检查告警
const alerting = new AlertingSystem();
setInterval(async () => {
try {
const alerts = await alerting.checkAlerts();
if (alerts.length > 0) {
console.log(`检测到 ${alerts.length} 个告警`);
}
} catch (error) {
console.error('告警检查失败:', error);
}
}, 60000); // 每分钟检查一次
常见问题
Q: 如何降低云函数的执行成本?
A: 优化代码逻辑、调整内存配置、使用连接池、启用函数预热等方式可以有效降低成本。
Q: 数据库查询速度慢怎么办?
A: 检查索引配置、优化查询语句、使用缓存、分析慢查询日志等方法可以提升性能。
Q: 如何监控应用的实时状态?
A: 建立完善的监控体系,包括性能指标、错误日志、告警规则等。
Q: 存储空间不足如何处理?
A: 清理无用文件、压缩大文件、建立数据归档策略、扩容存储空间。
总结
通过完善的资源管理,您可以:
- 📊 实时监控:掌握应用运行状态和资源使用情况
- 💰 成本优化:通过合理配置和优化策略控制运营成本
- 🚀 性能提升:识别瓶颈并进行针对性优化
- 🛡️ 稳定运行:通过告警和自动化确保应用稳定性
- 📈 扩展能力:根据业务增长合理规划资源扩容
建议定期审查资源使用情况,持续优化配置,确保应用高效稳定运行。
🎉 恭喜!您已完成 AI Builder 的完整学习流程
从需求描述到资源管理,您现在已经掌握了使用 AI Builder 开发和部署应用的全部技能。继续实践和探索,创造更多精彩的应用!