Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    script ajax: sovraccarico cpu

    Ciao, ho bisogno di un aiuto se qualche buon'anima riesce a fornirmelo. Sul mio sito utilizzo una comune shoutbox ajax, ma i tanti utenti contemporanei (circa 3000), hanno mandato ko la cpu del mio hosting. Inizialmente ho fatto una prima modifica, portando il tempo di refresh da 3 secondi a 2 minuti. In questo modo le chiamate al server sono passate da oltre 1milione a 50mila circa al minuto. Adesso devo ottimizzare ulteriormente il codice. Il mio provider mi ha suggerito di mettere mano alla riga del codice in cui è contenuta la funzione random (qui sotto allego il codice completo dello script), ma io sinceramente non riesco a saltarci fuori.
    Qualcuno mi può aiutare? Grazie mille in anticipo.
    ecco il codice dello script:

    <script language="javascript" type="text/javascript">
    <!--
    var request;
    var lastload=0;
    var refreshTime=120000; // 2 minutes

    function createRequest()
    {
    try {
    request = new XMLHttpRequest();
    } catch (trymicrosoft) {
    try {
    request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (othermicrosoft) {
    try {
    request = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (failed) {
    request = false;
    }
    }
    }

    if (!request)
    alert("Error initializing XMLHttpRequest!");
    }


    createRequest();

    function sayIt()
    {
    var msg = document.getElementById("myShout").value;
    document.getElementById("myShout").value = "";
    var randomnumber=Math.floor(Math.random()*23123); // get rid of pesky caching...

    var url = "ajax_command.php?shout=ashout&n="+randomnumber+"& msg="+escape(msg);
    request.open("GET", url, true);
    request.onreadystatechange = updateSayIt;
    request.send(null);
    }

    function clearShoutStatus()
    {
    document.getElementById("shoutstatus").innerHTML = "";
    }

    function updateSayIt()
    {
    if (request.readyState == 1)
    document.getElementById("shoutstatus").innerHTML = "Aggiornamento live.";
    if (request.readyState == 4)
    {
    document.getElementById("shoutstatus").innerHTML = "Aggiornato";
    setTimeout('clearShoutStatus();',refreshTime);
    getNewShouts();
    }
    }

    function getShouts()
    {
    var randomnumber=Math.floor(Math.random()*23123); // get rid of pesky caching...
    var url = "ajax_command.php?shout=getshouts&n="+randomnumber ;
    request.open("GET", url, true);
    request.onreadystatechange = updateShouts;
    request.send(null);
    }

    function updateShouts()
    {
    if (request.readyState == 4)
    if (request.status == 200) // check server result code...
    {
    var i;
    var messagetime;
    var message;
    var response = request.responseText.split("~");

    document.getElementById("myshouts").innerHTML = '';
    for(i=0;i<response.length;i+=3) // go thru each element in array.. length -1 needed..
    {
    message = response[i];
    messagetime = response[i+1];
    messagetexttime = response[i+2];
    document.getElementById("myshouts").innerHTML += "";

    document.getElementById("myshouts").innerHTML += ""+message+"";
    document.getElementById("myshouts").innerHTML += "

    ";
    if(i==0) lastload = messagetime; // use this for when calling updates...
    }
    setTimeout('getNewShouts();',refreshTime); // run again in 3 seconds..
    }
    else if (request.status == 404) // check server result code...
    alert("Could Not Find Page on Server!");
    }

    function getNewShouts()
    {
    //createRequest();
    var randomnumber=Math.floor(Math.random()*11); // get rid of pesky caching...
    var url = "ajax_command.php?shout=getnewshouts&time="+lastlo ad+"&n="+randomnumber;
    // alert(url);
    request.open("GET", url, true);
    request.onreadystatechange = updateNewShouts;
    request.send(null);
    }

    function updateNewShouts()
    {
    if (request.readyState == 4)
    {
    if (request.status == 200) // check server result code...
    {
    // send a header of a weird number if unable to find page on server...request.status == 999
    var i;
    var messagetime;
    var message;
    var newHTML="";
    var response = request.responseText.split("~");

    for(i=0;i<response.length;i+=3) // go thru each element in array.. length -1 needed..
    {
    message = response[i];
    messagetime = response[i+1];
    messagetexttime = response[i+2];

    newHTML += ""+message+"";
    newHTML += "

    ";
    document.getElementById("myshouts").innerHTML = newHTML + document.getElementById("myshouts").innerHTML;
    if(i==0) lastload = messagetime; // use this for when calling updates...
    }
    }
    else if (request.status == 404) // check server result code...
    alert("Could Not Find Page on Server!");

    setTimeout('getNewShouts();',refreshTime); // run again in 3 seconds..

    }
    }

    function submitenter(e)
    {
    var keycode;
    if (window.event) keycode = window.event.keyCode;
    else if (e) keycode = e.which;
    else return true;

    if (keycode == 13)
    {
    sayIt();
    return false;
    }
    else
    return true;
    }


    //-->
    </script>

    <body onLoad="getShouts()">

    <input type="text" id="myShout" onKeyPress="return submitenter(event)" /> <a onMouseDown="sayIt()">say it</a>
    <font size=1 color="#FF0000"><div id=shoutstatus></div></font>

    <div id=myshouts></div>

    </body>

  2. #2
    Ma tu ti rendi conto che ogni click su "say It" o ogni invio nel text input causa 3, TRE, richieste al server?

    3000 utenti * 3 richieste al click = 9000 richieste per utente,

    Metti che in un minuto uno possa mandare 10 messaggi:

    9000 * 10 = 90.000 richieste al minuto!

    Ritieniti fortunato che ne fanno di meno.

    Fai in modo che un click o un invio = 1 richiesta e già hai meno di 30000 richieste al minuto.
    I DON'T Double Click!

  3. #3
    Prima di tutto ti ringrazio per la risposta... purtroppo io non sono un programmatore, tanto meno un esperto di script php... ho letto qualcosa e mi è balzata agli occhi la questione del refresh. Ti prego, se possibile, di aiutarmi perché questo è uno script già fatto che ho trovato su internet. Io non sono in grado di farlo... tu mi puoi dare una mano?

  4. #4
    se mi spieghi che cosa fa ajax_command.php o mi posti l'url dove hai scaricato lo script, posso vedere di fare qualcosa.
    I DON'T Double Click!

  5. #5

    ancora grazie

    ecco il codice di ajax_command.
    Per completezza di informazione ti dico che la possibilità di scrivere nella shout è limitata a pochi lettori, mentre dati alla mano, tutti (circa 3000) leggono contemporaneamente.
    Ancora grazie mille... se non trovo la soluzione mi chiudono il sito...

    <?
    // PROGRAM ajax_shout.php //
    /*
    * This program is a very ugly but simple php/AJAX implementation of
    * a chat program..
    *
    * Permission to use and modify is granted to the public domain so
    * long as they leave my contact info intact. If you wish to contribute
    * changes feel free to drop me an email and notify me. Permission is NOT
    * granted for this to be redistributed by itself.
    *
    * (c)opyright irbobo (happysap -NOSPAM- at -NOSPAM- gmail.com)
    * http://thedevnet.com
    */


    ignore_user_abort(true);
    @ob_start();
    include_once('shoutbox_data.php');

    function HTTPStatus($num) {

    static $http = array (
    100 => "HTTP/1.1 100 Continue",
    101 => "HTTP/1.1 101 Switching Protocols",
    200 => "HTTP/1.1 200 OK",
    201 => "HTTP/1.1 201 Created",
    202 => "HTTP/1.1 202 Accepted",
    203 => "HTTP/1.1 203 Non-Authoritative Information",
    204 => "HTTP/1.1 204 No Content",
    205 => "HTTP/1.1 205 Reset Content",
    206 => "HTTP/1.1 206 Partial Content",
    300 => "HTTP/1.1 300 Multiple Choices",
    301 => "HTTP/1.1 301 Moved Permanently",
    302 => "HTTP/1.1 302 Found",
    303 => "HTTP/1.1 303 See Other",
    304 => "HTTP/1.1 304 Not Modified",
    305 => "HTTP/1.1 305 Use Proxy",
    307 => "HTTP/1.1 307 Temporary Redirect",
    400 => "HTTP/1.1 400 Bad Request",
    401 => "HTTP/1.1 401 Unauthorized",
    402 => "HTTP/1.1 402 Payment Required",
    403 => "HTTP/1.1 403 Forbidden",
    404 => "HTTP/1.1 404 Not Found",
    405 => "HTTP/1.1 405 Method Not Allowed",
    406 => "HTTP/1.1 406 Not Acceptable",
    407 => "HTTP/1.1 407 Proxy Authentication Required",
    408 => "HTTP/1.1 408 Request Time-out",
    409 => "HTTP/1.1 409 Conflict",
    410 => "HTTP/1.1 410 Gone",
    411 => "HTTP/1.1 411 Length Required",
    412 => "HTTP/1.1 412 Precondition Failed",
    413 => "HTTP/1.1 413 Request Entity Too Large",
    414 => "HTTP/1.1 414 Request-URI Too Large",
    415 => "HTTP/1.1 415 Unsupported Media Type",
    416 => "HTTP/1.1 416 Requested range not satisfiable",
    417 => "HTTP/1.1 417 Expectation Failed",
    500 => "HTTP/1.1 500 Internal Server Error",
    501 => "HTTP/1.1 501 Not Implemented",
    502 => "HTTP/1.1 502 Bad Gateway",
    503 => "HTTP/1.1 503 Service Unavailable",
    504 => "HTTP/1.1 504 Gateway Time-out"
    );

    header($http[$num]);
    }


    //string insens_replace($haystack,$needle,$replacewith) - case insensitive replace function
    function insens_replace($needle,$replacewith,$haystack)
    {
    static $recursed=FALSE;
    static $beginpart='';
    static $endpart='';

    if(($pos=strpos(strtolower($haystack),strtolower($ needle)))!==FALSE)
    {
    $recursed=TRUE;
    $beginpart.=substr($haystack,0,$pos).$replacewith;
    $endpart=substr($haystack,$pos+strlen($needle));
    return insens_replace($endpart,$needle,$replacewith);
    }
    else
    {
    if($recursed)
    {
    $result=$beginpart.$endpart;

    $recursed=FALSE;
    $beginpart='';
    $endpart='';

    return $result;
    }
    else
    {
    return $haystack;
    }
    }
    }

    function shoutbox_shout($MESSAGE)
    {
    global $SHOUTBOX;

    $MESSAGE = str_replace("-",'ASH:', $MESSAGE);

    // take out anything that isn't A-Z,a-z,0-9
    $MESSAGE = ereg_replace('[^a-zA-Z0-9 ,.?!:#+*&)(|\'"]',"",$MESSAGE);

    // trim excess whitespace...
    $MESSAGE = preg_replace('/\s+/', ' ', $MESSAGE);
    $MESSAGE = trim($MESSAGE);

    // replace bad words...
    $MESSAGE = insens_replace('poker','', $MESSAGE);
    $MESSAGE = insens_replace('viagra','', $MESSAGE);
    $MESSAGE = insens_replace('pill','', $MESSAGE);
    $MESSAGE = insens_replace('pthc','', $MESSAGE);
    $MESSAGE = insens_replace('preteen','', $MESSAGE);
    $MESSAGE = insens_replace('childporn','',$MESSAGE);
    $MESSAGE = insens_replace('kiddy','', $MESSAGE);
    $MESSAGE = insens_replace('kiddi','', $MESSAGE);
    $MESSAGE = insens_replace('kid','', $MESSAGE);
    $MESSAGE = insens_replace('children','',$MESSAGE);
    $MESSAGE = insens_replace('child','', $MESSAGE);
    $MESSAGE = insens_replace('teeny','', $MESSAGE);
    $MESSAGE = insens_replace('http','', $MESSAGE);
    # should render the .com's ,etc. to uselessness
    $MESSAGE = insens_replace('.com ',' ', $MESSAGE);
    $MESSAGE = str_replace('://','', $MESSAGE);
    $MESSAGE = str_replace('.','. ', $MESSAGE);
    $MESSAGE = str_replace('.com ',' ', $MESSAGE);


    // $MESSAGE = str_ireplace('','---',$MESSAGE);

    $MESSAGE = str_replace('ASH:','-',$MESSAGE);

    // trim message down to 255 characters...
    if(strlen($MESSAGE) > 255) $MESSAGE = substr($MESSAGE,0,255)."...";

    $MESSAGE = str_replace('&','&#38;',$MESSAGE);
    $MESSAGE = str_replace('"','&#34;',$MESSAGE);
    $MESSAGE = str_replace("'",'&#39;',$MESSAGE);


    if(!@empty($MESSAGE))
    {

    if (!isset($SHOUTBOX)) $SHOUTS = 0;
    else if(count($SHOUTBOX) >= 80) $SHOUTS = 79; // MAX DISPLAYED SHOUTS...
    else $SHOUTS = count($SHOUTBOX);

    // add latest message to $SHOUTBOX array //
    $TEMP_ARRAY[] = array("msg" => $MESSAGE, "userip" => $_SERVER['REMOTE_ADDR'], "time" => time());
    // ADD in the old shouts...
    if($SHOUTS > 0) for($i=0;$i<$SHOUTS;++$i) $TEMP_ARRAY[] = $SHOUTBOX[$i];

    $FCONTENTS = '<'.'?'."\r\n";

    for($i=0;$i<count($TEMP_ARRAY);++$i)
    {
    $FCONTENTS .= '$SHOUTBOX[] = array(';
    $FCONTENTS .= ' "msg" => "'.$TEMP_ARRAY[$i]['msg'] .'", ';
    $FCONTENTS .= ' "userip" => "'.$TEMP_ARRAY[$i]['userip'] .'", ';
    $FCONTENTS .= ' "time" => "'.$TEMP_ARRAY[$i]['time'] .'" ';
    // build file string...
    $FCONTENTS .= ");\r\n";
    }

    // array("key" => "value", ... ); //

    $FCONTENTS .= "\r\n".'?'.'>';

    $fp = fopen('shoutbox_data.php','w');
    fwrite($fp,$FCONTENTS);
    fclose($fp);
    }
    }

    function t_delimit($SHOUTS)
    {
    $SCOUNT = count($SHOUTS);
    for($i=0;$i < $SCOUNT;++$i)
    {
    echo $SHOUTS[$i]['msg']."~".$SHOUTS[$i]['time']."~".date("F j, Y, g:i a", $SHOUTS[$i]['time']);
    if($i<$SCOUNT-1) echo "~";
    else echo "\n";
    }
    }

    function return_new_shouts($SHOUTS, $OLDTIME)
    {
    for($i=0;$i<count($SHOUTS);++$i)
    if($SHOUTS[$i]['time'] > $OLDTIME)
    $NEWSHOUTS[] = $SHOUTS[$i];

    if(!@empty($NEWSHOUTS[0]['time'])) return $NEWSHOUTS;
    }

    switch(@$_GET['shout'])
    {
    case 'add':
    $MESSAGE = $_POST['msg'];
    shoutbox_shout($MESSAGE);
    break;

    case 'ashout':
    $MESSAGE = urldecode($_GET['msg']);
    shoutbox_shout($MESSAGE);
    break;

    case 'getshouts':
    if(@empty($SHOUTBOX[0]['time'])) echo "NONE|";
    else t_delimit($SHOUTBOX);
    break;

    case 'getnewshouts':
    if($SHOUTS = return_new_shouts($SHOUTBOX, $_GET['time'])) t_delimit($SHOUTS);
    else HTTPStatus(304);
    break;
    }

    if(!@empty($_GET['shout']))
    {
    // header("location:".$_SERVER['PHP_SELF']);
    die();
    }

    ?>

  6. #6
    Allora, ho dato un'occhiata al codice... è un po' semplicistico per me, comunque, l'ideale sarebbe fare in modo che ci sia UNA opzione, alla fine del file, che permette di aggiungere il messaggio alla chat e, in ogni caso, alla fine la chat intera viene inviata dal server.

    Il problema è, a mio avviso, che tu scrivi su di un file, questo comporta che, se 3000 persone vogliono scrivere su di un file, 3000 persone dovranno essere in coda per aprire il file, scrivere la frase (tra l'altro noto che non appendi la frase in fondo al file, ma lo riscrivi ogni volta, aggiungendo la riga) e chiudere il file.

    Chiaramente, questo, oltre a causare notevole tempi di latenza, causa un affaticamento del server che si trova a fare richieste a raffica e a riscrivere ogni volta un file sempre più grande.

    Dato il numero di utenti, io ti consiglierei di spostarti su di un database, piuttosto che un file PHP, per mantenere la chat.

    Prova a correggere questi problemi e dovresti vedere un miglioramento.
    I DON'T Double Click!

  7. #7

    shout

    ho capito perfettamente il tuo discorso, ma forse c'è un passaggio che non ti ho detto oppure mi sono spiegato male. In pratica, la shoutbox è utilizzata dai 3000 utenti solamente in lettura, perché ho abilitato a scrivere (grazie a joomla che gestisce le registrazioni) solamente un numero limitato di utenti (10). Questo perché la shoutbox è utilizzata come mezzo di comunicazione istantaneo e non come interazione fra gli utenti...
    ecco perché quello che più mi interessa è la parte di "lettura", non tanto la parte di "scrittura". Oppure tu credi che la scrittura, nonostante sia abilitata a pochi, incida pesantemente sull'utilizzo della CPU?
    Spero di essere stato più chiaro e soprattutto spero di non averti ancora stancato...
    grazie mille

  8. #8
    Dipende dal numero di scritture, per dire 10, utenti possono comunque scrivere 10 messaggi al minuto (almeno 10) facendo 300 (10 * 10 * 3) richieste al minuto (5 al secondo), ognuna che importa il file PHP e lo riscrive da capo. A seconda del server, potrebbe essere pensate, soprattutto perché in un sito in Hosting, la CPU del server è condivisa da N siti, ognuno dei quali può avere un buon traffico.

    Io ti raccomanderei comunque di spostarti su di un Database.
    I DON'T Double Click!

  9. #9

    re

    scusa se insisto, ma non essendo un programmatore devo fare con il poco di conoscenze che ho... cercando quindi di ottimizzare il codice attraverso soluzioni "fisiche".
    Sulla base dei calcoli esatti che mi fai, ovvero 3 chiamate al server per ogni messaggio scritto:
    - Se io limito la scrittura ad un solo utente, che potrà scrivere solamente una volta al minuto o addirittura una volta ogni due minuti, in questo caso credi che i problemi possano ripresentarsi?

    - Nel lato "lettura" tu vedi qualche problema nel codice così come è strutturato ora?

    grazie ancora

  10. #10
    mmm in caso di lettura non dovrebbero esserci problemi... anche se sarebbe meglio usare un sistema diverso (per dire sarebbe meno complicato con un setInterval su di una funzione a se stante).

    Comunque, dovrebbe andare.
    I DON'T Double Click!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.