PHP als service om meerdere bronnen te combineren

Pagina: 1
Acties:

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Een niet veel voorkomende vorm van het gebruik van PHP is het maken van software om als service te draaien en bijvoorbeeld alle ingezonden bestandjes te verwerken. De reden hiervoor is dat PHP hier officieel niet echt voor bedoeld is. Desondanks willen wij dit toch graag hiervoor gebruiken om zo niet met meerdere verschillende talen hoeven te werken. Daarnaast hebben we een goed werkende cluster-opzet voor PHP wat ook niet onbelangrijk is.

Wat is in dit soort gevallen belangrijk, zeker als je PHP gebruikt? We hebben hier ervaring mee, en weten om te gaan met logging e.d. maar het lijkt logisch dat er toch bepaalde guidelines beschikbaar zijn om een dergelijke applicatie te ontwikkelen maar ik kan deze op dit moment niet vinden.

Concreet hebben we vraagstukjes als:
1. Welke loggingmethode gebruiken we voor errors.
2. Laat je het PHP script constant runnen en laat je deze op de één of andere manier direct input ontvangen, of laat je deze juist elke 5 seconden starten en een mapje met txt files lezen?

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28
Ik heb veel ervaring met het gebruik van PHP als directe daemon en als forking daemon en het designen van zo'n daemon; ik gebruik deze daemons als serverbeheer. Het blijkt erg goed mogelijk en helemaal niet moeilijk om dergelijke daemons in PHP te schrijven door diverse pcntl_* functies. Op je vragen:

1) Dat ligt aan de aard van de log. Errors kun je bijvoorbeeld naar het logging systeem van de distro sturen (syslog?), in een aparte logfile (daemon.log) of zelfs een aparte map met error.log (ala Apache). Ik heb persoonlijk voor de tweede methode gekozen, zodat ik alle relevante informatie in één file heb en meteen kan zien bij welk proces errors horen.

2) Dat ligt aan wat je precies wil. Timed parsing (dus waar je met een sleep() een tijdje wacht) is weliswaar efficiënt qua geheugengebruik, maar je verspilt resources als je telkens het proces moet draaien terwijl er niets te doen is. Ook is er een delay tussen het uploaden van de input en het verwerken daarvan wat ongewenst kan zijn.

Ik heb het met forking opgelost: een daemon process forkt zichzelf zodra er input komt, en het child process handelt de input af en verwerkt het. Dat is weliswaar iets zwaarder om te verwerken bij veel input (veel child processes) maar ik denk uiteindelijk wel het efficiënst voor zware taken die snel afgehandeld moeten worden.

  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 16:07

hamsteg

Species 5618

De eerste vraag is maar wat je vraagt en wilt. Ik zou gewoon syslog() gebruiken.

Het tweede is mij niet helemaal duidelijk. Je zult eigenlijk voor jezelf een aantal vragen moeten stellen:
a: hoevaak krijg je input?
b. is er sprake van noodzakelijke synchroniteit ?
c "Elke 5 seconden starten en een mapje met txt files lezen?" dat zijn veel .txt files, hoeveel verwacht je er op een dag ???
d. wat is de noodzaak tot WERKELIJKE verwerking (en dus niet:ik wil het altijd optimaal hebben)?

Afsplitsen als hierboven genoemd klinkt goed behalve als je werkelijk gemiddeld binnen vijf seconden een aantal files binnen krijgt. Maak eens eerst een grondige analyse van je datastromen en hoe je deze wilt behandelen. Is de responsetijd van 5 seconden echt nodig? Ik ken maar heel weining systemen die dat vragen ... post daarna nog eens je analyse.

... gecensureerd ...


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Versimpeld moet je het zo zien als een kassasysteem. Je tikt dus op de kassa in: "2x tosti voor tafel 10". Vervolgens komt er in de keuken een bon op het scherm te staan.

