Complete profile-based PHP-FPM optimization system with real usage data

Implement data-driven optimization using actual server metrics instead of thresholds:

NEW FEATURES:
- lib/php-analytics.sh: Analytics engine for domain profiling
  • analyze_memory_errors_from_logs: Parse error logs for memory exhaustion
  • analyze_process_memory_usage: Measure actual PHP process memory via ps
  • get_peak_concurrent_detailed: Extract peak concurrent requests from access logs
  • detect_memory_leak_pattern: Identify domains with memory leak issues
  • build_domain_profile: Complete profile with all real usage data
  • Intelligent recommendations based on ACTUAL peak memory, traffic, and leak patterns

- modules/performance/php-domain-analyzer.sh: Pre-analysis script
  • Scans all domains and builds comprehensive profiles
  • Stores profiles in /tmp/php-domain-profiles/ for use by optimizer
  • Shows summary with top memory users, traffic patterns, and potential leaks
  • Displays analysis in real-time with progress indicators

- php-optimizer.sh: Profile-based optimization levels
  • Option 0: Run pre-analysis to collect real usage data
  • Levels 1-5: Now use profile-based recommendations (fallback to traffic-based if no profiles)
  • Shows real usage data from profiles when optimizations applied
  • Memory recommendations: peak_memory_seen + 20% buffer
  • Max children: peak_concurrent_requests + 30% safety margin
  • Max requests: 250 for leak-prone domains, 500 for normal domains

ARCHITECTURE:
- Profile format (pipe-delimited): domain|username|peak_concurrent|avg_concurrent|
  total_hits|min_mem|max_mem|avg_mem|proc_count|mem_exhausted|peak_mem_seen|
  leak_type|current_memory_limit|current_max_children
- Profiles cached in /tmp/php-domain-profiles/ (24 hour TTL)
- All 5 optimization levels now profile-aware
- Seamless fallback to traffic-based method if no profiles exist

CONVERSION COMPLETED:
- Level 1: Optimizes pm.max_children only (profile-aware)
- Level 2: pm.max_children + memory_limit (profile-aware)
- Level 3: All of above + pm.max_requests for leak prevention (profile-aware)
- Level 4: OPcache optimization (unchanged)
- Level 5: Complete optimization with all settings (NOW PROFILE-AWARE - FIXED)

