![]() |
Hej,
Jag funderar lite över performance vid hantering av bilder. Jag har två metoder att välja på: 1. Alla bilder går via image.php image.php öppnar filen och läser filen från en katalog på disk och spottar därefter ut bilden till webbläsaren. 2. Bilder länkas som vanligt Alltså en <img>-tagg pekar direkt på bildens position. Min fråga är; är alternativ 1 mycket långsammare än alternativ 2? Jag trodde först att så var fallet, men sedan började jag tänka i banor som att "Någon måste ju ändå läsa filen från disk, om det är ett PHP-script (image.php) eller Apache som gör detta borde väl inte spela någon stor roll?" Vad tror ni? Anledningen till att jag helst vill gå via image.php är för att jag vill kunna styra vilka som skall få tillgång till bilderna genom att kontrollera deras SESSION. Tacksam för svar från performance-gurus! |
En webläsare kan göra flera simultana anrop mot exempelvis en img. Hur php filer exekveras vet jag inte, men då en webläsare förväntar ett svar ifrån ett php skript så vet jag inte om de läggs på "kö" eller dylikt. Du har ju en php som i sitt htmlsvar anropar en php. En php i sig bör ju ta något längre tid att exekvera även fast den är mycket simpel. Frågan är om det är så pass mycket tid så du behöver bry dig om det.
Någon? |
Jag har bilder och vanliga dokument också. Låt säga att någon laddat upp en TIFF-bild på 10MB.. om PHP-scriptet skall läsa in filen och spotta ut den till webbläsaren kommer detta att ta lite tid. Men filen måste ju ändå spottas ut till läsaren av något... PHP eller via direkt länk och då av Apache?
Vad tror ni? |
Citat:
I början av php-dokumentet så spottar du ut klockslaget/sekunder, och samma sak nederst i dokumentet, så ser du juh hur snabbt sidan laddas? |
Citat:
|
Citat:
Du kanske hittar svaret redan i apache servern (som jag vet 0 om). Finns det "trådar" den kör anrop i eller ställs allt på kö, eller är det bara anrop till php som går i en kö och bilder/html whatever i egen etc etc. |
Gör som nomicon sa, testa. Det blir ju en viss overhead jämfört med en img-tag i HTML, men det verkar ju funka för Lunar...
|
Min syn på saken:
Har du alternativet att generera en korrekt bildurl i htmlen, gör det. Att köra script som läser och skickar filen är overkill i de fall bilden är en statisk bild. (genererar du en bild är det en annan sak.) http 1.1 tillåter att man (webläsaren) kan återanvända en koppling mot servern för flera requests, vilket ger ett "kösystem" i sig. Men ie tillåter i sin tur (som standard) 4 kopplingar mot servern samtidigt, vilket gör att du har 4 köer som hämtar html/bilder/css/javascript/whatever. Har du stora bilder så är det en sak. Men har du många små bilder så blir det en anhopning förfrågningar på scriptet och då kommer scriptet vara avsevärt långsamare är httpd. Jag har inga siffror, men vi gjorde en dylik lösning för ett antal år sedan, och det är skillnad. (för besökaren that is). Det var iofs en äldre cgi installation av php. httpd har långt mer erfarenhet av att spotta ut filer. Så är det det den ska göra så rekomenderar jag att köra på "statiska" bilder. |
Som jag förstod det ska användaren kunna ladda ner bilder om vissa parametrar i hans/hennes session stämmer, inte på alla bilder som hör till designen. Om det rör alla bilder (även små) som ligger på sidan och ingår i designen bör man inte köra dem genom ett script. Men om du vill räkna antal nerladdningar mm så borde det gå bra att köra genom ett script.
|
Ett snabbt test med ApacheBench visar att det går ungefär 3 gånger snabbare att anropa bilden direkt.
Direkt: Citat:
Citat:
Citat:
Kod:
$sFilename = "./image.jpg"; |
Jag glömde ange storlek på bilden, jag testade med en JPEG på 2.2 MiB.
/ mikael |
Tack Mikael, mycket bra redovisning!
3 ggr är ganska mkt... dock är mitt problem att jag vill kunna begränsa access till vissa bilder / filer vilket avgörs i PHP-filen. Får nog ta och överväga det hela och se om det verkligen är värt det. |
Personligen tycker jag att du ska köra med PHP om du behöver begränsa tillgången som du säger. 3 gånger är INTE mycket om man tänker på vad som sker på servern när PHP används instället för att anropa bilden direkt.
Citat:
/ mikael |
Citat:
Testet borde göras om med en mindre fil (om det är mindre filer du vill accesskolla), men i det stora hela tycker jag du ska köra på en PHP lösning för att sfå den funktionalitet du vill ha. I slutänden vill du ju göra så mkt mer än att bara hämta filen. Din accesskontroll (mot DB förmodar jag) kommer sannolikt stå för större del av tiden än vad fpassthru komemr göra. |
Citat:
|
Citat:
Däremot kanske readfile() är enklare att använda här och ger lite snyggare kod. |
Citat:
Sen det där med bilden, hur snabbt det blir beror lite hur PHP är implementerat på servern. Att bara göra en bench utan att tala om något om konfigurationen säger i princip inte ett dyft. Den överheaden som tillkommer gentemot en "statisk" bild är ju först och främst att sidan måste parsas av PHP-tolken. Om det är CGI-installerad PHP så får man enorm overhead jämfört om man kör FastCGI eller som apachemodul. Den andra överheaden som tillkommer är hur optimerad din kod är. Det exempel vi såg är den enklaste och som ger minimal overhead. Sen kan det ju vara så att man vill fippla med bilden i sig och då får man använda sig av andra imagefunktioner som säkert ger ännu mer överhead. /Zoran |
Citat:
Givetvis kör jag PHP som en Apachemodul, ledsen att det inte framgick i mitt exempel. / mikael |
Vet inte hur ApacheBench funkar men är det möjligt att den cachar bilderna och därför bara får ett 304 svar? För isåfall bör man lägga in samma sak i PHP skriptet vilket är rätt enkelt gjort.
|
Jag tror inte du ska bli så förskräckt av att php tar 3 gånger längre tid på sig att läsa filen än om apache skulle göra det. Jag vet inte vilken typ av sida du driver men du tvingar användaren att bli medlem (ha seession) för att se bilden och hotlinking slipper du. Har du otur kan hotlinking göra din servern mer beslastad än vad du kan tänka dig.
|
Citat:
httpd.apache.org/docs/programs/ab.html |
Drar upp den här gamla tråden eftersom jag sitter i samma sits nu.
Jag vill alltså gärna låta PHP sköta berhörighetskontroll för bilder. Jag har kört benchmark och kommit fram till att det är hälften så snabbt att göra detta med PHP. Nu är frågan om det har hänt något på den här fronten och alltså om det finns några bra metoder att snabba upp PHP. Jag har testat olika inställningar för output buffer utan nämnvärt resultat. Kan det vara så att PHP 5 av någon anledning är snabbare på detta? Andra tips på trim uppskattas (allt från kompileringsflaggor till inställningar). Mjukvara: Linux Apache 2 (prefork MPM) PHP 4 Testkörd kod: Citat:
|
Jag använder eAccelerator som cachar phpfilerna färdigkompilerade. Detta hjälper mig en hel del. Jag vet inte hur mycket det hjälper vid bildvisning, men det är jag nyfiken på.
eAccelerator är en vidareutveckling av turckmmcache. |
Med eAccelerator tjänar jag ca. 5-7% i tid. Det medgör att det bara tar 60% mer tid med PHP. Hur jag kunde få det till att det tog dubbelt så lång tid med PHP igår vet jag inte för det är samma kod jag kört testet på. Men men, 60% är inte så farligt mycket.
|
Hittade denna kommentar på php.net "readfile and fpassthru are about 55% slower than doing a loop with "feof/echo fread"." Vet inte om det stämmer men du skulle ju alltid kunna testa.
|
Kul att denna gamla tråden kom upp igen.
Jag håller på med ett system där jag har stått inför precis samma övervägande. För att undvika att databasen behöver tillkallas vid var bild som ska skickas till webläsaren, så funderar jag på följande. Sidan som generarar alla [img]image.php?id...[/img]-tagar kontrollerar ju även att bilden är godkänd för användarn (Annars skulle inte tagen-skrivas) Således behöver inte detta test göras fler gånger så en cache med denna information lägges i en session-variabel. Så image.php kontrollerar enbart mot databasen om bilden saknas i session-variabeln. image.php rensar även i session-variabeln när bilden visasts, för att sessions-datamängden inte ska växa ohämat. Jag har inte haft tid att testa systemets prestanda än, men jag hoppas det ska snabba upp det hela! / Lasse |
Tvartom: Jag tror inte din egen hemmagjorda cachning ger något nämnvärt i performance vinst.
För image.php måste ju läsa filen (readfile, read eller passthru) oavsett och det är där flaskhalsen ligger tror jag. Inte i hur effektivt du kollar om bilden är ok eller inte mot databasen. |
Halkade in på denna gamla tråden.
Varför inte kombinera det bästa av två världar. Låt php kontrollera om användaren får ladda ned bilden och låt apache skicka den. Jag tänker mig nått i stil med detta: Kod:
image.php Dock så kan tekniska användare hotlinka till denna bilden om de tittar på headrarna som servern skickar tillbaka. Men i slutändan är väl allt en avvägning. Edit: Formattering av pseudokod |
Men om du gör header('Location: <bildens url>'); vad hindrar då någon att gå direkt till bilden?
Däremot om man använder lighttpd kan man göra det. Då kan man göra auth-kollen i php och sen sätta headern x-sendfile vilket gör att Lighttpd kommer outputa bilden åt en. Mer info finns på http://blog.lighttpd.net/articles/2006/07/...7/02/x-sendfile. |
Citat:
Citat:
Så då är det bara att ta mitt exempel och byta ut Location mot x-sendfile och se till att modden är installerad på din Apache server. Nu är det verkligen det bästa av två världar ;) |
Testa annars xcache till php.. vilket jag tyckte gjorde mer än apc/eacc..
Ulitmat lösning - Lighttpd - php - xcache har funkar perfekt för mig.. |
Citat:
Däremot så kommer ju även prestandan bli lidande i ditt fall. Eftersom först görs anropet till PHP skriptet som kommer skicka tillbaka till besökaren att bilden finns på plats x. Och sen gör användaren ett anrop till bilden. Det gör att det kommer göras 2 anrop per bild. |
Citat:
I slutändan är ju inte PHP gjort för att skicka ut statisk data. Nu är jag inte så insatt i Keep-Alives, men säg att man sätter keep-alives till 2 sekunder. Då borde requesten för själva bilden komma i samma socket-session så att man undviker teardown och setup för en ny anslutning till servern. Hade varit väldigt skoj att bencha detta :) |
Alla tider är GMT +2. Klockan är nu 12:11. |
Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson