Apache Speedup

Door Cruz op dinsdag 26 mei 2009 18:56 - Reacties (7)
Categorie: Willekeurig, Views: 6.306

Zoals in eerdere posts beschreven sleutel ik aan een web-based applicatie. Nu valt er altijd wel wat aan de performance te verbeteren, door minder databasequeries toe te passen etc, maar ik las in een JSMin+ blogpost van crisp dat er een plugin voor een plugin van firefox is (YSlow voor Firebug) die de performance beoordeeld.

Dit gebeurt door middel van een handige scorekaart, dit is een voorbeeld resultaat (en tevens mijn eindresultaat):
http://www.urdland.com/images/yslow_klein.png
(Klikbaar voor groter plaatje)

Hierbij is een Content Delivery Network niet relevant voor een lokale webapplicatie, en met Expires-headers heb je eigenlijk geen ETags nodig. Cookie-free domains wil zeggen dat je plaatjes e.d. op een ander domein zet zodat bij GET requests vanuit de browser niet elke keer de inhoud van het cookie wordt meegestuurd: ook dit is niet relevant voor een lokale webapp.

Wat in eerste instantie een slechte score kreeg, zijn de volgende items:
  • Add Expires headers
  • Compress components with gzip
En deze zijn dus eenvoudig op te lossen door de apache configuratie te tweaken!

Om voor het nageslacht vast te leggen wat ik gedaan heb beschrijf ik dit in deze blogpost. Hierbij moet ik wel een belangrijke disclaimer plaatsen: Ubuntu 8.04. Als je zelf een andere distro gebruikt kan het zijn dat je andere commando's moet gebruiken.
Add Expires headers
Zonder expires-headers weet een browser niet hoe lang hij een object (webpagina, plaatje etc) moet cachen. Standaard laadt een browser aan het begin van een sessie alles, vervolgens worden plaatjes/js/css etc tijdens de duur van de sessie gecached. Dat betekent dat er over een sessie heen niets wordt gecached... Beetje zonde! En daarom gaan we de mod_expires installeren :D
Het grote voordeel: Snellere laadtijden
Het grote nadeel: Soms verouderde informatie

Installatie gaat makkelijk via het a2enmod commando:

code:
1
sudo a2enmod expires



Tot zo de installatie, nu nog het belangrijkste - de configuratie:
Bestand: /etc/apache2/apache2.conf
Locatie: In hoofd-scope

code:
1
2
3
4
5
6
7
8
9
10
11
ExpiresActive On
ExpiresDefault "now"
expiresbytype image/gif "access plus 7 days"
expiresbytype image/jpg "access plus 7 days"
expiresbytype image/png "access plus 7 days"
expiresbytype text/html "access plus 6 hours"
expiresbytype text/txt "access plus 6 hours"
expiresbytype text/js "access plus 7 days"
expiresbytype text/css "access plus 7 days"
expiresbytype text/javascript "access plus 7 days"
expiresbytype application/x-javascript "access plus 7 days"



Bovenstaande zorgt ervoor dat standaard bestanden niet worden gecached. Voor de belangrijkste bestandstypes zijn vervolgens uitzonderingen gemaakt, HTML en tekst mag elke 6 uur opnieuw worden opgevraagd door de browser, CSS, JS en plaatjes veranderen maar zelden dus die mogen na 7 dagen uit de cache worden gegooid.
Compress components with gzip
Gzip is een compressie-algoritme. Als je deze aan apache toevoegt wil dat zeggen dat apache niet de originele data maar de gecomprimeerde data naar de browser van een bezoeker stuurt. Deze browser pakt het dan automatisch uit en geeft het weer.
Het grote voordeel: Minder bandbreedte nodig
Het grote nadeel: Extra CPU belasting van server (en client)

Vroeger heette deze apache mod 'mod_gzip' maar sinds apache 2 heet het 'mod_deflate'. Het is te installeren met de volgende opdracht:


