Cache-toiminto websivuille

Aloittaja weatherc, keskiviikko, 17.06.2009, 17:01

« edellinen - seuraava »

0 Jäsenet ja 1 Vieras katselee tätä aihetta.

weatherc

Mitä se on:
Kun kävijä tulee normaalille php-sivulle se tehdään alusta loppuun. Tämä vaatii jonkin verran resursseja palvelimelta, jos on paljon php:tä se vaatii tietty enemmän kun jos vaan on "print "Hello"; ;)
Cache-tominnossa tallentaan sivusta kopio palvelimelle ja mikäli kopio on uudempi kun asetettu aikaraja niin katsojalle näytetään tämä valmis kopio sen sijaan että sivua tehään uusiksi. Koska suurin osa sivun rakenteista sekä myös tekstistä on pysyvää, katsoja ei huomaa mitään eroa. Tämä vähentää palvelimen resurssitarvetta sekä myös nopeuttaa sivun lataamista koska valmiin sivun latausaika on nopeampi kun jos ensin täytyy tehdä sivu.
Koska esim. meidän sääsivuilla (varsinkin jos käyttää CL-templatea tms.) on aika paljon tausta-skriptejä, kuten esim. meteoalarm-skripti, cachella voi saada aika paljonkin kevennystä aikaseksi.

Esimerkki miten se toimii:
Sivulla käy 1 minuutin sisään 10 kävijää ja cachen aikarajaksi on asetettu 1 minuutti.

Ilman cachea:
Sivu tehdään alusta loppuun jokaiselle 10 kävijälle

Cachella:
Kävijä 1 "tekee" sivun josta tallennetaan kopio ja lopulle 9:lle näytetään tämä valmis kopio.

Mistä saan cachen?
Esim. tuolta: http://www.addedbytes.com/php/caching-output-in-php/
Tuossa skriptissä laitetaan sivun alkuun sekä sivun loppuun omat pienet skriptinpätkät, tehdään cachekansio ja se on siinä. Itse asensin sen alta 10 minuutissa perusasetuksin.

Milloin tarvitsen sellaista?
Vähäliikenteinen sivu ei tarvi cachea. Mutta esim. niillä kellä ukkostutkat ja liikenne ukkosten aikaan selvästi isompi kun muutoin sekä ukkospäivien sivulataukset lasketaan tuhansissa enemmin kun sadoissa niin suosittelen lämpimästi. :)
Jollei muuta niin tämä pitäisi pitkittää aikaa edes jonkin verran, ennenkun savu alkaa nousemaan palvelimesta ja webhotelli alkaa kiroa sinua naama punaisena  ;D

Cache php-kuviin
Php-kuvat, kuten JpGraph-käppyrät ovat toinen asia mihin voi asettaa cache. Sen asettaminen on tosi helppoa:

Skriptin alkuun:

$file = 'cache/strikes.png';

$CacheTime = filectime($file);
$time = time();
$diff = $time - $CacheTime;

if($diff > 3600) {


Tässä kohtaa tuo 3600 on sekuntia jota tallenettua kuvaa näyetään

Kohta jossa:
$graph->Stroke();

Mutetaan tällaiseksi:
$graph-> Stroke($file);
//$graph->Stroke();
header("Content-type: image/png");
readfile($file);


} else {
header("Content-type: image/png");
readfile($file);
}


Ainut mitä pitää tehdä on cache-kansio jonka oikeudet CMOD:taa 777:ksi ja se on siinä :)

;D ;D


teutari

Alkoi tuo cache hiukan kiinnostamaan jotta olisi askeleen edellä webhotellia. ;D

Löysin tuommoisen sivun http://www.imponderabilia.nl/cache/caching.php missä on hiukan jalostettu tuota toimintoa.

- Mitäs asiantuntevat koodaajat sanovat tuosta koodista?
- Mitenkäs tuossa begin_caching.php:ssä kannattaisi tehdä nuo asetukset?
- Koodit yksittäisille sivuille vai Htaccess:iin?

Kysellään lisää kun aletaan koodia tunkemaan mutta täytyy nyt ensin tarkistaa onko tuo  register_globals päällä.

weatherc

LainaaAlkoi tuo cache hiukan kiinnostamaan jotta olisi askeleen edellä webhotellia. Virnistää

