webForumDet fria alternativet

Snabba upp IIS6 med 800%

PHP

1 svar · 791 visningar · startad av kjell

Medlem sedan dec. 1999757 inlägg
Frågan#1

Det är möjligt att titeln kan uppfattas som aningen överdriven men faktum är att det i vissa fall kan bli ännu bättre resultat.
Jag skriver vissa fall eftersom detta samtidigt är en fråga om hur man kodar i PHP och vilka inställningar som finns i php.ini. Hur som helst så har det i.o.m. Windows 2003 fått en avgörande betydelse och jag fann det ganska intressant att veta varför. Efter väldigt mycket testande och uteslutande så hittade jag till slut en sak i den nya versionen som inte fungerade som tidigare. Det är ju så typiskt Microsoft att släppa saker som inte riktigt är färdiga och nu ska man tydligen behöva vänta på att SP1 till 2k3 ska släppas. Nu när alla bitar har fallit på plats börjar dock inse att det faktiskt fungerar som logiken kräver och att det nog faktiskt är win2k som egentligen innehåller en bugg.

Vad är det som ändrats då?
Jo, tidigare så buffrade winsocken nätverkstrafiken för IIS5:an men det gör den alltså inte längre.
Inte mycket att bråka om kan tyckas men det spelar en helt avgörande roll om man tidigare kodat på ett speciellt sätt. Nedanstående kod används i exemplet:

<?php
for ($i = 1; $i <= 20000; $i++) {
	echo "$i<br>\n";
}
?>

Lägg det här i bodyn på en sida och kör koden över nätverk. Jag skriver nätverk eftersom http://localhost inte påverkas av hur winsocken jobbar. Om du testar koden på en win2k/iis5 så gissar jag att den sidan är klar på 1-2sec och kör du den i win2k3/iis6 så tar det kanske 8sec.
Det är värt att notera att antalet rader inte spelar större roll än mängden byte i varje echo. Lägg till en tabell i varje echo så ser du resultatet. Kör du koden med en tabell i varje echo så misstänker jag att din server gör en timeout och det skrivs kanske ut drygt 4000 rader. Kör du samma på en win2k/iis5 så klarar den förmodligen detta utan problem.

Vad gör man då åt detta?
Ja, man har ett par möjligheter att påverka detta.

1.
Man kodar inte på det sättet utan sparar undan alla värden tills det är dags att släppa ut sidan.
Exempelvis

<?php
for ($i = 1; $i <= 20000; $i++) {
	$value .= "$i<br>\n";
}
echo "$value";
?>

I exemplet ovan är det tämligen simpelt men så ser ju inte alla php-filer ut.
Har man många skript är det kanske inte så kul att koda om allt och personligen gillar jag inte alls att koda på det viset. Jag vill att allt är så lättläst som möjligt samt att jag vill koda på ett enkelt och snabbt sätt. Går jag in och hämtar något från MySQL så skriver jag hellre ut det avsnittet för att sedan fortsätta till nästa ställe och gör sedan samma sak där o.s.v. Det är ju inte sällan som en normal php-fil blir 250-400 rader och då tycker jag det blir enklare på detta viset. Sedan är det svårt att påverka alla färdiga skript som används, exempelvis phpMyAdmin som man ju uppdaterar frekvent och även denna går mycket segare med IIS6:an.

2.
php.ini
Vi letar upp raden output_buffering och ändrar värdet till On. Orginalvärdet varierar troligen mellan olika versioner och kanske även mellan zip och install. Det kan också variera beroende på om du valde att kopiera php.ini-dist eller php.ini-recommended. Om du har ett värde på 4096 så är det troligt att du valt php.ini-recommended och det är också med denna filen som testat har gjorts. Om det nu stod On från början i din fil så kan du antagligen lämna denna tråden. När värdet är ändrat så starta om IIS:en och testa åter det kodexempel som testades före ändringen. Det som tidigare tog 8sec körs nu antagligen på runt sekunden men hårdvaran kan naturligtvis spela en roll, fast det kodexemplet borde inte kräva speciellt mycket.

Konsekvenser?
Javisst. Inte så mycket för den normale användaren kanske men för webbhotellsägare och avancerade användare finns det några saker man bör känna till.
Nu när maskinen buffrar innan den skickar så måste ju detta ta vägen någonstans och det lägger sig mycket riktigt i minnet. Antagligen spelar det ingen roll vid normala sidor men om man har väldigt stora sidor på flera MB så bör man kanske skicka lite till klienten så den inte tror att sidan hängt sig. Har man haft 2000/iis5 tidigare så har du säkert redan gjort så med funktionen flush() och då kommer du nu att upptäcka att detta inte fungerar.
Exempelkod:

<?php
print ("<div style=\"color:#0000CC\">");
for($i = 0; $i < 100; $i++) {
	$spaces .= "<!-- bufferme -->";
}
for($i = 0; $i < 100; $i++) {
	for($ii = 0; $ii < 200000; $ii++) {
		// annat jobb...
	}
	print "$spaces|";
	flush();
}
print ("</div>");
print ("<br>F&ouml;rsta delen avklarad...");
// mer kod...
?>

Vad man här får göra är att ändra flush(); till ob_flush();.
Den uppmärksamme har nu upptäckt att jag glömde ob_start(); men det gjordes medvetet. Eftersom vi har satt output_buffering On i php.ini så är det alltid på och därför kan man nu istället ange ob_flush() där man tidigare hade flush().

En annan sak som också påverkas är header. Det är ju allmänt känt att man inte kan skicka en header när man väl skickat något annat men detta gäller inte längre.

<?php
echo "Hejdå";
header ("Location: nysida.php");
?>

fungerar alltså utmärkt.
Utöver detta har jag inte upptäckt något mer. Jag nämnde webbhotellsägare också. Själv har jag output_buffering On på min server men då har jag också kontroll på varje fil som körs. Hade jag haft ett webbhotell så är det möjligt att jag kollat lite hur mycket minne som äts och kanske testat fram olika värden istället för bara On men det är något som var och en får testa fram själv.

Det här är helt baserat på mina senaste erfarenheter av Win2003/IIS6/PHP v4.3.4 och finns det något som är felaktigt eller om du har något utöver detta så är jag väldigt tacksam om den informationen läggs till här. Själv vill jag ha maskin som serverar mina besökarna så snabbt som möjligt och utnyttjar den prestanda som finns tillgänglig.

Medlem sedan juni 20015 009 inlägg
#2

Mycket bra inlägg! :bire

278 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
132 ms — deklarationer (db)
0 ms — hämta statistik (cache)
143 ms — hämta tråd, inlägg och bilagor (db)
130 ms — ändringar (db)