Soms krijg je dus in binnen 5 seconden bijvoorbeeld 3 bonnen tegelijkertijd, soms 10 minuten niet. Het is geen constant proces als je het zo bekijkt. Wel is een seconde of 5 a 10 tussen het invoeren en het op het parsen gewenst. Zeker omdat er nog wat andere software tussen hangt.

De werkelijke noodzaak is: 3 systemen die een andere taal spreken en waar wij een koppeling tussen gaan maken. Wij kunnen dus lezen en schrijven in de taal van deze 3 systemen en zorgen dat het zaakje gekoppeld wordt aan onze logica.

@JeRa: Super bedankt voor de termen, nu kan ik een stuk meer concreet op zoek gaan!

[ Voor 5% gewijzigd door djluc op 23-01-2007 11:43 ]


  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 16:07

hamsteg

Species 5618

Hoe worden de bonnen ingevoerd (welke taal?) dat is nog een belangrijke vraag. Het mooiste zou gewoon zijn dat je PHP kunt triggeren (POST-en van data). Dan kan het kassa script op zijn beurt weer anderen posten/triggeren (bijv. de keuken). Zoals jij het nu vertelt gaat mijn voorkeur meer uit naar een actie-reactie systeem dan een polling systeem.

... gecensureerd ...


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Actie-reactie lijkt mij inderdaad ook de mooiste oplossing, als dat natuurlijk goed in PHP te implementeren is.

Alles wordt via XML doorgevoerd, dat kunnen alle partijen aanleveren. De opzet van de XML en de gegevens daarin moeten we dus handmatig koppelen en modificeren.

  • hamsteg
  • Registratie: Mei 2003
  • Laatst online: 16:07

hamsteg

Species 5618

Keuzes zat in PHP (& Apache). Deze scripttaal is gemaakt om te reageren op (post)requests. Een fsockopen() voor posten naar een andere site / server is een eenvoudige oplossing. Al dan niet in combinatie met pcntl_fork(). Kijk eens op http://www.php.net.

Eerlijkheid gebied wel te zeggen dat dit deel van communicatie een basieke kennis/vaardigheid/inzicht van RPC (Remote Procedure Calls) vereist. Het vooraf goed definiëren van de interfaces en wat daar over heen mag gaan aan data is zeer zeker aan te raden en kijk goed wat er allemaal parallel kan en mag lopen. Als er wachtrij-en (queues) moeten worden opgebouwd zal een (centrale?) database nodig zijn.