code:
1
sudo a2enmod deflate



Nu zit de module in apache, maar het is nog niet geconfigureerd. Omdat het geen zin heeft om plaatjes te gzippen (die zijn al gecomprimeerd) kiezen we voor de volgende configuratie:
Bestand: /etc/apache2/mods-enabled/deflate.conf
Locatie: In <ifmodule> scope

code:
1
2
3
4
5
6
7
8
9
10
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript

# Voor logging (kan weg als je weet dat alles goed werkt:
# Begin logging stuk
DeflateFilterNote Input input_info
DeflateFilterNote Output output_info
DeflateFilterNote Ratio ratio_info
LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
CustomLog /var/log/apache2/deflate_log deflate
# Eind logging stuk



Nu is er standaard 1 probleem.... Apache weet niet welke bestanden als text/css of text/javascript of application/x-javascript worden verzonden. Daarvoor moeten we een kleine aanpassing doen:
Bestand: /etc/apache2/mods-enabled/mime.conf
Locatie: In hoofd-scope

code:
1
2
AddType text/css .css
Addtype application/x-javascript .js



Nu snapt apache dat alle .css bestanden van het mime-type text/css zijn, etc.

Dan rest nog 1 taak: Apache herstarten zodat de wijzigingen van kracht worden:

code:
1
sudo apache2ctl restart


Zo! Performance getweakt = mission complete! :D

Usenet 4 dummies

Door Cruz op vrijdag 22 mei 2009 12:07 - Reacties (23)
Categorie: URD, Views: 9.227

Na het plaatsen van de eerste blogpost ontdekte ik al meteen een bugje die ervoor zorgde dat de lettergrootte van reacties niet in te stellen is via CSS beheer. Crisp heeft het inmiddels gefixt dus \o/ het ziet er weer wat beter uit nu. Blijkbaar ben ik de eerste die de reactie lettergrootte heb gewijzigd :D

Maar genoeg over de vorige post, nu is het tijd voor... Usenet voor dummies!
Introductie
Usenet is een internetdienst waarmee gebruikers elkaar berichten kunnen sturen, een soort kruising tussen email en een forum. Dat was in ieder geval de oorspronkelijke opzet ;)

Om het overzichtelijk te houden is er een onderverdeling gemaakt. Zoals je bij tweakers.net een forum hebt voor hardware zaken en een forum voor software zaken heb je bij usenet zogenaamde 'nieuwsgroepen'. Een aantal voorbeelden hiervan:
  • misc.sci.chem
  • comp.lang.c
  • alt.binaries.pictures.wallpaper
Hiervoor geldt dat alle nieuwsgroepen die met 'alt.' beginnen, over het algemeen niet worden gemodereerd door iemand die bepaalt wat wel en niet gepost mag worden.

Omdat het een supercomputer en een enorme internetverbinding vereist als alle eindgebruikers op 1 systeem hun berichten plaatsen, maakt het usenet gebruik van een heleboel servers. Deze worden nieuwsservers genoemd.
Om te illustreren hoe dat werkt heb ik een tekeningetje gemaakt:

http://www.urdland.com/images/usenet.png

Hierbij zijn er 4 nieuwsservers (1,2,3,4) en de rode blokjes zijn eindgebruikers die via een usenet client berichten plaatsen in bijvoorbeeld comp.lang.c.
  • Een gebruiker die op server 3 is aangesloten stuurt een bericht naar comp.lang.c
  • Server 3 stuurt dit bericht door naar servers 1 en 4, die het allebei doorsturen naar server 2
  • Een gebruiker die op server 4 is aangesloten vraagt de nieuwe berichten van comp.lang.c op
  • Server 4 stuurt het zojuist geplaatste bericht naar de eindgebruiker
