Det ser ud til, at du forsøger at starte langvarige processer fra en webserver og derefter spore disse processer i en database. Det er ikke umuligt, men ikke en anbefalet praksis.
Hovedproblemet er, at en HTTP-anmodning i øjeblikket skal håndteres på din webserver, for du gør det alt (herunder spore processer, der kører på systemet) -- du har brug for noget, der kan køre hele tiden...
I stedet ville en bedre idé være at få en anden dæmoniseret "manager"-proces (som du nævner perl, det ville være et godt sprog at skrive det på) til at spawne og spore de langvarige opgaver (ved PID og signaler), og for det proces for at opdatere din SQL-database.
Du kan derefter få din "manager"-proces til at lytte efter anmodninger om at starte en ny proces fra din webserver. Der er forskellige IPC-mekanismer, du kan bruge. (fx:signaler, SysV shm, unix domæne sockets, igangskøer som ZeroMQ osv.).
Dette har flere fordele:
- Hvis dine affødte scripts skal køre med bruger-/gruppebaseret isolation (enten fra systemet eller hinanden), så behøver din webserver ikke at køre som root eller være setgid.
- Hvis en affødt proces "crasher", vil et signal blive leveret til "manager"-processen, så den kan spore fejludførelser uden problemer.
- Hvis du bruger igangskøer (f.eks. ZeroMQ) til at levere anmodninger til "manager"-processen, kan den "drossele" anmodninger fra webserveren (så brugere ikke med vilje eller ved et uheld kan forårsage D.O.S).
- Uanset om den affødte proces ender godt eller ej, behøver du ikke en "aktiv" HTTP-anmodning til webserveren for at opdatere din sporingsdatabase.
Om noget, der bør be running is running, det er virkelig op til din semantik. (dvs.:er det baseret på en kendt køretid? baseret på forbrugte data? osv.).
Kontrollen om det er løb kan være dobbelt:
- "Manager"-processen opdaterer databasen efter behov, inklusive det affødte PID.
- Din webserver-hostede kode kan faktisk vise processer for at afgøre, om PID'et i databasen er faktisk kører, og endda hvor lang tid den har gjort noget nyttigt!
Tjek om det er ikke løb skal være baseret på konventionen:
- Navngiv de affødte processer noget, du kan forudsige.
- Få en procesliste for at finde ud af, hvad der stadig kører (nedlagt?), som ikke burde være det.
I begge tilfælde kan du enten informere de brugere, der har anmodet om, at processerne blev afledt og/eller faktisk gøre noget ved det.
En tilgang kan være at have et CRON-job, som læser fra SQL-databasen og laver ps
for at bestemme, hvilke afledte processer, der skal genstartes, og anmoder derefter igen om, at "manager"-processen gør det ved hjælp af den samme IPC-mekanisme, som bruges af webserveren. Hvordan du skelner mellem start og genstart i din sporing/overvågning/logning er op til dig.
Hvis serveren selv mister strøm eller går ned, kan du få "manager"-processen til at udføre oprydning, når den først kører, f.eks.:
- Søg efter indgange i databasen for afledte processer, der angiveligt kørte, før serveren blev lukket ned.
- Se efter disse processer ved PID og kørselstid (dette er vigtigt).
- Genoptag enten de affødte processer, der ikke blev fuldført, eller gem noget i databasen for at indikere over for webserveren, at dette var tilfældet.
Opdatering #1
I henhold til din kommentar er her nogle tips til at komme i gang:
Du nævnte perl, så forudsat at du har nogle færdigheder der -- her er nogle perl-moduler til at hjælpe dig på vej til at skrive "manager"-processcriptet:
Hvis du ikke allerede er bekendt med det CPAN er repository for perl-moduler, der gør stort set alt.
Daemon::Daemonize - At dæmonisere processen, så den fortsætter med at køre, efter du har logget ud. Giver også metoder til at skrive scripts for at starte/stoppe/genstarte dæmonen.
Proc::Spawn
- Hjælper med at 'afføde' børnescripts. Grundlæggende gør fork()
derefter exec()
, men håndterer også STDIN/STDOUT/STDERR (eller endda tty) af underordnet proces. Du kan bruge dette til at starte dine langvarige perl-scripts.
Hvis din webserver-frontend-kode ikke allerede er skrevet i perl, skal du bruge noget, der er ret bærbart til meddelelsesoverførsel mellem processer og kø; Jeg ville sandsynligvis lave din webserver-frontend i noget, der er nemt at implementere (som PHP).
Her er to muligheder (der er mange). mere):
- Perl og PHP implementeringer til Spread Toolkit .
- Perl og PHP implementeringer til ZeroMQ bibliotek.
Proc::ProcessTable - Du kan bruge dette tjek på kørende processer (og få alle slags statistikker som diskuteret ovenfor).
Tid::HiRes - Brug tidsfunktionerne med høj granularitet fra denne pakke til at implementere din 'throttling'-ramme. Grundlæggende skal du blot begrænse antallet af anmodninger, du sætter i kø pr. tidsenhed.
DBI (med mysql ) - Opdater din MySQL-database fra "manager"-processen.