Vergis je niet door te denken dat dit even in elkaar te zetten is want dan kun je nog wel eens lelijk je neus stoten. |:( Met name de niet recht-toe-recht-aan oplossingen gaan tijd vreten.

... gecensureerd ...


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
We hebben de tijd om het echt goed te doen, dat is een groot voordeel. Daarnaast huren we wat kennis in, maar ik moet daarvoor wel een goed inzicht zien te krijgen in de mogelijkheden hiervoor en waar op te letten. Daarnaast is dit iets wat we vaker gaan doen dus willen we zelf ook wat kennis opbouwen.

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Inmiddels een stuk verder, we gaan met PHP werken, dat is nu zeker.

Helaas werkt het fork verhaal in PHP totaal niet op Windows, daar moeten we dus een omweg voor zoeken.

Wat we eigenlijk willen is iets als:
Applicatie draait constant (service). Een andere applicatie geeft de service een invoer en deze wordt meteen verwerkt zonder dat de service hier last van heeft. Is dat een goede basis opzet? Of zouden jullie gaan pollen in een mapje o.i.d.?

Verwijderd

Ik ben niet zo'n windows persoon, maar volgens mij is het nogal lastig om onder windows een service te schrijven die acties mag doen op de desktop waarop de gebruiker is ingelogd..... tenminste ik neem aan dat er uiteindelijk iets op de desktop in de keuken moet verschijnen en dat die service daarvoor moet gaan zorgen.

Het is dan volgens mij echt makkelijker om een applicatie te schrijven die opstart bij het inloggen.

Als het niet zo is dat php interactief met desktop hoeft te zijn, dan kun je idd een service schrijven, alhoewel ik niet weet of je met php een windows service kunt bakken. Er zitten nl. nogal wat eisen aan een windows service (ik heb met Delphi weleens een windows service geschreven).

Mij lijkt trouwens een gescheduled scriptje meer dan genoeg voor jou doeleinden.

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Er is geen interactie nodig. Het programma verwerkt alleen XML bestanden.

Het nadeel van zo'n scheduled ding is de vertraging, die tickets moeten zo snel mogelijk aanwezig zijn in de keuken. Zeker als er een zware verwerking plaats vind, bijvoorbeeld een export van de gerechten, zit er een vertraging in de tickets.

(een service maken kan trouwens redelijk simpel met srvany)

[ Voor 8% gewijzigd door djluc op 02-02-2007 13:43 ]


Verwijderd

Ik snap wat je bedoelt met vertraging, het enige wat ik niet snap is hoe je dat denkt op te gaan lossen met een service.

Als je je script constant in een loopje laat om te kijken of er bestanden staan, dan gebruikt ie volgens mij nogal wat cpu tijd.

Hoe wilde je dat aanpakken in je sevice dan??

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Ik ben op zoek naar een manier dat ik kan praten tegen die service. Denk aan http://nl2.php.net/manual/nl/ref.sockets.php

  • eghie
  • Registratie: Februari 2002
  • Niet online

eghie

Spoken words!

Je zou iets als SOAP kunnen gebruiken of iets als XMLRPC. Ook een zelf bedacht protocol lukt wel via sockets. Ik zou het inderdaad iig via sockets oplossen, want dan is de applicatie/service optie niet systeem afhankelijk.

Verwijderd

Tja... dat is hartstikke goed mogelijk idd... maar dan zul je een eigen protocol moeten gaan schrijven, wat nog best lastig is, en misschien voor nogal wat bugs in je systeem kan zorgen die je later weer op moet lossen.

Dat hele protocol ontwikkelen kan je denk ik het makkelijkst oplossen door gewoon een webserver te draaien waarnaartoe die xml bestanden worden gepost en vervolgens een php script draaien die er dan vanalles mee doet.

Ik zie alleen maar voordelen hierin: 1. het is een bewezen concept en 2. Het is nog eens gratis te implementeren ook (denk aan apache + php).

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
We hebben een draaien apache php5 setup draaien op 2 servers dus dat is geen probleem. Een eigen protocol lijkt me inderdaad ook niet verstandig, soap daarentegen kan wel interessant zijn. Dat ga ik wat verder uitzoeken.

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Mm, PHP op Windows schijnt toch nogal wat beperkingen te hebben.

Waar ik mee begonnen ben ik het opzetten van een PHP socket server. Gewoon het voorbeeld van: http://www.php.net/manual/en/ref.sockets.php en daar gaat het al fout. Als je via telnet contact maakt met de server wordt er steeds slechts 1 teken gelezen. Heel vaag probleem, je kan dus niet 1 regel invoeren en dan op enter drukken maar constant worden de gegevens verzonden. Op linux werkt het prima.

Het blijkt een bug te zijn die al in 2004 bekend was maar nog steeds niet opgelost is. Weet iemand een omweg?

Toch lekker werken zo, forks werken niet, sockets werken niet...

  • Gwaihir
  • Registratie: December 2002
  • Niet online
JeRa schreef op maandag 22 januari 2007 @ 21:21:
Ik heb veel ervaring met het gebruik van PHP als directe daemon en als forking daemon en het designen van zo'n daemon; ik gebruik deze daemons als serverbeheer. Het blijkt erg goed mogelijk en helemaal niet moeilijk om dergelijke daemons in PHP te schrijven door diverse pcntl_* functies.

[..]

Ik heb het met forking opgelost: een daemon process forkt zichzelf zodra er input komt, en het child process handelt de input af en verwerkt het. Dat is weliswaar iets zwaarder om te verwerken bij veel input (veel child processes) maar ik denk uiteindelijk wel het efficiënst voor zware taken die snel afgehandeld moeten worden.
Dat klinkt wel heel goed, JeRa. Je laat dus probleemloos een PHP script dagen achtereen draaien? Dat heb ik tot nu toe nog niet aangedurfd, bang voor geheugenlekken en andere kleine bugs die gaan oplopen als zo'n script dagen draait in plaats van seconden, zoals bij PHP gebruikelijk is. Gebruik je hiervoor "gewoon" telkens de laatste stabiele PHP versie, of is het opletten geblazen bij elke upgrade?

Hoe doe je het forken precies? Start je simpelweg een nieuw commandline PHP script op en laat je het "los", of zie je kans de moeder-daemon er daadwerkelijk contact mee te laten houden, meer zoals Apache dat doet (zodat je langs die weg ook een maximum aan het aantal threads kunt stellen en zo).

Op mijn werk doen we tot nu toe alles met queues en vanaf cron gestarte verwerkers. Zelf zou ik graag naar een meer event driven actie-reactie model willen voor het oppakken van die taken. Wel wil ik graag controle houden over het aantal child-processes; wanneer de machine onder zware load staat moeten voorgrondprocessen voldoende ruimte houden en sommige achtergrond taken (prioriteit verschilt per taak) op hun beurt wachten. Voor de communicatie tussen de verwerkers gebruiken we nu een database tabel.

N.B. In tegenstelling tot de TS werk ik wel met Linux servers.

djluc: Ik snap niet helemaal hoe die bestanden jouw systeem binnenkomen. De XML berichten kunnen niet in een http post request verpakt worden? Dan onstaat een "vrij standaard" webservice, waar het forken en direct afhandelen netjes door je server wordt verzorgd.

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 30-11 12:59

LauPro

Prof Mierenneuke®

Ik gebruik zelf cron. Deze roept elke 5 minuten een PHP 'agentscript' aan. Deze 'agent' kijkt welke taken er open staan en start de eerstvolgende (en vertelt dat ook de database). Daarna wordt de taak afgehandeld. En start de volgende agent de volgende taak etc etc.

Daastnaast zit er in de agent een check die kijkt of andere agents nog draaien en wacht na een bepaald aantal agents met het spawnen van nieuwe bijv.

Het gaat bij dit keukensysteem er om om een bon uit te printen. Kan je niet beter van buitenaf (webserver) via SSH verbinding maken met die print-pc en dan de printopdracht sturen? Of de webserver en de printpc in een VPN zetten en het script gewoon in de CUPS-wachtrij de taak laten zetten. CUPS lijkt me het meest handige om al die printtaken af te handelen.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • Gwaihir
  • Registratie: December 2002
  • Niet online
Ah, die process control functies heb ik al eerder naar zitten kijken, maar deze opmerking bovenaan de pagina in de gebruiksaanwijzing schrikte me af:
Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a webserver environment and unexpected results may happen if any Process Control functions are used within a webserver environment.
Wat wordt hiermee bedoeld? Ik begrijp dat dit niet bedoeld is om te functioneren in een Apache module, maar kan ik op een machine waarop ik mod_php draai ik wel of niet gelijktijdig een CLI versie met process control gebruiken voor achtergrond taken? Het manual is hier toch wat opervlakkig. Is er een goede bron van informatie over dit gebruik van PHP elders?

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 30-11 12:59

LauPro

Prof Mierenneuke®

Het is niet de bedoeling dat je vanuit een script dat draait onder mod_php die Process Control functies gaat gebruiken. Ten eerste treed er al vrij snel een rechtenprobleem op en ten tweede moet je dat imo ook niet willen. Een bug zou kunnen betekenen dat je bijv. de webserver zelf kan afsluiten.

Die Process Control functies zijn meer bedoeld om met CLI PHP scripts andere processen te sturen. Bijvoorbeeld Apache reload na vhost-change. Echter moet je ook dit dan eigenlijk via cron ofzo aanroepen.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • Gwaihir
  • Registratie: December 2002
  • Niet online
LauPro schreef op zaterdag 03 februari 2007 @ 17:09:
Het is niet de bedoeling dat je vanuit een script dat draait onder mod_php die Process Control functies gaat gebruiken. Ten eerste treed er al vrij snel een rechtenprobleem op en ten tweede moet je dat imo ook niet willen. Een bug zou kunnen betekenen dat je bijv. de webserver zelf kan afsluiten.
Ja, dat snap ik, tot zoverre. Maar: is dat alles wat met webserver environment wordt bedoeld? Ik ben geneigd daarin te lezen: niet op een machine draaien die (ook) als webserver in gebruik is.

Een compleet losse machine voor de achtergrondtaken heb ik evenwel niet (en verwacht ik ook niet tegen te komen in de projecten waar ik aan werk). Het zou dus handig zijn als ik op dezelfde machine waar apache met mod_php draait, in CLI PHP deze functies kan gebruiken. (Achtergrond taken, gestart via cron of door een CLI proces op te starten in een script en "los" te laten, lopen toch al via CLI PHP.) Of dat veilig en verantwoord kan of niet is me, op basis van die opmerking in het manual, niet duidelijk.

Verwijderd

Gaat 't hier echt alleen om een keukenbonnetjes interface?
Dan zou ik gewoon voor file IO kiezen. De kassa (of een andere aanbieder) zet gewoon een bestandje in een samen afgesproken directory, en de keukenbon-'engine' haalt die directory eens in de 10 seconden of zo leeg en verwerkt die files.
Dat kan prima met een PHP scriptje en een cronjob, en je hebt meteen het voordeel dat kassaboeren deze manier van werken gewend zijn, dus dat interfacet lekker handig. ;)

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 15:03
Het gaat uiteindelijk een centrale dataplaats worden voor de meest cruciale database in het bedrijf. Daarnaast willen we dit gewoon uitproberen.

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28
Birdie schreef op zaterdag 03 februari 2007 @ 16:52:
[...]