De berichten (voor usenet wordt de benaming "artikelen" gebruikt) worden zo dus voor iedereen beschikbaar gemaakt. Feitelijk is het een variant op email waarbij je het niet naar een eindgebruiker stuurt maar naar een centrale database waar iedereen toegang toe heeft. Als gebruiker heb je een usenet-client en daarin abonneer je jezelf op een aantal nieuwsgroepen die je interessant vindt. Vervolgens haalt jouw client de artikelen op van de nieuwsserver waar je toegang tot hebt.

In eerste instantie vraagt de client alleen de headers van de berichten op, dus de naam van de persoon die het heeft gepost, het onderwerp etc. De inhoud van de berichten wordt pas gedownload als je dat handmatig bevestigd, dit om verspilling van bandbreedte te voorkomen.
Retentie
Omdat een usenet-server maar een beperkte capaciteit heeft, worden oude artikelen na verloop van tijd weggegooid. De tijd waarover artikelen beschikbaar zijn voor eindgebruikers wordt de retentietijd genoemd. Met een langere retentietijd, of ook wel gezegd met een grotere retentie, is er meer informatie beschikbaar.
Binaire data
Usenet was dus bedoeld om tekstberichten uit te wisselen. Maar het zou natuurlijk ook handig zijn als je soms een (binair) bestand kan versturen, bijvoorbeeld een C-programma in plaats van alleen broncode. Usenet ondersteunt echter alleen 7-bit US ASCII karakters (dus alleen normale leestekens). Om dit toch mogelijk te maken hebben mensen wat trucs bedacht. Door de binaire data om te zetten in leesbare tekst, en er een soort label voor te zetten, kan toch binaire data geplaatst worden. Hiervoor zijn verschillende functies geschikt, zoals UUencoding, Base64 encoding en yENC, waarvan de laatste het meest efficient is.

Een ander probleem is dat een deel van de usenet servers een limiet aan de grootte van een artikel hanteren: naast het omzetten van binaire data naar tekst moet die tekst ook worden opgesplitst in meerdere artikelen. Dit is weergegeven in onderstaand plaatje.

Je begint met binaire data, dat wordt omgezet in leesbare tekst, en opgesplitst in stukken die in 1 artikel passen.

http://www.urdland.com/images/usenet2.png

De ontvanger van die artikelen volgt het omgekeerde proces om tot de oorspronkelijke data te komen.
Robuustheid
Helaas komt het wel eens voor dat bepaalde artikelen verdwijnen bij het synchroniseren tussen verschillende usenet-servers. Als het niet al te veel moeite is kan de originele poster een zogenaamde 'repost' doen waarbij hij hetzelfde bestand nogmaals plaatst. Maar voor grote bestanden is dat natuurlijk niet praktisch. Daarom wordt er gebruik gemaakt van Par2 (Par1 werd oorspronkelijk gebruikt maar is vervangen door het veel beter werkende Par2).

Dit is een algoritme dat informatie over de te versturen data in een aantal par2-bestanden plaatst. Als nu enkele artikelen zijn weggevallen kunnen de par2-bestanden worden gebruikt om de verloren informatie terug te halen.
Bestanden downloaden
Stel, iemand heeft 1G aan data geplaatst in een nieuwsgroep. Die data bestaat uit 100 bestanden, 90 rar-bestanden van 10MB plus 10 Par2 bestanden van 10MB. Deze staan verspreid over zo'n 4000 artikelen, maar gelukkig brengen de meeste usenet-clients dit weer terug tot 100 berichten. Elk bericht heeft een onderwerp dat bestaat uit de bestandsnaam van de artikelen die erin zijn samengevat.

Handmatig downloaden van die 100 berichten is een kwestie van selecteren en op downloaden klikken. Maar stel dat je een bestand wil hebben waarvan je weet dat het in een nieuwsgroep staat waar je niet op geabonneerd bent, en die zo groot is dat alleen het downloaden van de headers al een halve dag gaat duren. Dan zou het handig zijn als je precies wist welke artikelen je van de nieuwsserver op moet vragen.

