Warteschlange für Downloads
Ethrandil
- php
Hallo,
was ich gerne realisieren würde ist eine Warteschlange für Downloads.
Ähnliches in aufwändiger Form gibt es z.B. bei http://www.fileshack.com .
Zur not stünde auch eine MySQL-DB zur verfügung, andere Lösungen wären natürlich vorzuziehen.
Noch eine Frage zu PHP (ich bevorzuge Java ... ): Kann man die Script-instanzen, die beim Aufruf der Seite gestartet werden, irgendwie synchronisieren? Gibt es globale Variablen (also instanz und script übergreifend)
Und: Ja, ich hasse PHP, aber ist schön leicht ;)
und nochwas: Um die Warteschlange zu realisieren müsste man irgendwie feststellen: a) Wieviele downloads laufen
und / oder b) Wann und ob ein Download läuft.
Wie geht das?
Hi!
was ich gerne realisieren würde ist eine Warteschlange für Downloads.
Ähnliches in aufwändiger Form gibt es z.B. bei http://www.fileshack.com .
Also ich denke mit PHP ist das nicht ganz so einfach, vor allem da die Scripte meist stark laufzeitbegrenzt sind. Normalerweise kann man nicht 10 Minuten lang in einer Warteschleife bleiben, also mit einem Script, sondern man muss nach einer bestimmten Zeit das Script beenden und an ein weiteres Script übergeben. Dazu kommt das Problem, dass man eigentlich nicht wirklich sagen kann wann ein download zu Ende ist, die einzieg Möglichketi die mir einfällt wäre mit fpassthru(), damit gibst Du Dateien über ein PHP-Scipt aus, problematisch an der Sache, wenn der download ein paar Minuten dauert bekomst Du Probleme mit der Laufzeit. Naja, abgesehen davon würde ich eine Wartechlange wie folgt realisieren: Sagen wir mal du willst 10 Downloads gleichzeitg erlauben, dann würde ich in ein bestimmtes verzeichnis 10 Dateien legen, z.B. dl_01.active... bis dl_10.active, und bei einem Downlaod immer eine neue Datei erstellen, und beim beenden die Datei wieder löschen. Andere Requests prüfen dann ob alle 10 Dateien belegt sind, wenn neun wird eine der nict verwendeten Dateien erstellt, wenn ja wird gewartet.
Aber da das vermutlich nicht funktionieren wird (schon aufgrund der Laufzeitbegrenzung der Scripte), würde ich evtl. eher mit einer Durchschnittsdownload-Rate rechnen, und die "download-slots" dem entsprechend verteilen, die Download-Zeit würde ich also mit der Dateigröße ermitteln. Naja, vielleicht kennt ja jemand eine besseren weg.
Noch eine Frage zu PHP (ich bevorzuge Java ... ): Kann man die Script-instanzen, die beim Aufruf der Seite gestartet werden, irgendwie synchronisieren? Gibt es globale Variablen (also instanz und script übergreifend)
Wieso sollte man das tun? Was für Daten würdest Du in die globalen Variablen schreiben? Würden die während der Laufzeit eines Scriptes verändert oder was? Aber was willst Du da synchronisieren?
und nochwas: Um die Warteschlange zu realisieren müsste man irgendwie feststellen: a) Wieviele downloads laufen
und / oder b) Wann und ob ein Download läuft.Wie geht das?
Nur wenn Du volle Gewalt über die PHP-Konfiguration hast(Scriptlaufzeiten...)
Grüße
Andreas
Also ich denke mit PHP ist das nicht ganz so einfach, vor allem da die Scripte meist stark laufzeitbegrenzt sind.
Ja, außerdem kann es sein, das da sehr große Dateien bei sind (200 Mb) die will ich nicht alle 10 mal kopieren. Für den Download wollte ich eigentlich apache verwenden, nicht ein weiterleitendes PHP-Script
Aber da das vermutlich nicht funktionieren wird (schon aufgrund der Laufzeitbegrenzung der Scripte), würde ich evtl. eher mit einer Durchschnittsdownload-Rate rechnen, und die "download-slots" dem entsprechend verteilen, die Download-Zeit würde ich also mit der Dateigröße ermitteln. Naja, vielleicht kennt ja jemand eine besseren weg.
Noch eine Frage zu PHP (ich bevorzuge Java ... ): Kann man die Script-instanzen, die beim Aufruf der Seite gestartet werden, irgendwie synchronisieren? Gibt es globale Variablen (also instanz und script übergreifend)
Wieso sollte man das tun? Was für Daten würdest Du in die globalen Variablen schreiben? Würden die während der Laufzeit eines Scriptes verändert oder was? Aber was willst Du da synchronisieren?
Beispielsweise einen LOCK, der dafür sorgt, dass nur ein script gleichzeitig auf eine Datei zugreift...
und nochwas: Um die Warteschlange zu realisieren müsste man irgendwie feststellen: a) Wieviele downloads laufen
und / oder b) Wann und ob ein Download läuft.Wie geht das?
Nur wenn Du volle Gewalt über die PHP-Konfiguration hast(Scriptlaufzeiten...)
hätte ich, aber das ist ja auch ne sicherheitslücke ...
Also, bei der oben angesprochenen Lösung (fileshack) funktioniert das ganhze oberflächlich so: Ein User connected auf die Downloadseite. Da sieht er eine Ansicht, die ihm sagt er ist der x. in der Warteschlange. Diese Seite updated sich selber alle 2ß sec. Nach den 20 sec kommt entweder na andere Warteschlangennummer, oder ein Download beginnt.
So habe ich mir das auch vorgestellt, nur: Wie kann ich die user speichern, die in ner Warteschlange sind (ZB Global =) ) Und wie bekomme ich heraus, ob die leute aus meinem Tollen System ausgestiegen sind.
Mir Viele da folgendes ein:
Ein PHP-Script, dass jedem user erstmals ne eindeutige ID zuweist. Über diese ID wird er eindeutig in die Warteschlange eingeordnet.
Wenn er nicht regelmäßig auf der Seite reloaded (was sie ja von alleine macht) dann verfällt seine ID.
Allerdings bräuchte ich ja eine art Aufräumprozess, der die IDs nach abgelaufenem Timeout entfernt...
Mit MySQL würde das sicherlich gehen (zusammen mit nem Java-Daemon zB) Aber ich kenne mich da nicht sooo aus.
Moin!
Also, bei der oben angesprochenen Lösung (fileshack) funktioniert das ganhze oberflächlich so: Ein User connected auf die Downloadseite. Da sieht er eine Ansicht, die ihm sagt er ist der x. in der Warteschlange. Diese Seite updated sich selber alle 2ß sec. Nach den 20 sec kommt entweder na andere Warteschlangennummer, oder ein Download beginnt.
Mal so ganz dumm und ketzerisch gefragt: Wozu soll diese tolle Warteschlange überhaupt gut sein?
Ich habe sowas nur einmal selbst erlebt bei einer großen Firma in deren Downloadbereich und mich da auch gefragt, wozu das gut sein soll. Es hat mich eigentlich nur genervt. Ich will bei einem Download eigentlich nur sofort die Datei kriegen und deren Speicherort festlegen - wie lange der Download dann dauert, ist mir eigentlich ziemlich Banane. Aber mit so einer dummen Warteschlange muß ich erstmal ewig warten, bis ich den Download auf meiner Seite mit "Speichern unter..." abschließen kann, um mich anderen Dingen zuzuwenden.
Wenn du also einfach auf jegliche Warteschlange verzichtest, kriegen die Interessenten die Daten eben so langsam, wie die Internet-Anbindung des Servers ist. Aber sie kriegen dann immerhin eine Anzeige mit, wie schnell die Datei dann bei ihnen ist (die Browser rechnen meist eine Zeitdauer aufgrund der bisherigen Datenrate und der gesendeten Dateigröße aus).
- Sven Rautenberg
Hi!
Wenn du also einfach auf jegliche Warteschlange verzichtest, kriegen die Interessenten die Daten eben so langsam, wie die Internet-Anbindung des Servers ist. Aber sie kriegen dann immerhin eine Anzeige mit, wie schnell die Datei dann bei ihnen ist (die Browser rechnen meist eine Zeitdauer aufgrund der bisherigen Datenrate und der gesendeten Dateigröße aus).
Da stimme ich Dir voll und ganz zu, IMHO wird das ganze vielleicht sogar noch schneller da diese Refresh-Requests und der PHP/MySQL-Overhead wegfallen ;-)
Grüße
Andreas
Moin!
Also, bei der oben angesprochenen Lösung (fileshack) funktioniert das ganhze oberflächlich so: Ein User connected auf die Downloadseite. Da sieht er eine Ansicht, die ihm sagt er ist der x. in der Warteschlange. Diese Seite updated sich selber alle 2ß sec. Nach den 20 sec kommt entweder na andere Warteschlangennummer, oder ein Download beginnt.
Mal so ganz dumm und ketzerisch gefragt: Wozu soll diese tolle Warteschlange überhaupt gut sein?
Das ganze soll primär auf einer Größeren LAN-Veranstaltung zur Verteilung von Treiber(-paketen) genutzt werden.
Da nervt es einfach, wenn der Server diverse Downlloads hat, zumal der Uplink von switch zu switch nur 100 MBit groß ist.
Die Dateien sollten wenn dann schnell da sein, und das netz nicht allzudoll belasten.
Mhhhhhh.......................... Gibt es vielleicht ne Config von Apache, um die maximalen Downloads zu begrenzen ........
Hi!
Das ganze soll primär auf einer Größeren LAN-Veranstaltung zur Verteilung von Treiber(-paketen) genutzt werden.
200MB große Treiber?
Da nervt es einfach, wenn der Server diverse Downlloads hat, zumal der Uplink von switch zu switch nur 100 MBit groß ist.
Da bringt Dir so ne Warteschlange herzlich wenig, es wird immer dei maximal verfügbare Rate verwendet.
Die Dateien sollten wenn dann schnell da sein, und das netz nicht allzudoll belasten.
Was ist der Unterschied einen langen langsameren Download zu haben, gegenüber einem langen Warte-Fenster mit schnellem download was auch nicht schneller ist, eher im Gegenteile!
Mhhhhhh.......................... Gibt es vielleicht ne Config von Apache, um die maximalen Downloads zu begrenzen ........
Im Apachen weiß ich nicht, es sollte auf Betriebssystem-Ebene gehen.
Grüße
Andreas
Mhhhhhh.......................... Gibt es vielleicht ne Config von Apache, um die maximalen Downloads zu begrenzen ........
Im Apachen weiß ich nicht, es sollte auf Betriebssystem-Ebene gehen.
Sicher nicht =)
Das OS hat ja den Webserver net integriert ...
Ich meine die ANzahl der Downloads, nicht die Datenrate
DAs funktioniert mit MayClients = x , Zählt aber auch für html-seiten ..... mal schaun.
Hi!
Sicher nicht =)
Das OS hat ja den Webserver net integriert ...
Ich meine die ANzahl der Downloads, nicht die Datenrate
DAs funktioniert mit MayClients = x , Zählt aber auch für html-seiten
Ich meinte jetzt die Begrenzung des Traffics.
Grüße
Andreas
Moin!
Das ganze soll primär auf einer Größeren LAN-Veranstaltung zur Verteilung von Treiber(-paketen) genutzt werden.
Da nervt es einfach, wenn der Server diverse Downlloads hat, zumal der Uplink von switch zu switch nur 100 MBit groß ist.
Die Dateien sollten wenn dann schnell da sein, und das netz nicht allzudoll belasten.
Ok, das sind interessante Zusatzinformationen, die die zu findende Lösung eindeutig beeinflussen werden.
Mal so ganz dumm überlegt: Wenn du meinst, die Pakete sollen wenn, dann schnell da sein - dann willst du sicherlich volle Bandbreite für den jeweiligen User haben. Das belastet dann das Netz aber doch ziemlich, wenn auch nur in einem Teilsegment.
Ich würde die Fragestellung weg von "Warteschlange" hin zu "LAN-verträgliche Download-Gestaltung" abändern.
Mhhhhhh.......................... Gibt es vielleicht ne Config von Apache, um die maximalen Downloads zu begrenzen ........
Natürlich gibts da Möglichkeiten.
1. Wenn du in den Server nur eine 10MBit-Karte einbaust, überlastest du das Netz garantiert nicht. :)
2. Du kannst mit dem passenden Betriebssystem auch Traffic-Shaping realisieren und den Apache-Port 80 so auf akzeptable Datenraten fürs Netzwerk bringen, und trotzdem die 100Mbit-Karte drinlassen. In einer der letzten c't war darüber ein Beitrag zu lesen (der sich primär auf die Optimierung von ADSL-Verbindungen bezog). Du kannst dann z.B. das LAN in Untergruppen unterteilen und jeder Gruppe einen entsprechenden Bruchteil deiner Gesamtbandbreite zur Verfügung stellen. Diese Unterteilung läuft dann auf der Basis der vom CLient benutzten IP-Adresse.
3. Natürlich kannst du auch dem Apache verbieten, mehr als eine gewisse Anzahl von Anfragen parallel zu beantworten. Gewöhnlich sind 150 parallele Verbindungen konfiguriert (default), bis zu 256 Verbindungen kann man ohne Änderungen im Quelltext in der httpd.conf einstellen - aber eben auch 10 oder 5. :) Allerdings bedenke: Wenn 5 Downloads erlaubt sind und auch schon laufen, dann kriegt der 6., der nur mal gucken will, was die Startseite so hergibt, eine Fehlermeldung, und der Server ist nicht erreichbar. Da empfiehlt es sich irgendwie, wenn du zwei Apaches laufen läßt: Einer ist für den normalen Seitenbetrieb zuständig, und ein zweiter Apache läuft auf einem anderen Port (z.B. 81 oder 8080), ist mengenmäßig entsprechend begrenzt und liefert nur die Downloads aus.
Ich würde Traffic-Shaping oder die 10MBit-Methode vorziehen.
- Sven Rautenberg
Moin!
Natürlich gibts da Möglichkeiten.
Natürlich fällt mir die 4. Methode erst ein, wenn das Posting abgeschickt ist:
4. mod_throttle verwenden.
Mit diesem Apache-Modul kann man den Traffic Apache-seitig etwas beeinflussen, wenn auch nicht so schön, wie mit OS-seitigem Traffic-Shaping. Begrenzungen der Bandbreite, der Dateien pro Zeit und User etc. sind damit möglich - und der Vorteil ist, dass als Fehlermeldung "Server überlastet" oder so vom Apache kommt, der Benutzer aber Reloaden kann und damit ggf. irgendwann an die Datei kommt - oder du dir eine benutzerdefinierte Fehlerseite basteln kannst, die das Reloading per Javascript realisiert und bei ganz toller Programmierung vielleicht sogar noch gewisse Daten wie Warteschlange oder sowas ausgibt (was dann mit PHP geschehen könnte - mod_throttle gibt, wenn konfiguriert, eine Statistikseite per HTTP aus, die PHP auseinandernehmen könnte).
Ich würde Traffic-Shaping oder die 10MBit-Methode vorziehen.
An dieser Meinung ändere ich aber nichts. :)
- Sven Rautenberg
- mod_throttle verwenden.
Cool, das ist, wenns funzt, genial =)
Ich würde Traffic-Shaping oder die 10MBit-Methode vorziehen.
lol, ich nicht *g*
Ich pack doch keine Veraltete Hardware in nen pc, nur um ihn künstlich zu beschränken.
Ne andere idee wäre QoS, aber da müsste ich ja wieder nen neuen kernel kompilieren ...
*Gerande nen neuen apache kompiliert*
Moin!
- mod_throttle verwenden.
Cool, das ist, wenns funzt, genial =)
Es macht den Serverzugriff zumindest langsam. Ich hatte das mal bei meinem Apache zuhause eingebaut... und vergessen... und mich immer gefragt, warum denn das Intranet so lahm ist... ;)
Ne andere idee wäre QoS, aber da müsste ich ja wieder nen neuen kernel kompilieren ...
Ab Linux 2.4.20 doch kein großes Problem, oder?
PS: c't 24/2002 Seite 224.
- Sven Rautenberg
Hi Sven!
- Natürlich kannst du auch dem Apache verbieten, mehr als eine gewisse Anzahl von Anfragen parallel zu beantworten. Gewöhnlich sind 150 parallele Verbindungen konfiguriert (default), bis zu 256 Verbindungen kann man ohne Änderungen im Quelltext in der httpd.conf einstellen - aber eben auch 10 oder 5. :) Allerdings bedenke: Wenn 5 Downloads erlaubt sind und auch schon laufen, dann kriegt der 6., der nur mal gucken will, was die Startseite so hergibt, eine Fehlermeldung, und der Server ist nicht erreichbar. Da empfiehlt es sich irgendwie, wenn du zwei Apaches laufen läßt: Einer ist für den normalen Seitenbetrieb zuständig, und ein zweiter Apache läuft auf einem anderen Port (z.B. 81 oder 8080), ist mengenmäßig entsprechend begrenzt und liefert nur die Downloads aus.
Aber mal praktisch gedacht, sagen wir mal normalerweise wollen 50 Leute gleichzeitg runterladen, udn Du beschränkst das jetzt auf 5. Dann haben die 5 superdownlaod-Raten, aber was mache ich wenn ich einer von den anderen 45 bin? Muss ich dann 9 mal probieren bis ich vielleicht mal Glück habe und es geht? ich finde das nicht so sinnvoll. Am Ende gibt es eine bestimmte Menge an Daten die über das Netz wandert,
die erste Methode wäre: keine Bechränkung, jeder läd eine Datei und das dauert halt ein bisschen, 2. Methode ist, 10 % der Leute haben glück, 90% müssen andauernd probieren bis es geht, der eine mehr, der andere weniger. Am Ende haben alle im Schnitt gleich lange gebraucht, das Netz wurde mindestens(!) genauso stark belastet und mindestens 50% der Leute sind total genervt da sie mindestens 5 mal probieren mussten bis es funktioniert hat.
Grüße
Andreas
Hi!
Ja, außerdem kann es sein, das da sehr große Dateien bei sind (200 Mb) die will ich nicht alle 10 mal kopieren.
brauchst Du ja nicht. Du kannst die Datei - egal wo sie liegt, mit der von mir genannten Funktion einlesen, entsprechende HEader vorausschicken, und mit der Funktion öffnen und an den Client ausgeben, das sollte auch mit mehreren Clients gleichzeitig gehen.
Für den Download wollte ich eigentlich apache verwenden, nicht ein weiterleitendes PHP-Script
dann kannst Du es vergessen, denn HTTP ist normalerweise Zustandslos, Du kannst also nicht wirklich ermitteln wieviele Leute gleichzeitig noch dabei sind die Datei runterzuladen. Naja, theoretisch müsste es zwar gehen, ich wüßte aber nicht wie mit dem Apache, außer Du schreibst einen eigenen HTTP-Server der sowas kann.
Wieso sollte man das tun? Was für Daten würdest Du in die globalen Variablen schreiben? Würden die während der Laufzeit eines Scriptes verändert oder was? Aber was willst Du da synchronisieren?
Beispielsweise einen LOCK, der dafür sorgt, dass nur ein script gleichzeitig auf eine Datei zugreift...
dafür gibt es flock(), damit kannst Du eine Datei mi einem exklusiven Lock versehen, so kann nur ein Prozess auf diese Datei zugreifen.
Nur wenn Du volle Gewalt über die PHP-Konfiguration hast(Scriptlaufzeiten...)
hätte ich, aber das ist ja auch ne sicherheitslücke ...
Ja, wenn Du Dich nicht auskennst ;-)
Was ich meinte, damit das mit der Ausgabe über ein PGP-Script funktioniert, zumindest bei längeren Dwnloads, musst Du das Lauifzeit-Limit der PHP-Scripe deutlich hochschrauben. Wieso soll das ein Sicherheitsrisiko sein? Das machst Du einmal in der php.ini udn gut ist.
Also, bei der oben angesprochenen Lösung (fileshack) funktioniert das ganhze oberflächlich so: Ein User connected auf die Downloadseite. Da sieht er eine Ansicht, die ihm sagt er ist der x. in der Warteschlange. Diese Seite updated sich selber alle 2ß sec. Nach den 20 sec kommt entweder na andere Warteschlangennummer, oder ein Download beginnt.
So habe ich mir das auch vorgestellt, nur: Wie kann ich die user speichern, die in ner Warteschlange sind (ZB Global =) ) Und wie bekomme ich heraus, ob die leute aus meinem Tollen System ausgestiegen sind.
Das einfachste wäre wohl wirklich eine Datenbank-Tabelle, da könntest Du z.B. 2 Tabellen erstellen, 1. Tabelle que und eine Tabelle downloads.
In die Tabelle downloads schreibst Du bei einem beginnenden Downlaod über ein PHP-Script halt einen Datensatz für diesen Client rein, wenn der Downlaod. beendet ist, also direkt wenn fpassthru fertig ist, löscht Du den Datensatz wieder, bei jedem neuen Download-Request prüfst Du ob in diese Tabelle mehr als z.B. 10 Datensätze sind, wenn dem so ist komtm der User in die Tabelle que, sonst kommt er in die Tabelle downloads und Du startest den download. Wenn Du den USer in die Que geschrieben hast schickst Du ihm dann eine HTML-Seite mit einem meta-refresh oder sowas, und der ID, die damit Du ihn später wiedererkennen kannst, um ggfs. den Datensatz aus der Que zu löschen. Wenn nach x Minuten kein Refresh von einem Client gekommem ist, löscht Du den Datensatz ebenfalls und der Gute fliegt so aus der que. HIerzu musst Du also noch den letzten Refresh-Zeitpunt als timestamp in der Tabelle speichern.
Mir Viele da folgendes ein:
Ein PHP-Script, dass jedem user erstmals ne eindeutige ID zuweist. Über diese ID wird er eindeutig in die Warteschlange eingeordnet.
Wenn er nicht regelmäßig auf der Seite reloaded (was sie ja von alleine macht) dann verfällt seine ID.
genau.
Allerdings bräuchte ich ja eine art Aufräumprozess, der die IDs nach abgelaufenem Timeout entfernt...
Diese Aktion kannst Du ja bei jedem Request nebenbei durchführen. Alle Datensätze aus der DB löschen deren letzte Refresh > x Minute beträgt.
Mit MySQL würde das sicherlich gehen (zusammen mit nem Java-Daemon zB) Aber ich kenne mich da nicht sooo aus.
Ja, und mit PHP auch. Wenn Du also die Laufzeit verändern kannst ist das ganze kein Problem.
Grüße
Andreas