Add intelligent server-wide PHP optimization (option 5)
NEW FEATURE: Optimize Server-Wide PHP Settings
This implements the missing menu option 5 with intelligent, RAM-aware optimization
that analyzes the ENTIRE server before making any changes.
INTELLIGENT OPTIMIZATION PROCESS:
Step 1: Server Memory Capacity Analysis
- Calculates total RAM vs current max capacity across all pools
- Shows status: HEALTHY, CAUTION, WARNING, or CRITICAL
- Identifies if server is at risk of OOM
Step 2: Balanced Memory Allocation
- Uses calculate_balanced_memory_allocation() from php-analyzer.sh
- Distributes available RAM proportionally based on traffic
- Ensures total allocations never exceed physical RAM
- Accounts for system overhead (reserves 2GB or 20% of RAM)
Step 3: Smart Recommendations
- Shows BEFORE/AFTER values for each user
- Displays reason: REDUCE (prevent OOM), INCREASE (traffic demands), or OPTIMAL
- Requires explicit "yes" confirmation before applying
Step 4: Batch Optimization
- Applies pm.max_children settings for all users
- Tracks: OPcache disabled domains (manual intervention needed)
- Shows real-time progress per domain
- Automatic PHP-FPM reload after changes
FEATURES:
✓ Prevents OOM: Never allocates more RAM than physically available
✓ Traffic-aware: High-traffic sites get more resources
✓ Safe defaults: Minimum 5, maximum 200 processes per pool
✓ Progress tracking: Shows optimization status for each domain
✓ Summary report: Total optimized, skipped, detected issues
✓ Automatic restart: Reloads PHP-FPM services after changes
EXAMPLE OUTPUT:
Analyzing server capacity...
Total RAM: 16384MB
Current max capacity: 14200MB (86%)
Status: CAUTION - Approaching memory limits
Calculating balanced optimization...
user1: 50 → 35 (REDUCE - prevent OOM)
user2: 20 → 45 (INCREASE - traffic demands)
user3: 30 → 30 (OPTIMAL)
Apply these balanced optimizations? (yes/no): yes
[1] Processing: example.com [user1]
✓ Optimized (1 changes): max_children: 50→35
OPTIMIZATION SUMMARY
Total domains processed: 25
Optimized: 18
Skipped (healthy): 7
Changes applied:
• max_children: 18 domains
• opcache_needs_enable: 5 domains
This commit is contained in:
@@ -567,6 +567,243 @@ optimize_domain() {
|
|||||||
read -p "Press Enter to continue..."
|
read -p "Press Enter to continue..."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# OPTIMIZE ALL DOMAINS (SERVER-WIDE)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
optimize_all_domains() {
|
||||||
|
show_banner
|
||||||
|
cecho "${WHITE}${BOLD}SERVER-WIDE OPTIMIZATION${NC}"
|
||||||
|
echo ""
|
||||||
|
cecho "${YELLOW}This will analyze and optimize PHP settings for ALL domains on the server.${NC}"
|
||||||
|
echo ""
|
||||||
|
cecho "${CYAN}What will be optimized:${NC}"
|
||||||
|
cecho " • pm.max_children (based on memory analysis)"
|
||||||
|
cecho " • OPcache settings (enable if disabled)"
|
||||||
|
echo ""
|
||||||
|
cecho "${RED}${BOLD}WARNING:${NC} ${RED}This will modify PHP-FPM pool configurations server-wide!${NC}"
|
||||||
|
echo ""
|
||||||
|
read -p "Continue with server-wide optimization? (yes/no): " confirm
|
||||||
|
|
||||||
|
if [ "$confirm" != "yes" ]; then
|
||||||
|
cecho "${YELLOW}Operation cancelled${NC}"
|
||||||
|
read -p "Press Enter to continue..."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
show_banner
|
||||||
|
cecho "${WHITE}${BOLD}Analyzing server capacity...${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# First: Calculate server-wide memory capacity
|
||||||
|
cecho "${CYAN}Step 1: Checking server memory capacity...${NC}"
|
||||||
|
local capacity_result
|
||||||
|
capacity_result=$(calculate_server_memory_capacity 2>&1)
|
||||||
|
|
||||||
|
local total_required_mb total_ram_mb percentage status
|
||||||
|
total_required_mb=$(echo "$capacity_result" | head -1 | cut -d'|' -f1)
|
||||||
|
total_ram_mb=$(echo "$capacity_result" | head -1 | cut -d'|' -f2)
|
||||||
|
percentage=$(echo "$capacity_result" | head -1 | cut -d'|' -f3)
|
||||||
|
status=$(echo "$capacity_result" | head -1 | cut -d'|' -f4)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
cecho " Total RAM: ${WHITE}${total_ram_mb}MB${NC}"
|
||||||
|
cecho " Current max capacity: ${WHITE}${total_required_mb}MB${NC} (${percentage}%)"
|
||||||
|
|
||||||
|
case "$status" in
|
||||||
|
CRITICAL)
|
||||||
|
cecho " Status: ${RED}${BOLD}CRITICAL${NC} - Server may OOM if all pools hit max!"
|
||||||
|
;;
|
||||||
|
WARNING)
|
||||||
|
cecho " Status: ${YELLOW}${BOLD}WARNING${NC} - High memory pressure possible"
|
||||||
|
;;
|
||||||
|
CAUTION)
|
||||||
|
cecho " Status: ${YELLOW}CAUTION${NC} - Approaching memory limits"
|
||||||
|
;;
|
||||||
|
HEALTHY)
|
||||||
|
cecho " Status: ${GREEN}HEALTHY${NC} - Sufficient headroom"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
cecho "${CYAN}Step 2: Calculating balanced optimization...${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Get balanced recommendations based on total RAM
|
||||||
|
local balanced_result
|
||||||
|
balanced_result=$(calculate_balanced_memory_allocation 2>&1)
|
||||||
|
|
||||||
|
# Parse recommendations (format: USER|CURRENT_MAX|AVG_MB|TRAFFIC_RPM|RECOMMENDED_MAX|ALLOCATED_MB|REASON)
|
||||||
|
declare -A recommended_values
|
||||||
|
while IFS='|' read -r username current_max avg_mb traffic_rpm recommended_max allocated_mb reason; do
|
||||||
|
[ "$username" = "USER" ] && continue # Skip header
|
||||||
|
[ -z "$username" ] && continue
|
||||||
|
recommended_values["$username"]="$recommended_max"
|
||||||
|
cecho " ${CYAN}$username${NC}: $current_max → $recommended_max (${reason})"
|
||||||
|
done <<< "$balanced_result"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -p "Apply these balanced optimizations? (yes/no): " apply_confirm
|
||||||
|
|
||||||
|
if [ "$apply_confirm" != "yes" ]; then
|
||||||
|
cecho "${YELLOW}Optimization cancelled${NC}"
|
||||||
|
read -p "Press Enter to continue..."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
show_banner
|
||||||
|
cecho "${WHITE}${BOLD}Applying optimizations...${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Get all users
|
||||||
|
local users
|
||||||
|
users=$(list_all_users)
|
||||||
|
|
||||||
|
if [ -z "$users" ]; then
|
||||||
|
cecho "${RED}ERROR: No users found on system${NC}"
|
||||||
|
read -p "Press Enter to continue..."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Statistics tracking
|
||||||
|
local total_domains=0
|
||||||
|
local optimized_count=0
|
||||||
|
local skipped_count=0
|
||||||
|
declare -A optimization_summary
|
||||||
|
|
||||||
|
# Process each user
|
||||||
|
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
|
||||||
|
|
||||||
|
total_domains=$((total_domains + 1))
|
||||||
|
|
||||||
|
cecho "${CYAN}[$total_domains] Processing: ${WHITE}$domain${NC} ${CYAN}[$username]${NC}"
|
||||||
|
|
||||||
|
# Detect issues first
|
||||||
|
local issues
|
||||||
|
issues=$(detect_php_config_issues "$username" "$domain")
|
||||||
|
|
||||||
|
# Count critical/high issues
|
||||||
|
local critical_high_count
|
||||||
|
critical_high_count=$(echo "$issues" | grep -cE "^[^|]*\|(CRITICAL|HIGH)\|" || true)
|
||||||
|
|
||||||
|
if [ "$critical_high_count" -eq 0 ]; then
|
||||||
|
cecho " ${GREEN}✓${NC} No optimization needed - domain is healthy"
|
||||||
|
skipped_count=$((skipped_count + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use balanced recommendation from server-wide analysis
|
||||||
|
local recommended_max_children
|
||||||
|
recommended_max_children="${recommended_values[$username]}"
|
||||||
|
|
||||||
|
# If no recommendation found, skip
|
||||||
|
if [ -z "$recommended_max_children" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get current pool config
|
||||||
|
local pool_config
|
||||||
|
pool_config=$(find_fpm_pool_config "$username")
|
||||||
|
|
||||||
|
if [ -z "$pool_config" ] || [ ! -f "$pool_config" ]; then
|
||||||
|
cecho " ${YELLOW}⊘${NC} No FPM pool config found - skipping"
|
||||||
|
skipped_count=$((skipped_count + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get current max_children
|
||||||
|
local current_max_children
|
||||||
|
current_max_children=$(grep "^pm.max_children" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
||||||
|
|
||||||
|
# Apply optimizations
|
||||||
|
local changes_made=0
|
||||||
|
local changes_list=""
|
||||||
|
|
||||||
|
# Optimization 1: Adjust max_children if needed
|
||||||
|
if [ -n "$recommended_max_children" ] && [ -n "$current_max_children" ] && [ "$recommended_max_children" -ne "$current_max_children" ]; then
|
||||||
|
if modify_fpm_pool_setting "$pool_config" "pm.max_children" "$recommended_max_children" >/dev/null 2>&1; then
|
||||||
|
changes_made=$((changes_made + 1))
|
||||||
|
changes_list+="max_children: $current_max_children→$recommended_max_children, "
|
||||||
|
optimization_summary["max_children"]=$((${optimization_summary["max_children"]:-0} + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Optimization 2: Enable OPcache if disabled
|
||||||
|
local opcache_enabled
|
||||||
|
opcache_enabled=$(check_opcache_enabled "$username")
|
||||||
|
if [ "$opcache_enabled" = "0" ]; then
|
||||||
|
# OPcache is disabled - mark for enabling (note: requires php.ini edit, not implemented yet)
|
||||||
|
changes_list+="OPcache: needs_enable, "
|
||||||
|
optimization_summary["opcache_needs_enable"]=$((${optimization_summary["opcache_needs_enable"]:-0} + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove trailing comma
|
||||||
|
changes_list=${changes_list%, }
|
||||||
|
|
||||||
|
if [ "$changes_made" -gt 0 ]; then
|
||||||
|
cecho " ${GREEN}✓${NC} Optimized ($changes_made changes): $changes_list"
|
||||||
|
optimized_count=$((optimized_count + 1))
|
||||||
|
else
|
||||||
|
if [ -n "$changes_list" ]; then
|
||||||
|
cecho " ${YELLOW}⊙${NC} Detected: $changes_list (manual intervention needed)"
|
||||||
|
skipped_count=$((skipped_count + 1))
|
||||||
|
else
|
||||||
|
cecho " ${YELLOW}⊘${NC} No changes applied"
|
||||||
|
skipped_count=$((skipped_count + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
done <<< "$user_domains"
|
||||||
|
done <<< "$users"
|
||||||
|
|
||||||
|
# Restart PHP-FPM services if changes were made
|
||||||
|
if [ "$optimized_count" -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
cecho "${CYAN}Restarting PHP-FPM services...${NC}"
|
||||||
|
|
||||||
|
# Get all PHP versions
|
||||||
|
local php_versions
|
||||||
|
php_versions=$(detect_installed_php_versions)
|
||||||
|
|
||||||
|
while IFS= read -r php_version; do
|
||||||
|
[ -z "$php_version" ] && continue
|
||||||
|
if reload_php_fpm "$php_version" >/dev/null 2>&1; then
|
||||||
|
cecho " ${GREEN}✓${NC} Reloaded $php_version"
|
||||||
|
fi
|
||||||
|
done <<< "$php_versions"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Display summary
|
||||||
|
echo ""
|
||||||
|
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||||
|
cecho "${WHITE}${BOLD}OPTIMIZATION SUMMARY${NC}"
|
||||||
|
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||||
|
echo ""
|
||||||
|
cecho " Total domains processed: ${WHITE}$total_domains${NC}"
|
||||||
|
cecho " ${GREEN}Optimized: $optimized_count${NC}"
|
||||||
|
cecho " ${YELLOW}Skipped (healthy): $skipped_count${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ ${#optimization_summary[@]} -gt 0 ]; then
|
||||||
|
cecho "${WHITE}Changes applied:${NC}"
|
||||||
|
for key in "${!optimization_summary[@]}"; do
|
||||||
|
cecho " • $key: ${optimization_summary[$key]} domains"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||||
|
echo ""
|
||||||
|
read -p "Press Enter to continue..."
|
||||||
|
}
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# OPTION 6: VIEW OPCACHE STATISTICS
|
# OPTION 6: VIEW OPCACHE STATISTICS
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -1178,8 +1415,7 @@ main() {
|
|||||||
optimize_domain
|
optimize_domain
|
||||||
;;
|
;;
|
||||||
5)
|
5)
|
||||||
cecho "${YELLOW}Server-wide optimization not yet implemented${NC}"
|
optimize_all_domains
|
||||||
sleep 2
|
|
||||||
;;
|
;;
|
||||||
6)
|
6)
|
||||||
view_opcache_stats
|
view_opcache_stats
|
||||||
|
|||||||
Reference in New Issue
Block a user