Om dat probleem te tackelen is het .nzb bestandsformaat opgezet. In een NZB bestand staat een verzameling van artikel-identifiers die vervolgens direct vanaf de nieuwsserver gedownload kunnen worden.

Het is dan niet nodig om je te abonneren op een nieuwsgroep, en alle headers op te halen maar gewoon 'klik' en 'download'. Deze NZB bestanden zijn daarom erg populair. Je kan het vergelijken met een .torrent bestand: er staan verwijzingen in waar informatie te verkrijgen is.
Usenet-clients
Er zijn een boel verschillende usenet-clients, de belangrijkste verschillen zijn:
  • Het besturingssysteem waarvoor ze geschikt zijn
  • Ondersteuning voor tekstberichten
  • Ondersteuning voor binaire bestanden
  • Automatisch uitpakken/repareren van binaire bestanden
  • Command-line, Grafische client en/of via een webinterface
URD, waaraan ik dus knutsel, is voor linux, werkt via een webinterface en kan alles met binaire bestanden :)

PS: Mocht er iets niet kloppen, lemme know en ik fix het!

My First Blogpost

Door Cruz op donderdag 21 mei 2009 00:15 - Reacties (11)
Categorie: Willekeurig, Views: 6.660

Inderdaad!

Vanmiddag besloten om toch maar eens een tweakblog te beginnen. Probleem 1: Niet genoeg karma! Karma is a bitch maar ja.. toch eraan moeten geloven; aan de slag gegaan met 2 product reviews en de benodigde 1500 karmapunten waren zo binnen. (Voor de geinteresseerden: Logitech G15 en de WD Velociraptor)

Toen aan het pielen met de layout, in Photoshop een header in elkaar gedraaid en voila! Ik ben mijn eerste blogbericht aan het schrijven. De keuze tussen English of Nederlands was een lastige, uiteindelijk toch maar voor NL gekozen maar misschien dat ik er soms iets anglisaksisch doorheen gooi ;)

Voor zover de boring 13-in-een-dozijn introductie! Waar ben ik in hemelsnaam mee bezig?

Qua arbeid
TNO ICT, afdeling security, als security consultant. Vooropgesteld: Alles wat ik hier schrijf is uit persoonlijke titel. Ik heb het erg naar mijn zin bij TNO en wil die baan graag houden ;)

Wat ik daar doe? Van alles, en dat is het mooiste van TNO. De ene keer doe je een risicoanalyse op een nieuwe dienst, dan help je mee om een kantoorautomatiseringstraject te begeleiden vanuit het beveiligingsoogpunt en dan moet je proberen in te breken op een heel belangrijke webapplicatie. Ik blijf leren en groeien, en dat in combinatie met een goeie werksfeer en leuke collega's en een niet-onverdienstelijk salaris maakt dat ik het naar mijn zin heb :) En er zijn nog vacatures dus... :P

Qua hobby
Ik probeer een klein beetje conditie vast te houden door wekelijks in het doel te staan bij een plaatselijke voetbalclub. Dat gaat redelijk, dit seizoen eindigen we ~ 5e van de 12 dus een soort van subsubtopper :) Niveau 7e klasse reserve, dus niet dat we goed zijn of zo ;)

Daarnaast speel ik wat computerspellen, voornamelijk UT2k4 en af en toe L4D. Titan Quest ben ik momenteel ook mee bezig, die RPG's zijn zo gruwelijk verslavend :(

En tot slot, last but definitely not least, URD! In een toekomstige post meer daarover, maar een collega vroeg zo'n jaar geleden of ik hem wilde helpen bij het schrijven van een NZB downloader in PHP. Dat leek me wel grappig en inmiddels is URD (Usenet Resource Downloader) gegroeid van een paar PHP scriptjes die een HellaNZB backend aansturen tot een complete webapplicatie. Meer info staat op de website urdland.com (helaas was urd.com al bezet, gek genoeg ;)), waaronder screenshots etc.