All levels now enumeraate users/domains directly and use profile recommendations
when available, with intelligent fallback to the original traffic-based method.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
cschantz
2026-02-18 19:40:01 -05:00
parent 7a68086bf1
commit 4d745f203e
3 changed files with 944 additions and 89 deletions
+408 -89
View File
@@ -19,6 +19,9 @@ source "$PHP_TOOLKIT_DIR/lib/php-scanner.sh" 2>/dev/null || true
source "$PHP_TOOLKIT_DIR/lib/php-action-executor.sh" 2>/dev/null || true
source "$PHP_TOOLKIT_DIR/lib/php-server-manager.sh" 2>/dev/null || true
# True Optimization - Analytics Library for real data-driven decisions
source "$PHP_TOOLKIT_DIR/lib/php-analytics.sh" 2>/dev/null || true
# Color codes (using safe echo -e)
RED='\033[0;31m'
GREEN='\033[0;32m'
@@ -1263,6 +1266,158 @@ rollback_php_ini() {
return 1
}
# ============================================================================
# RUN DOMAIN ANALYZER - Collect real usage data
# ============================================================================
run_domain_analyzer() {
show_banner
cecho "${WHITE}${BOLD}DOMAIN PRE-ANALYSIS${NC}"
echo ""
cecho "${YELLOW}This will analyze real usage data from your domains.${NC}"
echo ""
cecho "${CYAN}This process will:${NC}"
cecho " • Scan error logs for memory exhaustion patterns"
cecho " • Analyze current process memory usage"
cecho " • Parse traffic logs for peak concurrent requests"
cecho " • Detect potential memory leaks"
cecho " • Build accurate domain profiles"
echo ""
if ! confirm "Continue with domain analysis?"; then
cecho "${YELLOW}Analysis cancelled${NC}"
read -p "Press Enter to continue..."
return
fi
# Check if php-domain-analyzer.sh exists
local analyzer_script="/root/server-toolkit/modules/performance/php-domain-analyzer.sh"
if [ ! -f "$analyzer_script" ]; then
cecho "${RED}ERROR: Domain analyzer script not found${NC}"
cecho "${YELLOW}Expected: $analyzer_script${NC}"
read -p "Press Enter to continue..."
return
fi
# Run the analyzer
bash "$analyzer_script"
echo ""
cecho "${GREEN}${BOLD}✓ Domain analysis complete!${NC}"
cecho "${YELLOW}Profiles are ready for optimization.${NC}"
echo ""
read -p "Press Enter to continue..."
}
# ============================================================================
# PROFILE-BASED OPTIMIZATION FUNCTIONS (True Optimization)
# ============================================================================
# Get recommendation for memory_limit using actual usage data
get_memory_limit_recommendation() {
local domain="$1"
local username="$2"
# Try to get from stored profile first (real data)
if [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
local profile
profile=$(cat "/tmp/php-domain-profiles/$domain.profile")
# Calculate based on ACTUAL memory seen in logs
local peak_mem_seen=$(echo "$profile" | cut -d'|' -f11)
if [ "$peak_mem_seen" -gt 0 ]; then
# Use observed peak + 20% buffer
local recommended=$((peak_mem_seen + (peak_mem_seen / 5)))
[ "$recommended" -gt 1024 ] && recommended=1024
[ "$recommended" -lt 64 ] && recommended=64
echo "${recommended}M"
return 0
fi
fi
# Fallback to old method if no profile
calculate_optimal_memory_limit "$username" "$domain" "50"
}
# Get recommendation for max_children using actual traffic data
get_max_children_recommendation() {
local domain="$1"
local username="$2"
# Try to get from stored profile first (real traffic data)
if [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
local profile
profile=$(cat "/tmp/php-domain-profiles/$domain.profile")
# Use ACTUAL peak concurrent from logs
local peak_concurrent=$(echo "$profile" | cut -d'|' -f3)
if [ "$peak_concurrent" -gt 0 ]; then
# Add 30% safety margin for spikes
local recommended=$((peak_concurrent + (peak_concurrent / 3)))
[ "$recommended" -gt 100 ] && recommended=100
[ "$recommended" -lt 5 ] && recommended=5
echo "$recommended"
return 0
fi
fi
# Fallback to old method
calculate_optimal_max_requests "50"
}
# Get recommendation for max_requests using memory leak analysis
get_max_requests_recommendation() {
local domain="$1"
# Try to get from stored profile first
if [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
local profile
profile=$(cat "/tmp/php-domain-profiles/$domain.profile")
# Check for memory leak pattern
local leak_type=$(echo "$profile" | cut -d'|' -f12)
if [ "$leak_type" = "LIKELY_LEAK" ]; then
echo "250" # Recycle frequently for leak-prone domains
return 0
fi
fi
# Default
echo "500"
}
# Display profile data if available
show_profile_analysis() {
local domain="$1"
[ ! -f "/tmp/php-domain-profiles/$domain.profile" ] && return
local profile
profile=$(cat "/tmp/php-domain-profiles/$domain.profile")
local peak_concurrent=$(echo "$profile" | cut -d'|' -f3)
local avg_concurrent=$(echo "$profile" | cut -d'|' -f4)
local min_mem=$(echo "$profile" | cut -d'|' -f6)
local max_mem=$(echo "$profile" | cut -d'|' -f7)
local avg_mem=$(echo "$profile" | cut -d'|' -f8)
local mem_exhausted=$(echo "$profile" | cut -d'|' -f10)
local peak_mem=$(echo "$profile" | cut -d'|' -f11)
local leak_status=$(echo "$profile" | cut -d'|' -f12)
cecho "${CYAN}REAL USAGE DATA (from profile analysis):${NC}"
cecho " Peak Concurrent: ${WHITE}${peak_concurrent}${NC} | Avg: ${avg_concurrent}"
cecho " Process Memory: ${WHITE}${min_mem}MB${NC}-${max_mem}MB (avg: ${avg_mem}MB)"
if [ "$mem_exhausted" -gt 0 ]; then
cecho " Memory Exhaustion Errors: ${RED}${mem_exhausted}${NC}"
fi
cecho " Peak Memory Seen: ${WHITE}${peak_mem}MB${NC}"
cecho " Memory Status: ${leak_status}"
echo ""
}
# ============================================================================
# OPTIMIZE ALL DOMAINS (SERVER-WIDE) - TIERED OPTIMIZATION
# ============================================================================
@@ -1275,6 +1430,11 @@ optimize_all_domains() {
cecho "${YELLOW}Choose optimization level for all domains on the server${NC}"
echo ""
cecho "${CYAN}PRE-ANALYSIS (Recommended for accurate optimization):${NC}"
cecho " ${GREEN}0${NC}) Pre-analyze domains"
cecho " └─ Collect real usage data for data-driven optimization"
echo ""
cecho "${CYAN}OPTIMIZATION LEVELS:${NC}"
cecho " ${GREEN}1${NC}) Optimize pm.max_children only"
cecho " └─ Adjust process limits based on traffic"
@@ -1297,18 +1457,21 @@ optimize_all_domains() {
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
while true; do
read -p "Select optimization level (1-5, b, or q): " opt_choice
read -p "Select option (0-5, b, or q): " opt_choice
opt_choice=${opt_choice,,}
if [[ "$opt_choice" =~ ^[1-5bq]$ ]]; then
if [[ "$opt_choice" =~ ^[0-5bq]$ ]]; then
break
fi
echo ""
cecho "${RED}Invalid choice. Please enter 1-5, b, or q${NC}"
cecho "${RED}Invalid choice. Please enter 0-5, b, or q${NC}"
echo ""
done
case "$opt_choice" in
0)
run_domain_analyzer
;;
1)
optimize_level_1_max_children
;;
@@ -1377,40 +1540,72 @@ optimize_level_1_max_children() {
cecho " Status: ${WHITE}${status}${NC}"
echo ""
# Check if profiles exist
local profiles_exist=0
if [ -d "/tmp/php-domain-profiles" ] && [ "$(ls -1 /tmp/php-domain-profiles/*.profile 2>/dev/null | wc -l)" -gt 0 ]; then
profiles_exist=1
cecho "${GREEN}${BOLD}✓ Domain profiles detected!${NC}"
cecho "${YELLOW}Using REAL usage data from domain analysis${NC}"
echo ""
fi
# Get recommendations
cecho "${CYAN}Step 2: Calculating optimal settings...${NC}"
echo ""
local balanced_result
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
balanced_result=$(calculate_balanced_memory_allocation_per_domain)
else
balanced_result=$(calculate_balanced_memory_allocation)
fi
declare -A recommended_values
declare -A domain_to_username
local changes_needed=0
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
while IFS='|' read -r domain username php_ver current_max avg_mb traffic_rpm recommended_max allocated_mb reason; do
[ "$domain" = "DOMAIN" ] && continue
# Get all users and domains
local users
users=$(list_all_users)
while IFS= read -r username; do
[ -z "$username" ] && continue
local user_domains
user_domains=$(get_user_domains "$username")
while IFS= read -r domain; do
[ -z "$domain" ] && continue
local current_max
local pool_config
pool_config=$(find_fpm_pool_config "$username" "$domain" 2>/dev/null)
if [ -n "$pool_config" ] && [ -f "$pool_config" ]; then
current_max=$(grep "^pm.max_children" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
[ -z "$current_max" ] && current_max="?"
else
current_max="?"
fi
# Get recommendations - use profile if available, otherwise use traffic-based
local recommended_max
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
recommended_max=$(get_max_children_recommendation "$domain" "$username")
else
# Fallback to traffic-based (old method)
local traffic_rpm
traffic_rpm=$(get_domain_peak_concurrent "$domain" 2>/dev/null || echo "0")
[ "$traffic_rpm" = "?" ] && traffic_rpm="0"
recommended_max=$((traffic_rpm > 5 ? traffic_rpm + 10 : 5))
fi
recommended_values["$domain"]="$recommended_max"
domain_to_username["$domain"]="$username"
if [ "$current_max" != "$recommended_max" ]; then
if [ "$current_max" != "?" ] && [ "$current_max" != "$recommended_max" ]; then
changes_needed=$((changes_needed + 1))
if [[ "$reason" == *"REDUCE"* ]]; then
cecho " ${YELLOW}${NC} $domain: $current_max${YELLOW}$recommended_max${NC} (REDUCE)"
elif [[ "$reason" == *"INCREASE"* ]]; then
cecho " ${GREEN}${NC} $domain: $current_max${GREEN}$recommended_max${NC} (INCREASE)"
else
cecho " ${CYAN}$domain${NC}: $current_max$recommended_max"
cecho " ${GREEN}${NC} $domain: $current_max${GREEN}$recommended_max${NC}"
# Show profile data if available
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
show_profile_analysis "$domain"
fi
fi
done <<< "$balanced_result"
fi
done <<< "$user_domains"
done <<< "$users"
echo ""
if [ "$changes_needed" -eq 0 ]; then
@@ -1514,7 +1709,7 @@ optimize_level_2_memory() {
cecho "${YELLOW}This will adjust both process limits and PHP memory settings.${NC}"
echo ""
cecho "${CYAN}What will be optimized:${NC}"
cecho " • pm.max_children (based on traffic)"
cecho " • pm.max_children (based on real traffic data if available)"
cecho " • memory_limit (PHP memory per domain)"
echo ""
cecho "${RED}${BOLD}WARNING:${NC} ${RED}This will modify PHP-FPM and php.ini configurations!${NC}"
@@ -1543,44 +1738,92 @@ optimize_level_2_memory() {
cecho " Status: ${WHITE}${status}${NC}"
echo ""
# Check if profiles exist
local profiles_exist=0
if [ -d "/tmp/php-domain-profiles" ] && [ "$(ls -1 /tmp/php-domain-profiles/*.profile 2>/dev/null | wc -l)" -gt 0 ]; then
profiles_exist=1
cecho "${GREEN}${BOLD}✓ Domain profiles detected!${NC}"
cecho "${YELLOW}Using REAL usage data from domain analysis${NC}"
echo ""
else
cecho "${YELLOW}${BOLD}⚠ No domain profiles found${NC}"
cecho "${CYAN}For more accurate optimization, run pre-analysis first:${NC}"
cecho " ${WHITE}php-optimizer.sh${NC} → Option 3 (Pre-analyze domains)"
echo ""
fi
# Get recommendations
cecho "${CYAN}Step 2: Calculating optimal settings...${NC}"
echo ""
local balanced_result
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
balanced_result=$(calculate_balanced_memory_allocation_per_domain)
else
balanced_result=$(calculate_balanced_memory_allocation)
fi
declare -A recommended_max_children
declare -A recommended_memory_limit
declare -A domain_to_username
local changes_needed=0
# Parse balanced result and show recommendations
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
while IFS='|' read -r domain username php_ver current_max avg_mb traffic_rpm recommended_max allocated_mb reason; do
[ "$domain" = "DOMAIN" ] && continue
# Get all users and domains
local users
users=$(list_all_users)
while IFS= read -r username; do
[ -z "$username" ] && continue
local user_domains
user_domains=$(get_user_domains "$username")
while IFS= read -r domain; do
[ -z "$domain" ] && continue
local current_max
local pool_config
pool_config=$(find_fpm_pool_config "$username" "$domain" 2>/dev/null)
if [ -n "$pool_config" ] && [ -f "$pool_config" ]; then
current_max=$(grep "^pm.max_children" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
[ -z "$current_max" ] && current_max="?"
else
current_max="?"
fi
# Get recommendations - use profile if available, otherwise use traffic-based
local recommended_max
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
recommended_max=$(get_max_children_recommendation "$domain" "$username")
else
# Fallback to traffic-based (old method)
local traffic_rpm
traffic_rpm=$(get_domain_peak_concurrent "$domain" 2>/dev/null || echo "0")
[ "$traffic_rpm" = "?" ] && traffic_rpm="0"
recommended_max=$((traffic_rpm > 5 ? traffic_rpm + 10 : 5))
fi
local recommended_memory
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
recommended_memory=$(get_memory_limit_recommendation "$domain" "$username")
else
# Fallback to traffic-based (old method)
local traffic_rpm
traffic_rpm=$(get_domain_peak_concurrent "$domain" 2>/dev/null || echo "0")
[ "$traffic_rpm" = "?" ] && traffic_rpm="0"
recommended_memory=$(calculate_optimal_memory_limit "$username" "$domain" "$traffic_rpm")
fi
recommended_max_children["$domain"]="$recommended_max"
recommended_memory_limit["$domain"]="$recommended_memory"
domain_to_username["$domain"]="$username"
# Calculate optimal memory_limit based on traffic
local optimal_memory
optimal_memory=$(calculate_optimal_memory_limit "$username" "$domain" "$traffic_rpm")
recommended_memory_limit["$domain"]="$optimal_memory"
if [ "$current_max" != "$recommended_max" ]; then
if [ "$current_max" != "?" ] && [ "$current_max" != "$recommended_max" ]; then
changes_needed=$((changes_needed + 1))
cecho " ${GREEN}${NC} $domain:"
cecho " pm.max_children: $current_max${GREEN}$recommended_max${NC}"
cecho " memory_limit: → ${GREEN}$optimal_memory${NC}"
cecho " memory_limit: → ${GREEN}$recommended_memory${NC}"
# Show profile data if available
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
show_profile_analysis "$domain"
fi
fi
done <<< "$balanced_result"
fi
done <<< "$user_domains"
done <<< "$users"
echo ""
if [ "$changes_needed" -eq 0 ]; then
@@ -1749,51 +1992,87 @@ optimize_level_3_advanced() {
cecho " Status: ${WHITE}${status}${NC}"
echo ""
# Check if profiles exist
local profiles_exist=0
if [ -d "/tmp/php-domain-profiles" ] && [ "$(ls -1 /tmp/php-domain-profiles/*.profile 2>/dev/null | wc -l)" -gt 0 ]; then
profiles_exist=1
cecho "${GREEN}${BOLD}✓ Domain profiles detected!${NC}"
cecho "${YELLOW}Using REAL usage data and memory leak detection${NC}"
echo ""
fi
# Get recommendations
cecho "${CYAN}Step 2: Calculating optimal settings...${NC}"
echo ""
local balanced_result
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
balanced_result=$(calculate_balanced_memory_allocation_per_domain)
else
balanced_result=$(calculate_balanced_memory_allocation)
fi
declare -A recommended_max_children
declare -A recommended_memory_limit
declare -A recommended_max_requests
declare -A domain_to_username
local changes_needed=0
# Parse balanced result
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
while IFS='|' read -r domain username php_ver current_max avg_mb traffic_rpm recommended_max allocated_mb reason; do
[ "$domain" = "DOMAIN" ] && continue
# Get all users and domains
local users
users=$(list_all_users)
while IFS= read -r username; do
[ -z "$username" ] && continue
local user_domains
user_domains=$(get_user_domains "$username")
while IFS= read -r domain; do
[ -z "$domain" ] && continue
recommended_max_children["$domain"]="$recommended_max"
recommended_max_children["$domain"]=0
recommended_memory_limit["$domain"]=0
recommended_max_requests["$domain"]=0
domain_to_username["$domain"]="$username"
# Calculate optimal memory_limit
local optimal_memory
optimal_memory=$(calculate_optimal_memory_limit "$username" "$domain" "$traffic_rpm")
recommended_memory_limit["$domain"]="$optimal_memory"
# Use profile-based if available
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
recommended_max_children["$domain"]=$(get_max_children_recommendation "$domain" "$username")
recommended_memory_limit["$domain"]=$(get_memory_limit_recommendation "$domain" "$username")
recommended_max_requests["$domain"]=$(get_max_requests_recommendation "$domain")
else
# Fallback to traffic-based (old method)
local traffic_rpm
traffic_rpm=$(get_domain_peak_concurrent "$domain" 2>/dev/null || echo "0")
[ "$traffic_rpm" = "?" ] && traffic_rpm="0"
# Calculate optimal max_requests
local optimal_requests
optimal_requests=$(calculate_optimal_max_requests "$traffic_rpm")
recommended_max_requests["$domain"]="$optimal_requests"
recommended_max_children["$domain"]=$((traffic_rpm > 5 ? traffic_rpm + 10 : 5))
recommended_memory_limit["$domain"]=$(calculate_optimal_memory_limit "$username" "$domain" "$traffic_rpm")
recommended_max_requests["$domain"]=$(calculate_optimal_max_requests "$traffic_rpm")
fi
if [ "$current_max" != "$recommended_max" ]; then
local current_max
local pool_config
pool_config=$(find_fpm_pool_config "$username" "$domain" 2>/dev/null)
if [ -n "$pool_config" ] && [ -f "$pool_config" ]; then
current_max=$(grep "^pm.max_children" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
[ -z "$current_max" ] && current_max="?"
else
current_max="?"
fi
local rec_max_children=${recommended_max_children["$domain"]}
local rec_memory=${recommended_memory_limit["$domain"]}
local rec_requests=${recommended_max_requests["$domain"]}
if [ "$current_max" != "?" ] && [ "$current_max" != "$rec_max_children" ]; then
changes_needed=$((changes_needed + 1))
cecho " ${GREEN}${NC} $domain:"
cecho " pm.max_children: $current_max${GREEN}$recommended_max${NC}"
cecho " memory_limit: → ${GREEN}$optimal_memory${NC}"
cecho " pm.max_requests: → ${GREEN}$optimal_requests${NC} (prevent memory leaks)"
cecho " pm.max_children: $current_max${GREEN}$rec_max_children${NC}"
cecho " memory_limit: → ${GREEN}$rec_memory${NC}"
cecho " pm.max_requests: → ${GREEN}$rec_requests${NC} (prevent memory leaks)"
# Show profile data if available
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
show_profile_analysis "$domain"
fi
fi
done <<< "$balanced_result"
fi
done <<< "$user_domains"
done <<< "$users"
echo ""
if [ "$changes_needed" -eq 0 ]; then
@@ -2158,11 +2437,13 @@ optimize_level_5_everything() {
cecho "${CYAN}STEP 2: Calculating Recommendations${NC}"
echo ""
local balanced_result
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
balanced_result=$(calculate_balanced_memory_allocation_per_domain)
else
balanced_result=$(calculate_balanced_memory_allocation)
# Check if profiles exist
local profiles_exist=0
if [ -d "/tmp/php-domain-profiles" ] && [ "$(ls -1 /tmp/php-domain-profiles/*.profile 2>/dev/null | wc -l)" -gt 0 ]; then
profiles_exist=1
cecho "${GREEN}${BOLD}✓ Domain profiles detected!${NC}"
cecho "${YELLOW}Using REAL usage data for comprehensive optimization${NC}"
echo ""
fi
declare -A recommended_max_children
@@ -2173,23 +2454,55 @@ optimize_level_5_everything() {
local changes_count=0
local opcache_count=0
if [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
while IFS='|' read -r domain username php_ver current_max avg_mb traffic_rpm recommended_max allocated_mb reason; do
[ "$domain" = "DOMAIN" ] && continue
# Get all users and domains
local users
users=$(list_all_users)
while IFS= read -r username; do
[ -z "$username" ] && continue
local user_domains
user_domains=$(get_user_domains "$username")
while IFS= read -r domain; do
[ -z "$domain" ] && continue
local current_max
local pool_config
pool_config=$(find_fpm_pool_config "$username" "$domain" 2>/dev/null)
if [ -n "$pool_config" ] && [ -f "$pool_config" ]; then
current_max=$(grep "^pm.max_children" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
[ -z "$current_max" ] && current_max="?"
else
current_max="?"
fi
# Get recommendations - use profile if available, otherwise use traffic-based
local recommended_max
local recommended_memory
local recommended_requests
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
recommended_max=$(get_max_children_recommendation "$domain" "$username")
recommended_memory=$(get_memory_limit_recommendation "$domain" "$username")
recommended_requests=$(get_max_requests_recommendation "$domain")
else
# Fallback to traffic-based (old method)
local traffic_rpm
traffic_rpm=$(get_domain_peak_concurrent "$domain" 2>/dev/null || echo "0")
[ "$traffic_rpm" = "?" ] && traffic_rpm="0"
recommended_max=$((traffic_rpm > 5 ? traffic_rpm + 10 : 5))
recommended_memory=$(calculate_optimal_memory_limit "$username" "$domain" "$traffic_rpm")
recommended_requests=$(calculate_optimal_max_requests "$traffic_rpm")
fi
recommended_max_children["$domain"]="$recommended_max"
recommended_memory_limit["$domain"]="$recommended_memory"
recommended_max_requests["$domain"]="$recommended_requests"
domain_to_username["$domain"]="$username"
local optimal_memory
optimal_memory=$(calculate_optimal_memory_limit "$username" "$domain" "$traffic_rpm")
recommended_memory_limit["$domain"]="$optimal_memory"
local optimal_requests
optimal_requests=$(calculate_optimal_max_requests "$traffic_rpm")
recommended_max_requests["$domain"]="$optimal_requests"
if [ "$current_max" != "$recommended_max" ]; then
if [ "$current_max" != "?" ] && [ "$current_max" != "$recommended_max" ]; then
changes_count=$((changes_count + 1))
fi
@@ -2197,8 +2510,8 @@ optimize_level_5_everything() {
opcache_needs_enable["$domain"]="1"
opcache_count=$((opcache_count + 1))
fi
done <<< "$balanced_result"
fi
done <<< "$user_domains"
done <<< "$users"
cecho " Domains needing updates: ${YELLOW}${changes_count}${NC}"
cecho " Domains needing OPcache: ${YELLOW}${opcache_count}${NC}"
@@ -2254,7 +2567,13 @@ optimize_level_5_everything() {
if [ "$pool_updated" -gt 0 ]; then
cecho " ${GREEN}${NC} $domain: FPM settings optimized"
cecho " pm.max_children: ${recommended_max} | pm.max_requests: ${recommended_requests}"
optimized=$((optimized + 1))
# Show profile data if available
if [ "$profiles_exist" = "1" ] && [ -f "/tmp/php-domain-profiles/$domain.profile" ]; then
show_profile_analysis "$domain"
fi
fi
fi
@@ -2285,7 +2604,7 @@ optimize_level_5_everything() {
modify_php_ini_setting "$ini_file" "opcache.memory_consumption" "$optimal_opcache_mem" >/dev/null 2>&1
if validate_php_ini "$ini_file" >/dev/null 2>&1; then
cecho " ${GREEN}${NC} $domain: OPcache enabled"
cecho " ${GREEN}${NC} $domain: OPcache enabled (${optimal_opcache_mem})"
opcache_enabled=$((opcache_enabled + 1))
fi
fi