| Autor |
Beitrag |
jf_stgt
      
Beiträge: 88
|
Verfasst: Mi 13.08.08 17:13
Hallo!
Für ein Projekt sollen Messwerte an Clients ausgeteilt werden.
Ein Client kontaktiert dabei den Server. Dieser liest den zugehörigen Messwert (aus dem Arbeitsspeicher - keine DB) und gibt diesen wieder an den Client zurück. Danach könnte die Verbindung nach ein paar Sekunden erneut aufgebaut werden.
Ich habe mir überlegt, das Ganze mit UDP statt TCP aufzubauen. Dann könnte man doch auf Verbindungsaufbau und Co verzichten, oder? UDP ist zwar nicht so sicher - aber falls mal eine Nachricht verloren geht wäre dies kein Beinbruch.
Was denkt ihr. Wie viele solche UDP Anfragen könnte ein Serverprozess (gleichzeitig) beantworten? Ich weiß, es hängt natürlich von den Nachrichten, der Netzwerklast, usw. ab.
Aber nehmen wir mal an, wir hätten 1000 Clients. Die würden alle paar Sekunden so eine Anfrage an den Server abschicken. Problem? Das Auslesen des Messwerts würde nicht lange dauern (Arbeitsspeicher) und auch keine (kaum) Resourcen belegen.
Vielleicht könnt ihr mal ein paar Erfahrungen berichten.
Viele Grüße
jf_stgt
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mi 13.08.08 17:15
Sind das die selben werte für alle Clienes? Dann würde ich auf die Anfargen verzichen und ein Broadcast verwenden
_________________ Markus Kinzler.
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Mi 13.08.08 17:21
Hallo Markus,
mkinzler hat folgendes geschrieben: | | Sind das die selben werte für alle Clienes? Dann würde ich auf die Anfargen verzichen und ein Broadcast verwenden |
An sich eine sehr gute Idee. Zwei Probleme. Die Werte sind unterschiedlich von Client zu Client und Problem zwei: Die Clients können zum Teil vom Internet aus auf den Server zugreifen. Und für Broadcasta endet die Reise ja am Router.
Danke trotzdem!
jf_stgt
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mi 13.08.08 17:24
Man könnte aber dann aber eine Registrierung verwenden. Also Clients melden sich für den Empfang an und werden dann bei neuen Werten benachrichtigt. Die Registrierung muss regelmässig erneuert werden ( aber nicht für jeden Wert).
_________________ Markus Kinzler.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mi 13.08.08 17:31
Titel: Re: Viele kleine Abfragen auf einem Server -> Philosophiefra
jf_stgt hat folgendes geschrieben: | | Aber nehmen wir mal an, wir hätten 1000 Clients. Die würden alle paar Sekunden so eine Anfrage an den Server abschicken. Problem? |
Eigentlich nicht: Nichts anderes macht zB. ein Gameserver.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Mi 13.08.08 17:32
Hallo Markus,
mkinzler hat folgendes geschrieben: | | Man könnte aber dann aber eine Registrierung verwenden. Also Clients melden sich für den Empfang an und werden dann bei neuen Werten benachrichtigt. Die Registrierung muss regelmässig erneuert werden ( aber nicht für jeden Wert). |
Ist eine an sich sehr gute Idee. Hast Du Erfahrung damit. Im Netzwerk sehe ich ja kein Problem. Aber wie läuft das über die Routergrenzen hinweg.
Nehmen wir an, Client A fragt jede Minute den Server an (Anmeldung). Dann weiß der Server die IP und sobald sich der Messwert ändert schiebt er das (UDP?) Paket an die Client IP. Die Frage ist, wie lange puffert der Router die interne Quell-IP (NAT) und leitet das Antwort-Paket korrekt weiter? Wenn das geht, könnte man auf die sekündlichen Anfragen verzichten und nur jede Minute oder noch seltener beim Server anfragen.
Habe leider nicht so viel Erfahrung im UDP Bereich.
OT: wir beide springen ja quer durch die Topics heute
Gruß
jf_stgt
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Mi 13.08.08 17:37
Titel: Re: Viele kleine Abfragen auf einem Server -> Philosophiefra
Martok hat folgendes geschrieben: | | Eigentlich nicht: Nichts anderes macht zB. ein Gameserver. |
Hhhmm. Vielleicht hast Du recht. Hast Du Erfahrungen in dem Bereich?
Sind 100 Anfragen pro Sekunde noch ok. Oder 1000 Anfragen?
Oder 10000 Anfragen pro Sekunde?
Die Schwierigkeit ist, dass ich es nicht ausprobieren kann. Ich kann ja nicht meine Applikation (oder den Thread) 1000 x starten.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 13.08.08 17:59
Je nach dem, wie aktuell die Daten vom Server kommen müssen, wäre es u.U. überlegenswert, die Anfragehäufigkeit zu reduzieren, dafür aber mehr Daten pro Request zurückzuliefern.
Eine Art Notify wäre auch denkbar, dass der Server jedem registrierten Client bescheid gibt, wenn sein Datenpuffer einen gewissen Füllstand erreicht hat.
Allein die Anzahl der UDP-Pakete ist erstmal weniger interessant, da das relativ unwichtig ist für die Anzahl der Clients. Entscheident ist hierbei eher, wieviel Empfangspuffer du deinem UDP-Socket zuteilst, da in diesem die noch anstehenden Nachrichten gesammelt werden. Bei 1000 Clients, die jede Sekunde ein Paket von ~128 Bytes schicken, Sollten also durchaus 64 bis 128 KB eingeplant werden. (Wobei hier ggf. eine Überlegung in Richtung Double Buffering und Lasterteilung angestellt werden sollte).
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Mi 13.08.08 18:27
BenBE hat folgendes geschrieben: | Je nach dem, wie aktuell die Daten vom Server kommen müssen, wäre es u.U. überlegenswert, die Anfragehäufigkeit zu reduzieren, dafür aber mehr Daten pro Request zurückzuliefern.
|
Klar! Werde sehen was ich dazu machen kann.
BenBE hat folgendes geschrieben: | Eine Art Notify wäre auch denkbar, dass der Server jedem registrierten Client Bescheid gibt, wenn sein Datenpuffer einen gewissen Füllstand erreicht hat.
|
Ist durch einen Router ja etwas schwiwerig. Die Frage ist wie gesagt wie da der Timeout zu sehen ist. Nehmen wir an, der Client hinter dem privaten Router sendet eine Anfrage an den Server und 1 Minute später kommt die UDP-Antwort. Kann dies der Router noch durch das NAT an den Client zustellen?
BenBE hat folgendes geschrieben: | | ... wieviel Empfangspuffer du deinem UDP-Socket zuteilst, da in diesem die noch anstehenden Nachrichten gesammelt werden. Bei 1000 Clients, die jede Sekunde ein Paket von ~128 Bytes schicken, Sollten also durchaus 64 bis 128 KB eingeplant werden. |
Die Mathematik verstehe ich. Aber ich teile doch gar kein Empfangspuffer zu, oder? Also ich verwende die Delphi Komponenten und da macht er das irgendwie automatisch oder habe ich beim UDP-Server was übersehen?
Wenn Du 128 kB schreibst heißt das dann, dass bei 128 Byte und 1000 Clients der Arbeitsspeicher mti 128 kB belegt wäre, oder? Geht ja noch, oder? Oder ist die Prozessorleistung das Nadelöhr?
BenBE hat folgendes geschrieben: | | Wobei hier ggf. eine Überlegung in Richtung Double Buffering und Lasterteilung angestellt werden sollte. |
Du meintest Lastverteilung, oder? Das habe ich auch schon überlegt. Aber die Frage ist ja, ab welcher Client-Zahl ein zweiter Server sinnvoll ist.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 13.08.08 18:45
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | Je nach dem, wie aktuell die Daten vom Server kommen müssen, wäre es u.U. überlegenswert, die Anfragehäufigkeit zu reduzieren, dafür aber mehr Daten pro Request zurückzuliefern.
|
Klar! Werde sehen was ich dazu machen kann. |
Hier ist IMHO das größte Einspar-Potential in Bezug auf die nötige Rechenleistung und Bandbreite..
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | Eine Art Notify wäre auch denkbar, dass der Server jedem registrierten Client Bescheid gibt, wenn sein Datenpuffer einen gewissen Füllstand erreicht hat.
|
Ist durch einen Router ja etwas schwiwerig. Die Frage ist wie gesagt wie da der Timeout zu sehen ist. Nehmen wir an, der Client hinter dem privaten Router sendet eine Anfrage an den Server und 1 Minute später kommt die UDP-Antwort. Kann dies der Router noch durch das NAT an den Client zustellen? |
Ich denke UDP Hole Punching könnte Dir hier u.U. helfen. Bei NAT waren die Timeouts aber i.d.R. 2-5 Minuten.
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | | ... wieviel Empfangspuffer du deinem UDP-Socket zuteilst, da in diesem die noch anstehenden Nachrichten gesammelt werden. Bei 1000 Clients, die jede Sekunde ein Paket von ~128 Bytes schicken, Sollten also durchaus 64 bis 128 KB eingeplant werden. |
Die Mathematik verstehe ich. Aber ich teile doch gar kein Empfangspuffer zu, oder? Also ich verwende die Delphi Komponenten und da macht er das irgendwie automatisch oder habe ich beim UDP-Server was übersehen?
Wenn Du 128 kB schreibst heißt das dann, dass bei 128 Byte und 1000 Clients der Arbeitsspeicher mti 128 kB belegt wäre, oder? Geht ja noch, oder? Oder ist die Prozessorleistung das Nadelöhr? |
Bei diesen 128 kB geht es um System-Speicher, der für dieses Socket reserviert sein muss. Das ist nämlich im Normalfall nur etwa 8KB. Man kann es wie gesagt durch verschiedene Tricks auch mit weniger Speicher hinbekommen, läuft dann aber Gefahr, dass der Puffer vollläuft (Lastspitzen, ...)
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | | Wobei hier ggf. eine Überlegung in Richtung Double Buffering und Lasterteilung angestellt werden sollte. |
Du meintest Lastverteilung, oder? Das habe ich auch schon überlegt. Aber die Frage ist ja, ab welcher Client-Zahl ein zweiter Server sinnvoll ist. |
Ein zweiter Server ist dann sinnvoll, wenn die Ressourcen des ersten Systems im Normalbetrieb zu 75% und bei Spitzen zu über 90% ausgelastet werden. Eine Lastverteilung kann u.a. durch ein einfaches DNS-Round-Robin oder einen Anycast realisiert werden.
Zu dem Double-Buffering: Es gibt einen Thread, der allein die Requests aus dem Socket liest und in einer Queue aufschreibt. Diese Queue wird dann von N Arbeitsthreads in regelmäßigen Abständen abgearbeitet. Der Socket-Thread muss dabei hohe Priorität haben, um die Daten aus dem System-Puffer (beschränkt) in den Programm-Puffer (unbeschränkt möglich) übertragen zu werden. Damit bekommt man den Vorteil, dass bei Lastspitzen ein Überlaufen (und damit das Ablehnen eines Paketes) mit hoher Wahrscheinlichkeit verhindert wird. Nachteil ist allerdings, dass die Anwendung längere "Nachlaufzeiten" hat, eine Antwort auf eine Anfrage auch erst durchaus zeitlich verzöger beantwortet werden kann (Wenn hohe Last auf dem System herrscht).
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Mi 13.08.08 19:17
Jetzt bin ich schon echt weiter. Das Forum hat mir wieder gut geholfen! Danke schonmal!
BenBE hat folgendes geschrieben: | | Ich denke UDP Hole Punching könnte Dir hier u.U. helfen. Bei NAT waren die Timeouts aber i.d.R. 2-5 Minuten. |
2-5 Minuten sind ja schon super. Er fragt einmal in der Minute an. Der Server "merkt" sich damit den User (ID mitübermittelt) und die IP. Bei Änderung der Messdaten (für diesen Client) sendet er diese an den Client.
Es kann auch sein, dass nur wenige Antworten pro Tag kommen aber das ist ja auch egal. Er muss ja nicht immer eine Antwort zurücksenden sondern nur wenn wirklich ein neues Datenpaket für den Client vorliegt.
Was hältst Du davon?
BenBE hat folgendes geschrieben: | | Bei diesen 128 kB geht es um System-Speicher, der für dieses Socket reserviert sein muss. Das ist nämlich im Normalfall nur etwa 8KB. |
Du scheints Dich ja echt auszukennen. Ist das der Wert "BufferSize" bei den Indy Komponenten? Die stehen nämlich auf 8192 Byte (8k).
BenBE hat folgendes geschrieben: | | Ein zweiter Server ist dann sinnvoll, wenn die Ressourcen des ersten Systems im Normalbetrieb zu 75% und bei Spitzen zu über 90% ausgelastet werden. Eine Lastverteilung kann u.a. durch ein einfaches DNS-Round-Robin oder einen Anycast realisiert werden. |
Werde erstmal versuchen das Ganze mit einem Server hinzubekommen. Zum Glück wächst das ganze dynamisch. Es sollte halt von Anfang an skalierbar sein (wie immer  ).
BenBE hat folgendes geschrieben: | | Zu dem Double-Buffering: Es gibt einen Thread, der allein die Requests aus dem Socket liest und in einer Queue aufschreibt. Diese Queue wird dann von N Arbeitsthreads in regelmäßigen Abständen abgearbeitet. Der Socket-Thread muss dabei hohe Priorität haben, um die Daten aus dem System-Puffer (beschränkt) in den Programm-Puffer (unbeschränkt möglich) übertragen zu werden. Damit bekommt man den Vorteil, dass bei Lastspitzen ein Überlaufen (und damit das Ablehnen eines Paketes) mit hoher Wahrscheinlichkeit verhindert wird. Nachteil ist allerdings, dass die Anwendung längere "Nachlaufzeiten" hat, eine Antwort auf eine Anfrage auch erst durchaus zeitlich verzöger beantwortet werden kann (Wenn hohe Last auf dem System herrscht). |
Eigentlich genial.
Den Nachteil mit der längeren Wartezeit könnte man in Kauf nehmen. Wenn der Messwert erst ein paar Sekunden später eintrifft spielt das (fast) keine Rolle.
Die Queue sollte allerdings gut konzipiert sein. Ich denke da an eine Art Datenbank oder was schlägst Du vor? Ein (dyn.) Array oder sonst ein Variablenzugriff ist ja wegen dem gleichzeitigem Zugriff aus mehreren Threads problematisch.
Der Thread der auf die Connection zugreift müsste ja nicht für jede Connection ein Unterthread bilden, oder? So mache ich das manchmal bei TCP Connections. Sonst hat man ja nachher 1000 Threads offen. Der Thread würde nur dann einen zuusätzlichen (weiteren) Thread zu Abarbeitung öffnen, falls die Queue zu viele Werte die der vorhandene "Rechenthread" nicht mehr abarbeiten kann.
Oder?
|
|
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Mi 13.08.08 19:23
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | | Bei diesen 128 kB geht es um System-Speicher, der für dieses Socket reserviert sein muss. Das ist nämlich im Normalfall nur etwa 8KB. |
Du scheints Dich ja echt auszukennen. Ist das der Wert "BufferSize" bei den Indy Komponenten? Die stehen nämlich auf 8192 Byte (8k).
|
Jap
_________________ Programmers never die, they just GOSUB without RETURN
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 14.08.08 00:16
jf_stgt hat folgendes geschrieben: | Jetzt bin ich schon echt weiter. Das Forum hat mir wieder gut geholfen! Danke schonmal!
BenBE hat folgendes geschrieben: | | Ich denke UDP Hole Punching könnte Dir hier u.U. helfen. Bei NAT waren die Timeouts aber i.d.R. 2-5 Minuten. |
2-5 Minuten sind ja schon super. Er fragt einmal in der Minute an. Der Server "merkt" sich damit den User (ID mitübermittelt) und die IP. Bei Änderung der Messdaten (für diesen Client) sendet er diese an den Client.
Es kann auch sein, dass nur wenige Antworten pro Tag kommen aber das ist ja auch egal. Er muss ja nicht immer eine Antwort zurücksenden sondern nur wenn wirklich ein neues Datenpaket für den Client vorliegt.
Was hältst Du davon? |
Damit der Router sich den Port als Offen merkt, muss regelmäß0ig ein "Keep Alive" empfangen werden.
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | | Bei diesen 128 kB geht es um System-Speicher, der für dieses Socket reserviert sein muss. Das ist nämlich im Normalfall nur etwa 8KB. |
Du scheints Dich ja echt auszukennen. Ist das der Wert "BufferSize" bei den Indy Komponenten? Die stehen nämlich auf 8192 Byte (8k). |
Jap ...
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | | Ein zweiter Server ist dann sinnvoll, wenn die Ressourcen des ersten Systems im Normalbetrieb zu 75% und bei Spitzen zu über 90% ausgelastet werden. Eine Lastverteilung kann u.a. durch ein einfaches DNS-Round-Robin oder einen Anycast realisiert werden. |
Werde erstmal versuchen das Ganze mit einem Server hinzubekommen. Zum Glück wächst das ganze dynamisch. Es sollte halt von Anfang an skalierbar sein (wie immer ). |
Einfach da das Protokoll so dynamisch halten, dass Du Befehle zur Server-Verwaltung (Client an anderen Server verweisen, ...) nachträglich ergänzen kannst.
jf_stgt hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | | Zu dem Double-Buffering: Es gibt einen Thread, der allein die Requests aus dem Socket liest und in einer Queue aufschreibt. Diese Queue wird dann von N Arbeitsthreads in regelmäßigen Abständen abgearbeitet. Der Socket-Thread muss dabei hohe Priorität haben, um die Daten aus dem System-Puffer (beschränkt) in den Programm-Puffer (unbeschränkt möglich) übertragen zu werden. Damit bekommt man den Vorteil, dass bei Lastspitzen ein Überlaufen (und damit das Ablehnen eines Paketes) mit hoher Wahrscheinlichkeit verhindert wird. Nachteil ist allerdings, dass die Anwendung längere "Nachlaufzeiten" hat, eine Antwort auf eine Anfrage auch erst durchaus zeitlich verzöger beantwortet werden kann (Wenn hohe Last auf dem System herrscht). |
Eigentlich genial.
Den Nachteil mit der längeren Wartezeit könnte man in Kauf nehmen. Wenn der Messwert erst ein paar Sekunden später eintrifft spielt das (fast) keine Rolle.
Die Queue sollte allerdings gut konzipiert sein. Ich denke da an eine Art Datenbank oder was schlägst Du vor? Ein (dyn.) Array oder sonst ein Variablenzugriff ist ja wegen dem gleichzeitigem Zugriff aus mehreren Threads problematisch.
Der Thread der auf die Connection zugreift müsste ja nicht für jede Connection ein Unterthread bilden, oder? So mache ich das manchmal bei TCP Connections. Sonst hat man ja nachher 1000 Threads offen. Der Thread würde nur dann einen zuusätzlichen (weiteren) Thread zu Abarbeitung öffnen, falls die Queue zu viele Werte die der vorhandene "Rechenthread" nicht mehr abarbeiten kann.
Oder? |
Kann man mit einer Queue, die als dynamisch realloziierbaren Ringpuffer realisiert ist, ganz einfach bauen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Do 14.08.08 10:14
BenBE hat folgendes geschrieben: | | Damit der Router sich den Port als Offen merkt, muss regelmäß0ig ein "Keep Alive" empfangen werden. |
Weißt Du wie oft so ein Keep Alive gesendet werden muss?
BenBE hat folgendes geschrieben: | | Kann man mit einer Queue, die als dynamisch realloziierbaren Ringpuffer realisiert ist, ganz einfach bauen. |
Ganz so einfach ist es doch nicht wegen den Zugriffen aus den Threads, oder?
Wie gewährleistest Du, dass nicht gerade der Socket-Lese-Thread neue Daten in den Ringpuffer schreibt und gleichzeitig Daten gelesen werdwen. Über die Methoden die dafür notwendig sind, bin ich mir im klaren (Critical Sections z.B.) aber wenn ich mit CS den anderen Thread warten lasse ist das nicht gerade perfomant oder ist dieser Schreibzugriff so kurz, dass dies keine Perfomanzeinbußen hat?
Als Ringpuffer könnte man doch wenn es mit CS geht einfach eine verkette Liste machen, oder?
Oder ein einfaches Array?!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 14.08.08 11:44
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Do 14.08.08 18:15
BenBE hat folgendes geschrieben: | Jedes Paket erneuert das Timeout. Zur Not einfach usprobieren  |
Habe ihm Internet mal nachgelesen. Der Timeout liegt wohl so bei 20-30 Sekunden. Ob das wahr ist, kann ich nicht genau sagen. Stand nur so auf der Homepage (keine Spezifikation).
Also doch selbst ausprobieren.
Viele Grüße und nochmals Danke
jf_stgt
Moderiert von Narses: 2. Frage entfernt
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Fr 15.08.08 14:07
Hallo!
Also ich habe es mal ausprobiert. Bei meinem Router dauert es 180 Sekunden (also 3 Minuten) bis er das Antwort-Paket des Servers nicht mehr als Antwort auf das Sendepaket anerkennt und verwirft. Wie das bei anderen Routern ist, kann ich natürlich nicht sagen.
Viele Grüße
jf_stgt
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Fr 22.08.08 09:56
Hallo BenBE,
möchte gerne Deine Idee mit der Queue noch etwas verfeinern.
BenBE hat folgendes geschrieben: | | Zu dem Double-Buffering: Es gibt einen Thread, der allein die Requests aus dem Socket liest und in einer Queue aufschreibt. Diese Queue wird dann von N Arbeitsthreads in regelmäßigen Abständen abgearbeitet. Der Socket-Thread muss dabei hohe Priorität haben, um die Daten aus dem System-Puffer (beschränkt) in den Programm-Puffer (unbeschränkt möglich) übertragen zu werden. Damit bekommt man den Vorteil, dass bei Lastspitzen ein Überlaufen (und damit das Ablehnen eines Paketes) mit hoher Wahrscheinlichkeit verhindert wird. ... |
Habe nun eine Queue (als doppelt verkettete Liste) gebaut und diese wird vom Socket-Thread eingelesen (hochprior) und vom Arbeitsthread (niederprior) auch abgerabeitet. Funktioniert!
Die Frage ist nun, was passiert wenn viele Kunden gleichzeitig darauf zugreifen. Du schreibst ja schon, dass N Arbeits-Threads gebildet werden könnten. Aber wie gross ist N? Sollte man dies dynamisch machen. Also beispielsweise es sind x Einträge in der Queue dann mache noch ein Thread auf oder man definiert ständig N Arbeitsthreads und wenn nichts zu tun ist legen sich diese schlafen, ...
Was meinst Du?
Gruß
jf_stgt
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 22.08.08 14:58
Das ist die Frage, welches Threading-Modell man nutzen will ...
Der Apache unter Linux bietet dafür z.B. mehrere Möglichkeiten:
Möglichkeit 1 (Prefork):
- Man hat statisch N alloziiert eine gewisse Anzahl, die einen Großteil ihrer Zeit schlafen ...
- Laufen mehr Anfragen (von mehr Clients) auf, als Threads verfügbar sind, werden dynamisch neue Threads (in gewissen Grenzen) erzeugt
Dieses Verhalten ist grad bei Webanfragen, wo man immer mal Lastspitzen abfangen muss vorteilhaft, führt aber zu einer Ressourcen-Verschwendung, wenn sehr häufig Lastspitzen abfangen muss.
Möglichkeit 2 (Worker):
Eine weitere Möglichkeit besteht darin, jeden Thread für eine gewisse Anzahl von Anfragen (clientunabhängig) wiederzuverwenden und dann nach dieser Anzahl Anfragen zu beenden. Nach dem sich ein Thread beendet hat, wird dieser neugestartet. Das hat unter Linux die Bewandnis, dass Speicherlöcher somit reduziert werden können in ihrer Auswirkung, ohne für jede Anfrage den Aufwand des Thread-Erstellens zu haben.
Für deinen Zweck würd ich den Worker-Ansatz favorisieren, da du selten wiederholte Anfragen vom gleichen Client hast.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
jf_stgt 
      
Beiträge: 88
|
Verfasst: Fr 22.08.08 15:05
Danke für die auzsführliche Info. Werde mich mal genauer (v.a. mit "Worker") beschäftigen.
|
|
|