JavaScript is disabled in your browser. Please enable it for the full experience.

A „Homokórázó” WordPress Admin Rejtélye: Hogyan nyomozd ki 3 lépésben a lassulást?

Ismerős a helyzet? A weboldal frontendje (főleg inkognitó ablakban) villámgyors, a PageSpeed zöldben, a látogatók boldogok. De amint…

⏳ 7 perc

Lőrincz András

Ismerős a helyzet? A weboldal frontendje (főleg inkognitó ablakban) villámgyors, a PageSpeed zöldben, a látogatók boldogok. De amint megpróbálsz belépni a wp-admin-ba, a rendszer megáll. 10 másodperc. 20 másodperc. Tölt, tölt, tölt… majd végül bejön (vagy timeoutol).

Cache nélkül az oldal használhatatlan. Ez történt nemrég egy ügyfélprojektnél. A hardver erős volt, a szoftver friss, mégis szenvedett a backend.

Így nyomoztam ki a hiba forrását három saját diagnosztikai scripttel, külső bloatware pluginok telepítése nélkül.

1. Lépés: Haldoklik a szerver? (CPU Diagnosztika)

Az első gyanúsított mindig az erőforrás-hiány. Ha egy végtelen ciklusba (infinite loop) ragadt PHP folyamat pörög a háttérben, az megeszi a CPU-t.

Hogy ezt ellenőrizzem anélkül, hogy SSH-t kéne nyitnom (vagy ha korlátozott a hozzáférés), írtam egy gyors PHP scriptet, ami lekérdezi a Linux processzlistát.

A script (Process Monitor): Ez a kód lefuttatja a ps vagy top parancsot PHP-ből, és kiírja a Top 20 CPU-zabáló folyamatot.

<?php
// FIGYELEM: Ezt csak diagnosztikára használd, utána töröld!
echo "<pre style='background:#000; color:#0f0; padding:20px;'>";
echo "<h1>FUTÓ FOLYAMATOK</h1>";

$output = null;
if (function_exists('shell_exec')) {
    // Linux PS parancs: CPU % szerint rendezve
    $output = shell_exec('ps aux --sort=-%cpu | head -n 20');
}

if (!$output) {
    // Fallback: top parancs
    $output = shell_exec('top -b -n 1 | head -n 20');
}

echo $output ? $output : "A shell_exec tiltva van.";
echo "</pre>";
?>

Az eredmény: Meglepetésre a CPU használat alacsony volt. A mysqld és a php-fpm folyamatok alig dolgoztak (1-2%).
Konklúzió: A szerver nem „dolgozik”, hanem vár. Valami blokkolja a futást (Blocking I/O).

2. Lépés: Adatbázis elhízás? (Autoload & Transients)

Ha a CPU rendben van, a következő gyanúsított a WordPress wp_options táblája. A WordPress minden admin oldalletöltéskor betölti a memóriába az autoload='yes' beállításokat. Ha egy rosszul megírt bővítmény ide szemetel, az minden egyes kattintásnál megfojtja az admint.

Írtam egy „Admin Footer” diagnosztikát, ami csak adminoknak jelenik meg, és megméri a rejtett terhelést.

A script (DB Hygiene Check): Ez egy MU-plugin (Must Use), ami ráakaszkodik az admin_footer-re.

add_action( 'admin_footer', function () {
    if ( ! current_user_can( 'manage_options' ) ) return;
    global $wpdb;

    // Autoload méret mérése
    $size = $wpdb->get_var( "SELECT SUM(LENGTH(option_value)) FROM $wpdb->options WHERE autoload = 'yes'" );
    $size_mb = round( $size / 1024 / 1024, 2 );

    // Szemét (lejárt transients) számolása
    $expired = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->options WHERE option_name LIKE '_transient_timeout_%' AND option_value < '" . time() . "'" );

    $color = $size_mb > 1.0 ? 'red' : 'green';
    echo "<div style='position:fixed; bottom:10px; right:10px; background:#000; color:#fff; padding:15px; border:2px solid $color;'>";
    echo "<strong>Autoload Size:</strong> $size_mb MB <br>";
    echo "<strong>Expired Transients:</strong> $expired db";
    echo "</div>";
});

Az eredmény: Az Autoload méret 1MB alatt volt, a Transients szám elfogadható. Tehát az adatbázis szerkezete egészséges. Mégsem tölt be az oldal.

Lépés: A „Brutális” Profilozó (A tettes leleplezése)

Ha nem CPU és nem DB méret, akkor egyetlen lehetőség maradt: Külső API hívások vagy lassú SQL lekérdezések. A WordPress admin betöltésekor a bővítmények gyakran „hazatelefonálnak” (licenc ellenőrzés, frissítés keresés, szinkronizáció). Ha ez a folyamat szinkron módon történik (a PHP megvárja a választ), és a távoli szerver lassú, akkor a mi oldalunk is megáll.

Készítettem egy „mindent látó” scriptet, ami elkapja a http_api_debug hookot és listázza a háttérben futó kéréseket.

A script (The Smoking Gun):

// Részlet a profilozóból (MU-Pluginba):
add_action( 'http_api_debug', function ( $response, $context, $class, $args, $url ) {
    global $wpm_http_log;
    $wpm_http_log[] = [
        'url' => $url,
        'code' => is_wp_error($response) ? 'ERROR' : $response['response']['code'],
        'time' => microtime(true)
    ];
}, 10, 5 );

add_action('admin_footer', function() {
    // Kiíratjuk a logot az admin aljára...
    // (A teljes kód hosszú, de a lényeg a HTTP logolás)
});

A „Heuréka” pillanat: Amint lefuttattam a scriptet, a képernyő alján vörösen izzott a hiba:

Összes idő: 10.82 másodperc Külső HTTP hívás: POST https://...mirakl-woocommerce-app-backend... -> (ERROR/TIMEOUT)

A diagnózis

Egy marketplace integrációs bővítmény (Mirakl) minden egyes admin oldalletöltésnél megpróbált szinkronizálni a központi szerverével. Mivel a távoli API épp nem válaszolt (vagy a tűzfal blokkolta), a PHP 10+ másodpercig várt a semmire. Ez blokkolta az egész WordPress admint (Blocking I/O).

A Tanulság

  1. Soha ne írj szinkron API hívást admin_init-re vagy oldalbetöltésre! Használj aszinkron megoldásokat (Action Scheduler, WP-Cron).
  2. A „Lassú WP” nem mindig erőforrás-hiány. Gyakran rossz kód, ami vár egy válaszra.
  3. Saját eszközök > Vaktában lövöldözés. Három egyszerű, célzott PHP snippettel percek alatt megtaláltuk a hibát, amit órákig tartó plugin-kapcsolgatással talán sosem vettünk volna észre.
Lőrincz András avatar

Lőrincz András

Lőrincz András vagyok, így hívnak. WordPress fejlesztőként weboldalak készítésével foglalkozom.

Amikor épp nem weboldalakat rakok össze, kvantumfizikáról vagy sci-firől olvasok, nézek videókat. Néha pedig elmerengek azon, hogy vajon mit csinál a másik énem egy párhuzamos univerzumban. Talán ő is épít valamit – vagy épp megőrült.

Vélemény, hozzászólás?

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük