Sådan optimerer du hastigheden på PHP med køsystem

I artikelserien "Hastighedsoptimering af PHP" går jeg i dybden med, hvordan man bygger hurtige og skalerbare PHP applikationer. Det er ikke en masse tips til små optimeringer, men håndgribelige metoder til at undgå flaskehalse og suboptimal kode.

Artiklerne omhandler udelukkende god eksekveringstid på dine PHP scripts. Vil du forbedre din hjemmesides overall loadtid, så start på PageSpeed Insights, eller se i din browsers Netværks-fane for nogle lavthængende frugter - det er ikke lige det, denne artikelserie handler om.

Artikler i serien:


Mange opgaver kan udføres, uden brugeren af din webapplikation behøver vente imens. Låser du brugeren, mens der fx afsendes e-mail, så giver jeg dig nu opskriften på, hvordan du kan gøre det smartere.

Med det rigtige setup, kan du give en sømløs brugeroplevelse – uden at forsinke udførelsen af opgaver.

Køsystem

Et køsystem er et system, der kan sætte en række opgaver i kø til senere udførelse.

Grundprincippet i forbindelse med hastighedsoptimering er, at alle opgaver, der ikke nødvendigvis skal udføres med det samme, lægges i køen.

En forespørgsel til fx en SMTP server kan hurtigt have en svartid på 50 ms + tiden til processering. Dette sparer du stortset brugerne helt for (der er dog en lille tidsomkostning forbundet med at lægge i kø, men den er minimal).

Din server vil selvfølgelig skulle bruge tiden på at udføre opgaven efterfølgende, men din bruger bliver ikke belastet.

Konceptet: simpelt køsystem

Du kan lave dit eget simple køsystem blot med en databasetabel og en cronjob, der løbende lytter på, om der er nye ikke-udførte opgaver i køen:

id     | queued_at           | executed_at         | function          | data
5      | 20XX-07-21 09:59:00 | null                | send_email        | {recipient: 'receiver@justiversen.dk', headline: '..', body: '..'}
4      | 20XX-07-21 09:57:50 | 20XX-07-21 09:57:52 | send_email        | {recipient: 'receiver@justiversen.dk', headline: '..', body: '..'}
3      | 20XX-07-21 09:57:48 | 20XX-07-21 09:57:52 | send_email        | {recipient: 'receiver@justiversen.dk', headline: '..', body: '..'}
2      | 20XX-07-21 09:56:34 | 20XX-07-21 09:56:38 | send_email        | {recipient: 'receiver@justiversen.dk', headline: '..', body: '..'}
1      | 20XX-07-21 09:53:10 | 20XX-07-21 09:53:12 | send_email        | {recipient: 'receiver@justiversen.dk', headline: '..', body: '..'}

Cronjobbet kalder blot funktionen fra feltet function med de givne data, der ligger i feltet data. Når jobbet er udført opdaterer den executed_at feltet.

Cronjobbet processerer kun opgaver, hvor executed_at har en null-værdi.

Det er i princippet, hvad der skal til.

I ovenstående er der dog ikke taget højde for

  • Hvordan og hvornår cronjobbet skal køre og lytte efter nye opgaver
  • Hvad der sker, hvis flere kører cronjobbet samtidig
  • Mulighed for at skalere over flere servere
  • Ingen notering af, om et cronjob har påbegyndt en opgave
  • Hvad der sker, hvis serveren går ned midt i operationen

Derudover skal du selv til at skrive koden til dit nye simple køsystem. Min anbefaling til dig er derfor at vælge en af de eksisterende løsninger.

Beanstalkd (pheanstalk til PHP) er et modent og stabilt køsystem, med en veludbygget API og udmærket dokumentation.

Som en del af Amazons populære serverløsninger findes også Amazon SQS, der løfter samme opgave. Det er let at implementere med færdigskrevne PHP-pakker, ligesom der findes færdige pakker til de andre løsninger derude.

Løsningerne er i bund og grund ikke så forskellige, så find en der passer godt til dit setup. Jeg er sikker på, at du og dine brugere bliver glade for dit nye køsystem.

Har jeg fat i noget? Eller er der fejl? Lav en pull request til artiklen på GitHub, hvis der er noget, du mener, skal være anderledes.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *