Files
s-hy2/scripts/performance-utils.sh
T
2025-09-24 14:59:19 +08:00

418 lines
9.6 KiB
Bash

#!/bin/bash
# 性能优化工具库
# 提供缓存、批处理和优化的系统调用
set -euo pipefail
# 性能缓存
declare -g -A PERFORMANCE_CACHE=()
declare -g -A CACHE_TIMESTAMPS=()
declare -g CACHE_TTL=300 # 5分钟缓存过期
# 批处理命令队列
declare -g -a BATCH_COMMANDS=()
declare -g BATCH_SIZE=10
# 系统信息缓存
declare -g -A SYSTEM_INFO_CACHE=()
# ========== 缓存管理 ==========
# 获取缓存键
get_cache_key() {
local prefix="$1"
shift
echo "$prefix:$(printf '%s:' "$@" | sed 's/:$//')"
}
# 检查缓存是否有效
is_cache_valid() {
local key="$1"
local current_time=$(date +%s)
local cache_time="${CACHE_TIMESTAMPS[$key]:-0}"
[[ $((current_time - cache_time)) -lt $CACHE_TTL ]]
}
# 设置缓存
set_cache() {
local key="$1"
local value="$2"
PERFORMANCE_CACHE["$key"]="$value"
CACHE_TIMESTAMPS["$key"]=$(date +%s)
}
# 获取缓存
get_cache() {
local key="$1"
if [[ -n "${PERFORMANCE_CACHE[$key]:-}" ]] && is_cache_valid "$key"; then
echo "${PERFORMANCE_CACHE[$key]}"
return 0
else
return 1
fi
}
# 清理过期缓存
cleanup_cache() {
local current_time=$(date +%s)
for key in "${!CACHE_TIMESTAMPS[@]}"; do
local cache_time="${CACHE_TIMESTAMPS[$key]}"
if [[ $((current_time - cache_time)) -ge $CACHE_TTL ]]; then
unset PERFORMANCE_CACHE["$key"]
unset CACHE_TIMESTAMPS["$key"]
fi
done
}
# ========== 系统信息缓存 ==========
# 获取系统信息(缓存版本)
get_system_info_cached() {
local info_type="$1"
local cache_key="system_info:$info_type"
if get_cache "$cache_key" >/dev/null; then
get_cache "$cache_key"
return 0
fi
local value
case "$info_type" in
"os_release")
if [[ -f /etc/os-release ]]; then
value=$(cat /etc/os-release)
else
value="unknown"
fi
;;
"cpu_count")
value=$(nproc 2>/dev/null || echo "1")
;;
"memory_total")
value=$(free -m 2>/dev/null | awk '/^Mem:/ {print $2}' || echo "0")
;;
"disk_space")
value=$(df -h / 2>/dev/null | awk 'NR==2 {print $4}' || echo "unknown")
;;
"kernel_version")
value=$(uname -r 2>/dev/null || echo "unknown")
;;
*)
value="unknown"
;;
esac
set_cache "$cache_key" "$value"
echo "$value"
}
# ========== 网络检查优化 ==========
# 批量端口检查
check_ports_batch() {
local ports=("$@")
local results=()
# 使用ss命令批量检查(比多次netstat快)
if command -v ss >/dev/null; then
local listening_ports
listening_ports=$(ss -tuln 2>/dev/null | awk '{print $5}' | grep -oE '[0-9]+$' | sort -u)
for port in "${ports[@]}"; do
if echo "$listening_ports" | grep -q "^$port$"; then
results+=("$port:used")
else
results+=("$port:free")
fi
done
else
# 降级到传统方法
for port in "${ports[@]}"; do
if netstat -tuln 2>/dev/null | grep -q ":$port "; then
results+=("$port:used")
else
results+=("$port:free")
fi
done
fi
printf '%s\n' "${results[@]}"
}
# ========== 文件操作优化 ==========
# 大文件处理优化
process_large_file() {
local file_path="$1"
local operation="$2"
local chunk_size="${3:-1048576}" # 1MB 默认块大小
if [[ ! -f "$file_path" ]]; then
return 1
fi
case "$operation" in
"checksum")
# 使用块读取计算大文件校验和
if command -v sha256sum >/dev/null; then
sha256sum "$file_path" | cut -d' ' -f1
else
# 降级方案
openssl dgst -sha256 "$file_path" | cut -d' ' -f2
fi
;;
"line_count")
# 优化的行数统计
wc -l < "$file_path"
;;
"size")
# 获取文件大小
stat --format='%s' "$file_path" 2>/dev/null || \
stat -f%z "$file_path" 2>/dev/null || \
wc -c < "$file_path"
;;
*)
return 1
;;
esac
}
# 批量文件操作
batch_file_operations() {
local operation="$1"
shift
local files=("$@")
case "$operation" in
"exists")
for file in "${files[@]}"; do
[[ -f "$file" ]] && echo "$file:exists" || echo "$file:missing"
done
;;
"size")
for file in "${files[@]}"; do
if [[ -f "$file" ]]; then
local size
size=$(process_large_file "$file" "size")
echo "$file:$size"
else
echo "$file:missing"
fi
done
;;
"permissions")
stat --format='%n:%a' "${files[@]}" 2>/dev/null || \
for file in "${files[@]}"; do
if [[ -f "$file" ]]; then
local perms
perms=$(stat -f%Mp%Lp "$file" 2>/dev/null || echo "unknown")
echo "$file:$perms"
else
echo "$file:missing"
fi
done
;;
esac
}
# ========== 进程管理优化 ==========
# 批量进程检查
check_processes_batch() {
local process_names=("$@")
local results=()
# 一次性获取所有进程信息
local all_processes
all_processes=$(ps aux 2>/dev/null | awk '{print $11}' | sort -u)
for process in "${process_names[@]}"; do
if echo "$all_processes" | grep -q "$process"; then
results+=("$process:running")
else
results+=("$process:stopped")
fi
done
printf '%s\n' "${results[@]}"
}
# ========== 网络连接优化 ==========
# 优化的连接测试
test_connection_optimized() {
local host="$1"
local port="${2:-80}"
local timeout="${3:-5}"
# 使用缓存避免重复测试
local cache_key
cache_key=$(get_cache_key "connection" "$host" "$port")
if get_cache "$cache_key" >/dev/null; then
get_cache "$cache_key"
return $?
fi
local result
if timeout "$timeout" bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null; then
result="success"
set_cache "$cache_key" "$result"
echo "$result"
return 0
else
result="failed"
set_cache "$cache_key" "$result"
echo "$result"
return 1
fi
}
# ========== 命令批处理 ==========
# 添加命令到批处理队列
add_to_batch() {
local command="$1"
BATCH_COMMANDS+=("$command")
# 自动执行批处理(当队列满时)
if [[ ${#BATCH_COMMANDS[@]} -ge $BATCH_SIZE ]]; then
execute_batch
fi
}
# 执行批处理命令
execute_batch() {
if [[ ${#BATCH_COMMANDS[@]} -eq 0 ]]; then
return 0
fi
# 并行执行命令(限制并发数)
local max_concurrent=4
local concurrent=0
for command in "${BATCH_COMMANDS[@]}"; do
if [[ $concurrent -ge $max_concurrent ]]; then
wait # 等待一些任务完成
concurrent=0
fi
eval "$command" &
((concurrent++))
done
wait # 等待所有任务完成
# 清空队列
BATCH_COMMANDS=()
}
# 强制执行剩余批处理
flush_batch() {
execute_batch
}
# ========== 配置文件优化 ==========
# 缓存配置解析
parse_config_cached() {
local config_file="$1"
local cache_key
cache_key=$(get_cache_key "config" "$config_file")
if get_cache "$cache_key" >/dev/null; then
eval "$(get_cache "$cache_key")"
return 0
fi
if [[ ! -f "$config_file" ]]; then
return 1
fi
local config_content
config_content=$(grep -E '^[A-Z_]+=.*' "$config_file" | sed 's/^/export /')
set_cache "$cache_key" "$config_content"
eval "$config_content"
}
# ========== 日志优化 ==========
# 批量日志写入
declare -g -a LOG_BUFFER=()
declare -g LOG_BUFFER_SIZE=50
buffered_log() {
local level="$1"
local message="$2"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
LOG_BUFFER+=("[$timestamp] [$level] $message")
if [[ ${#LOG_BUFFER[@]} -ge $LOG_BUFFER_SIZE ]]; then
flush_log_buffer
fi
}
flush_log_buffer() {
if [[ ${#LOG_BUFFER[@]} -eq 0 ]]; then
return 0
fi
local log_file="${LOG_FILE:-/tmp/s-hy2.log}"
# 批量写入日志
printf '%s\n' "${LOG_BUFFER[@]}" >> "$log_file"
# 清空缓冲区
LOG_BUFFER=()
}
# ========== 清理和维护 ==========
# 性能统计
get_performance_stats() {
cat << EOF
性能缓存统计:
- 缓存条目数: ${#PERFORMANCE_CACHE[@]}
- 批处理队列长度: ${#BATCH_COMMANDS[@]}
- 日志缓冲区大小: ${#LOG_BUFFER[@]}
- 缓存TTL: ${CACHE_TTL}秒
系统资源:
- CPU核心数: $(get_system_info_cached "cpu_count")
- 内存总量: $(get_system_info_cached "memory_total")MB
- 可用磁盘空间: $(get_system_info_cached "disk_space")
EOF
}
# 清理所有缓存和缓冲区
cleanup_performance() {
flush_batch
flush_log_buffer
cleanup_cache
PERFORMANCE_CACHE=()
CACHE_TIMESTAMPS=()
BATCH_COMMANDS=()
LOG_BUFFER=()
}
# 设置性能参数
set_performance_config() {
local cache_ttl="${1:-300}"
local batch_size="${2:-10}"
local log_buffer_size="${3:-50}"
CACHE_TTL="$cache_ttl"
BATCH_SIZE="$batch_size"
LOG_BUFFER_SIZE="$log_buffer_size"
}
# 退出时清理
trap cleanup_performance EXIT