Dat klinkt wel heel goed, JeRa. Je laat dus probleemloos een PHP script dagen achtereen draaien? Dat heb ik tot nu toe nog niet aangedurfd, bang voor geheugenlekken en andere kleine bugs die gaan oplopen als zo'n script dagen draait in plaats van seconden, zoals bij PHP gebruikelijk is. Gebruik je hiervoor "gewoon" telkens de laatste stabiele PHP versie, of is het opletten geblazen bij elke upgrade?
Hiervoor gebruik ik gewoon de laatste stabiele PHP versie waarbij je natuurlijk op moet letten dat alle 'exotische' extensies die je gebruikt ondersteund worden :) qua memory leaks heb ik niets gemerkt (of het is in de paar bytes), mocht dat ooit erger worden dan beperk je het door het forken natuurlijk en eventueel zou ik dan het hoofdproces om de zoveel tijd opnieuw kunnen laten starten tot er een fix is.
Hoe doe je het forken precies? Start je simpelweg een nieuw commandline PHP script op en laat je het "los", of zie je kans de moeder-daemon er daadwerkelijk contact mee te laten houden, meer zoals Apache dat doet (zodat je langs die weg ook een maximum aan het aantal threads kunt stellen en zo).
Forken werkt niet door nieuwe scripts op te starten maar door een kopie te maken van een bestaand proces (middels copy-on-write in Linux). Ik geef de child processes éénmalig de benodigde informatie mee om een request af te handelen (socket pointer, identifier, etc) en ze sterven daarna gewoon weer af. Er is geen Inter Process Communication, als je dat bedoelt. Het maximaal aantal threads bepaal ik dan ook vanuit het hoofdproces; nieuwe threads worden bij een maximum gewoon niet gestart. :)
Pagina: 1