środa, 14 stycznia 2009

Zmniejszamy obciążenie serwera

Mając własną stronę WWW, na której wykonywane są skrypty php, może zajść potrzeba zredukowania obciążenia serwera. Jest to istotne w momentach, kiedy otrzymujemy maile od Naszego hostingodawcy, z informacją że zużywamy za dużo zasobów, bądź posiadamy własny serwer dedykowany, gdzie zamieszczona została strona z dużą liczbą użytkowników.

Zbędne roboty

Jedną z najczęstszych przyczyn, zbyt dużego wykorzystania zasobów serwera, są częste odwiedziny robotów. Niektóre z nich są zbędne i bez konkretnego powodu, zjadają nam transfer i nazbyt często wykonują skrypty php, które prowadzą do przeciążania CPU serwera. W związku z tym zablokujmy je, a właściwie przekierujmy w jakieś inne miejsce. Aby to zrobić, wystarczy na początku każdej z podstron i strony głównej wkleić poniższy kod, lub stworzyć osobny plik .php i includować go :



<?$ua = $_SERVER[HTTP_USER_AGENT];
$ip = $_SERVER[REMOTE_ADDR];
$ur = $_SERVER[REQUEST_URI];

if (
eregi("wget", $ua)
|| eregi("askjeeves", $ua)
|| eregi("city4you", $ua)
|| eregi("converacrawler", $ua)
|| eregi("deltascan", $ua)
|| eregi("emeraldshield", $ua)
|| eregi("ia_archiver", $ua)
|| eregi("ichiro", $ua)
|| eregi("jyxobot", $ua)
|| eregi("linkwalker", $ua)
|| eregi("netexperts", $ua)
|| eregi("omniexplorer", $ua)
|| eregi("psbot", $ua)
|| eregi("shim-crawler", $ua)
|| eregi("societyrobot", $ua)
|| eregi("surveybot", $ua)
|| eregi("szook", $ua)
|| eregi("turingos", $ua)
|| eregi("wanadoo", $ua)
|| eregi("zongbot", $ua)
|| eregi("zoomspider", $ua)
|| eregi("zyborg", $ua)

// blokada po url
|| eregi("zoom_highlight", $ur)




// blokowanie zakresow IP
// omniexplorer
|| blozakres("64.71.131",$ip)
|| blozakres("65.19.134",$ip)
|| blozakres("65.19.150",$ip)
|| blozakres("65.19.169",$ip)
|| blozakres("66.246",$ip)
|| blozakres("72.36.254",$ip)



// niechciane IP

|| $ip == "65.19.150.241"
|| $ip == "65.214.44.54"
|| $ip == "65.75.166.200"
|| $ip == "69.57.132.54"
|| $ip == "72.36.254.178"
|| $ip == "80.51.198.186"
|| $ip == "81.190.43.231"
|| $ip == "209.123.8.173"
|| $ip == "220.181.26.69"
|| $ip == "211.120.209.3"



) {
// wysylam podejrzanego robota w kosmos np. za pomoca header("location: http:// odchlankosmosu.commm");
// lub poprzez $ip do nich samych...
header("HTTP/1.1 301 Moved Permanently");
header("location: http://inny-blog.blogspot.com/");
header("Connection: close");
exit;
}
function blozakres($zakres,$ip_,$zakresdo=""){
$ip_od = explode(".",$zakres);
$ip_we = explode(".",$ip_);
if (!$zakresdo) {
$zakresdo = $zakres;
}
$ip_do = explode(".",$zakresdo);

for( $x = 0; $x < 4; $x++ ){
$ip_od[$x] = sprintf("%03d",$ip_od[$x]);
$ip_we[$x] = sprintf("%03d",$ip_we[$x]);
if (!$ip_do[$x]) {
$ip_do[$x]=255;
}
$ip_do[$x] = sprintf("%03d",$ip_do[$x]);
}
$zakres = implode("",$ip_od) + 0;
$ip_ = implode("",$ip_we) + 0;
$zakresdo = implode("",$ip_do) + 0;
return (($ip_ >= $zakres) && ($ip_ <= $zakresdo));
}?>
Źródło PiO

W moim przypadku na serwerach prohost.pl, powyżej przedstawiony kod zredukował obciążenie CPU serwera z 15,73% do 8,07%. Zmniejszyło się też zużycie transferu.

Cache w php

Jak widać, powyższa porada mimo, że jest skuteczna, nie rozwiązuje całego problemu. Jednak mimo tego możemy dalej walczyć ze zbyt dużym wykorzystaniem zasobów serwera, poprzez cachowanie całych podstron. Nie zagłębiając się zbytnio w szczegóły, przedstawię jak szybko wstawić na podstrony ich cachowanie. Dzięki temu skrypty php nie będą wykonywały się zbyt często, zaś wcześniej wykonany skrypt, zostanie w swym całym ujęciu zapamiętany jako statyczna strona HTML, na czas przez Nas zdefiniowany.

Na początku stwórzmy plik o nazwie cacheclass.php i skopiujmy do niego poniższe funkcje :


<?function czytcache($plik,$czas)
{
$plik='cache/'.$plik.'.cache';
if (file_exists($plik))
if(time() > $czas + filemtime($plik))
return false;
else
return readfile($plik);
else
return false;
}

function wyscashe($plik){
$plik='cache/'.$plik.'.cache';
$nowyCashe=fopen($plik,'w+');
fwrite($nowyCashe, ob_get_contents());
fclose($nowyCashe);
ob_end_flush();
}
?>


Powyżej przedstawione funkcje, będą tworzyły nam pliki cache, w których będzie zapamiętywana Nasza strona, przez czas jaki za chwilę zdefiniujemy. Mając powyższe funkcje, możemy includować plik cacheclass.php.

Skoro mamy już gotowe funkcje, to na każda z podstron możemy zamieścić kod, który będzie je aktywował.



<? include "cacheclass.php";
if (!czytcache('index',86400)) { ob_start();?>
// Tu znajduje się kod naszej strony
// Za znacznikiem zamykającym HTML wstawiamy :
<? wyscashe('index-'.$id_str);} ?>



Powyżej domyślnie jako nazwę pliku podałem index. Jednak dla każdej podstrony, nazwa ta powinna być unikatowa. W innym przypadku będzie wyświetlana cały czas ta strona, która jako pierwsza została zapamiętana w pliku index.cache. Dlatego jako unikalną nazwę, proponuję dopisywać do niej jakieś paramerty, przekazywane metodą GET lub POST. Przykładowo plik może mieć taką nazwę ‘index-’.$_GET[‘zmienna1].’-‘.$_GET[‘zmienna2’]. Aby skrypt działał poprawnie, należy jeszcze na serwerze utworzyć katalog CACHE/. Nazwę i dostęp do tego katalogu możemy konfigurować w funkcjach znajdujących się w cacheclass.php. Powyżej przedstawiony kod domyślnie cache’uje stronę na 24 godziny (86400, czyli 60 sek * 60 min * 24 godz). Parametr ten możemy zmieniać według własnego uznania i własnych potrzeb.

Wyniki

Tak jak już pisałem, przekierowanie niechcianych robotów, zmniejszyło obciążenie CPU serwera z 15,73% na 8,07%. Po zastosowaniu cache’wania obciążenie CPU zmniejszyło się do 4,75%, co w porównaniu do stanu początkowego jest bardzo dobrym wynikiem.

Brak komentarzy:

Prześlij komentarz