Löysin tuommoisen sivun http://www.imponderabilia.nl/cache/caching.php missä on hiukan jalostettu tuota toimintoa.

- Mitäs asiantuntevat koodaajat sanovat tuosta koodista?
- Mitenkäs tuossa begin_caching.php:ssä kannattaisi tehdä nuo asetukset?
- Koodit yksittäisille sivuille vai Htaccess:iin?

Intressantti löytö!  ;D
Tuo että se osaa itse siivota cache-kansion on hyvä juttu, tuossa mun löydössä se ei tee sitä.

1. Tuota täytyy testata
2. Ainakin niin että cache-kansio on itse sivuston root:in ulkopuolella jos vain mahdollista, eli jos sivu on /home/www/html niin vaikka /home/www/cache.
Jos haluaa näpertää niin sivuille omat cache-ajat, eli vaikka joku About-sivu pärjää hyvin esim "$cachetime  = 3600;":lla kun taas esim etusivu vaikka 120:lla.
Extension .cache:na, silloin se ei ole suoraan luettavissa vaikkei muutenkaan pitäisi olla kun on root:in ulkopuolella.
$cache_exc :iin ehdottomasti tutkakuva ym sellaiset tiehään vaihtuvat jutut ettei vaan jää johonkin selaimen cachee:seen roikkumaan.
3. Mulla se on nyt koodissa mutta CL-templatessa se vois olla helpompi .htaccessissa.

;D

djmake

Kannattaa miettiä, että onko tuollaiselle oikeaa tarvetta. Aina cache ei toimi niinkun on suunniteltu ja silloin käyttäjille tarjotaan vanhaa / virheellistä infoa. Puhumattakaan tilanteesta, jossa tuollainen konffataan niin, että se vaikuttaa mahdolliseen foorumiin tms sisältöön.
Lisäksi ainakin itse lasken tuollaisen siihen ryhmään, jota ei kannata ilman oikeaa syytä asentaa. Eli seuraa ensin sitä palvelimen kuormitusta (siis jos sellainen mahdollisuus on annettu) ja sen perusteella päättelee tarpeen. Jossakin alitehoisessa web-hotellissa voi toki ongelmia tulla pienemmälläkin käyttäjämäärällä ja silloin tuollainen pelastaa. Mutta virtuaalipalvelimien tai dedikoitujen rautojen kanssa ei tuollaista ihan nopeasti tarvitse.

Tietysti kaikki riippuu siitä php-koodin määrästä. Jos jokaisella sivunlatauksella suoritetaan oikeasti paljon raskasta koodia, niin toki se konetta rasittaa. Mutta silloinkin pitää miettiä, että miten pitkään voi tarjota samaa staattista sisältöä ja miten monta sivunlatausta ko aikana tulee.

weatherc

Se onihan totta että näin normi-oloissa jolloin kävijöitä alle 30 samaan aikaa mitään cachea ei tarvita. Idea tämän takana onkin juuri ruuhkat, kuten ukkoset ukkostutkilla, milloin kävijämäärä nousee rajusti. Esimerkiksi omalla sivullani on normi luku noin 20-30 kävijää samaan aikaan kun viime ukkosella se kävi 300:ssa. Ja valitettavasti on sivu rakennettava sen 300:n mukaan että se toimii myös ruuhkaisena aikana.

Mitä virtuaalisen purkin ja cacheen tarpeellisuuteen en ole ihan samaa mieltä koska totuushan on se että normi webhotellissa sulla voi joissakin tapauksissa olla jopa enemmän tehoa käytettävissä kun virtuaalisessa purkissa. Virtuaalisessa sulla sen sijaan on aina se sama määrä käytettävissä koko ajan mitä on säädetty (esim 512 Kb) kun taas normi hotellissa jaat koko purkin tehot kaikkien kanssa jolloin jos on mäihä ja loput sivustot ovat "kevyitä" voit saada paljonkin tehoa käyttöösi.

Sekin on totta että esim. foorumeille cache ei sovi, mutta muistaakseni esim SMF-foorumilla on jonkunlainen cache sisäänrakennettunakin.

Yksi ideahan on että tuon cache-toiminnon pikkasen lisäjalostaa,
(a) käyttää sitä vain esim. tutkasivulla ja muilla paljon liikennettä tuottavilla sivuilla.
(b) ottaa sen käyttöön vain ruuhka-aikana. Tämä on mahdollista esim ww-foorumilla olevan "whos-online"-skriptin avulla. Sain siitä ulos tämän hetken kävijämäärän pienen tutkimisen jälkeen ja sen avullahan se on helppoa ohittaa koko cache-toiminto jos kävijämäärä on esim alle 25.  ;D

weatherc

Nyt näyttää vihdoinkin auttavan :)

Tein pienet yhdistelmät teutarin linkissä olevasta sekä tuosta omasta löytämästäni skriptistä koska tuo teutarin linkissä oleva ei toiminut suoraan, tuli herjaa jos toistakin ;)
Tähän asti on sivuni ruvennut tökkimään siinä 70-80 users online kohdalla ja oon nyt tänään koittanut kokeilla eri vaihtoehtoja kun näkee tuloksen livenä. ;)

Suurin muutos minkä tein tuohon alkuperäiseen on että lisäsin muutamat headers-tagit ja johan rupes pelittää, nyt hurisee oikein hyvin 85 usersillä, myös VPS:än Resourse usage tippui 20%:sta 3%:iin :)

Tässä on nyt käytössä oleva cache_start.php, erona se että omassa olen tehnyt eri cachetime:t eri sivuille:

 // Settings
$cachedir = '/var/www/.../cache/'; // Directory to cache files in (keep outside web root)
$cachetime = 600; // Seconds to cache files for
$cacheext = 'cache'; // Extension to give cached files (usually cache, htm, txt)
 

// Ignore List
$ignore_list = array(
'addedbytes.com/rss.php',
'addedbytes.com/search/'
);

   // cleanup    
   if(mt_rand(1,$check)===1){                          
       $dir = getcwd();
       chdir($cachedir);
       foreach (glob("*".$cacheext) as $filename)            
           if ( time() - $cachetime > filemtime($filename))         // delete cachefiles if they are to old
               unlink($filename);
       chdir($dir);                  
   }

 
   if(strpos($page,$cacheexc)!==false){               // add files with markers to the ignore list
       $ignore_list[] = $page;
   }

 $page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // Requested page
$cachefile = $cachedir . md5($page) . '.' . $cacheext; // Cache file to either load or create
   $ignore_page = false;                               // +
   
   foreach($ignore_list as $file_to_ignore){           // do we need to ignore this file
       if(strpos($page, $file_to_ignore)!== false){    // if a match was found on position 0 it would not return true, that is why

this strange !== false is necessary
           $ignore_page = true;
           break; // we're done
       }
   }

if($ignore_page===false) {
if(file_exists($cachefile)){  
           $fsize = filesize($cachefile);             // needed later
           $ftime = filemtime($cachefile);
           $etag = '"'.md5($cachefile).'"';           // +
}
}


 
 $cachefile_created = ((@file_exists($cachefile)) and ($ignore_page === false)) ? @filemtime($cachefile) : 0;
@clearstatcache();
/*  TÄMÄ EI MULLA TOIMINUT
           if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $ftime) { // just send headers if page is in browser cache
               header("Warning: 304 browser cache");
               header("HTTP/1.1 304 Not Modified");
               header("Last-Modified: ".gmdate("D, d M Y H:i:s", $ftime)." GMT");
               exit;
       }
*/
 
// Show file from cache if still valid
if (time() - $cachetime < $ftime) {
   ob_start("ob_gzhandler");
   header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
   header("Cache-Control: private");
   header("Pragma: no-cache");
                   header("Content-Encoding: gzip");
                   //header("Content-Length: ".$fsize);
                   header("Warning: 200 valid cache");
                   header("Last-Modified: ".gmdate("D, d M Y H:i:s", $ftime)." GMT");
                   //header("Etag: ".$etag);

@readfile($cachefile);
exit();
 
}
 
// If we're still here, we need to generate a cache file
ob_start("ob_gzhandler");
ob_start();
   header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
   header("Cache-Control: private");
   header("Pragma: no-cache");
                   header("Content-Encoding: gzip");
                   //header("Content-Length: ".$fsize);
                   header("Warning: 200 expired cache");
                   header("Last-Modified: ".gmdate("D, d M Y H:i:s", $ftime)." GMT");
                   //header("Etag: ".$etag);