Apache in einen TCP Server umwandeln

Apache, Lighttpd, nginx, Cherokee
stickybit
Posts: 59
Joined: 2007-08-16 09:39

Apache in einen TCP Server umwandeln

Post by stickybit » 2010-08-29 13:50

Servus,

ich benötige einen TCP Server, der viele parallele Abfragen möglichst ohne Verzögerung abarbeiten kann.
Ich habe mit dem Apache Server bis jetzt gute Erfahrungen gemacht.

Da ich jetzt einen reinen TCP Server benötige, überlege ich mir, ob es geht, ohne den Source Code von Apache zu ändern, das Header-Handling von Apache abzuschalten.

Für Ideen und Vorschläge wäre sehr dankbar.

André

Roger Wilco
Administrator
Administrator
Posts: 5924
Joined: 2004-05-23 12:53

Re: Apache in einen TCP Server umwandeln

Post by Roger Wilco » 2010-08-29 17:12

Der Apache httpd kann auch mit anderen Protokollen umgehen, so gibt es z. B. mod_ftp. Du müsstest nur ein entsprechendes Modul für dein Protokol erstellen.

stickybit
Posts: 59
Joined: 2007-08-16 09:39

Re: Apache in einen TCP Server umwandeln

Post by stickybit » 2010-08-29 17:34

matzewe01 wrote:Erklär mal genauer, was Du vor hast.


Hallo,

und danke an matzewe01 und Roger Wilco für die Antworten.

Ich benötige einen TCP-Server. Zunächst kam die Idee diesen selbst zu programmieren. Ich habe mir eine Testumgebung aufgebaut und ein Paar Tests duchgeführt. Ich musste bsw. feststellen, dass während eine Aufgabe vom Server erledigt wird, werden die Andreren Clients blockiert. Ich benötige aber wie gesagt, dass Aufgaben parallel ausgeführt werden. Ich kann jetzt natürlich beginnen, Lösungen für das Problem zu suchen. Ich denke, ich wäre schneller am Ziel, wenn Apache für meinen Zweck einsetze.

Der Apache soll mir bei einer eingehender Verbindung einach eine bestimmte PHP-Datei öffnen und mit dem Client ohne Header kommunizieren.

Das Problem ist, wenn sich der Client nur verbindet, passiert nichts. Denn der muss ja noch mind. zwei Zeilen senden, damit der Server weiß, was er zu tun hat, bsw.

Code: Select all

POST / HTTP/1.1\nHOST: hostname
Content-Length: 25


Wenn ich das irgenwie umgehen könnte...

dotme
Posts: 150
Joined: 2004-12-15 16:48

Re: Apache in einen TCP Server umwandeln

Post by dotme » 2010-08-29 17:51

Um schnell Ergebnisse zu erzielen würde ich mir mal tcpserver und Twisted ansehen.

stickybit
Posts: 59
Joined: 2007-08-16 09:39

Re: Apache in einen TCP Server umwandeln

Post by stickybit » 2010-08-29 18:23

matzewe01 wrote:Also wirklich ganz kann Ich dir nocht nicht folgenden.
Ob und wie, hängt nun von Deiner eingesetzten Client "Sprache" ab.

1. der Client verbindet sich mit meinem Server (TCP).
2. über diese Verbindung wird ein Auftrag versendet (eigenes Protokoll).
3. der Server führt den Autfrag aus.
4. der Server antwortet dem Client mit ok/nok.

Ich habe bereits eine Serverumgebung aufgebaut. Es können sich mehrere Clients mit meinem Test-Server verbinden. Das "Problem" macht leider der 3. Schritt. Hintergrund und Forken sind schon die richtigen Stichworte. Wenn ein Auftrag ein zeitintensiver Auftrag eingeliefert hat, dann müssen alle anderen warten.

Roger Wilco
Administrator
Administrator
Posts: 5924
Joined: 2004-05-23 12:53

Re: Apache in einen TCP Server umwandeln

Post by Roger Wilco » 2010-08-29 18:30

Das, was du beschreibst, ist problemlos mit inetd oder xinetd (oder eben dem schon genannten tcpserver) umzusetzen. Dein Programm müsste dann lediglich die Eingaben des Clients auf stdin annehmen und die Antwort auf stdout ausgeben.

Das Forken bzw. den Aufruf eines neuen Serverprozesses für den nächsten Client übernimmt dann (x)inetd.

Roger Wilco
Administrator
Administrator
Posts: 5924
Joined: 2004-05-23 12:53

Re: Apache in einen TCP Server umwandeln

Post by Roger Wilco » 2010-08-29 18:40

Es hat sich für mich so gelesen, als hätte er zuvor einen Single-Process-Server gehabt, bei dem jeweils nur 1 Client bedient werden kann und der Rest warten muss.

User avatar
daemotron
Administrator
Administrator
Posts: 2635
Joined: 2004-01-21 17:44

Re: Apache in einen TCP Server umwandeln

Post by daemotron » 2010-08-29 20:28

stickybit wrote:Ich habe bereits eine Serverumgebung aufgebaut. Es können sich mehrere Clients mit meinem Test-Server verbinden. Das "Problem" macht leider der 3. Schritt. Hintergrund und Forken sind schon die richtigen Stichworte. Wenn ein Auftrag ein zeitintensiver Auftrag eingeliefert hat, dann müssen alle anderen warten.


Du hast grundsätzlich drei Möglichkeiten, um (pseudo-)paralleles Handling von Client-Verbindungen zu realisieren:

  1. Nebenläufigkeit durch mehrere Prozesse: Das ist das, was Du oben mit "fork" schon angesprochen hast. Dabei kannst Du entscheiden, ob für jeden Client einen eigenen Prozess forkst und diesen nach Sitzungsende sterben lässt, oder ob Du einen Pool von Worker-Prozessen auf Vorrat anlegst (preforked) und eingehende Verbindungen an diese verteilst. Ein Beispiel für einen rein auf Prozessen basierenden Server ist Apache mit dem Prefork-MPM Modul.
  2. Nebenläufigkeit durch mehrere Threads: Ist vom Prinzip her ähnlich wie die oben beschriebene Variante mit den Prozessen, nur dass statt Prozessen (fork) Threads erzeugt werden müssen (pthread_create). Auch hier gilt es wieder, zwischen den beiden möglichen Lebenszyklusmodellen zu wählen. Allerdings muss man bei Threads höllisch aufpassen, dass man nur mit eintrittsinvarianten Funktionen arbeitet, da sich alle Threads den Prozessraum (incl. Speichersegmente!) gemeinsam teilen und es OS-seitig keine Mechanismen gibt, die vor ungewollten Wechselwirkungen schützen. Beispiel für einen rein mit Threads arbeitenden TCP-Server ist der MySQL-Datenbankserver.
  3. Multiplexing mit select, epoll oder kqueue; Dieses Verfahren kommt ohne den Einsatz mehrere Prozesse oder Threads aus. Per select()* wird geprüft, an welchem der Client-Sockets gerade Daten vorliegen. Diese werden eingelesen und an den Buffer des Clients angehängt. Das Spielchen spielt man so lange, bis für einen Client ein Buffer-Zustand erreicht ist, auf den der Server mit einer Aktion reagieren kann. Ein erfolgreicher Vertreter dieser Strategie ist z. B. Lighttpd
Natürlich lassen sich die verschiedenen Techniken untereinander kombinieren, und in der Praxis findet man nur wenige Server, die davon keinen Gebrauch machen. Apache's Worker-MPM beispielsweise erzeugt preforked Worker-Prozesse, die dann jeweils einen Thread-Pool pro Prozess erzeugen. Nginx kombiniert hingegen mehrere Prozesse mit non-blocking Sockets, arbeitet also mit mehreren multiplexenden Prozessen.

* select() ist eine generische Implementierung, die nicht unbedingt besonders performant ist. Unter Linux würde man stattdessen epoll verwenden, unter FreeBSD kqueue.

P. S. wenn Du Dich mit Python mal versuchen möchtest, dann schau Dir mal das SocketServer Modul an - das gehört zur Standard-Bibliothek. Ich würde bei Python allerdings den ForkingMixIn empfehlen, da Threads aufgrund eines Locks im Interpreter selbst nicht wirklich parallel ausgeführt werden. Als (deutschsprachige) Literatur sei auf Kapitel 20 des Python-Openbook von Galileo verwiesen.
Last edited by daemotron on 2010-08-29 20:35, edited 1 time in total.
“Some humans would do anything to see if it was possible to do it. If you put a large switch in some cave somewhere, with a sign on it saying 'End-of-the-World Switch. PLEASE DO NOT TOUCH', the paint wouldn't even have time to dry.” — Terry Pratchett, Thief of Time

User avatar
daemotron
Administrator
Administrator
Posts: 2635
Joined: 2004-01-21 17:44

Re: Apache in einen TCP Server umwandeln

Post by daemotron » 2010-09-06 18:57

Noch ein kleiner Nachtrag: Im Rahmen eines (anderen) Projekts habe ich das Grundrezept eines nebenläufigen TCP-Daemons auf Pthread-Basis zusammengebastelt (in C). SSL-Support ist noch nicht ganz fertig, kommt aber auch noch. Das Ding arbeitet pre-threaded mit einer einstellbaren Anzahl an Worker Threads.

Derzeitiger Stand: Es funktioniert, es nimmt TCP-Verbindungen an. Eine (protokollspezifische) Funktion zur Verarbeitung einer Verbindung fehlt allerdings noch (die wolltest Du ja eh selbst beisteuern). Umgesetzt sind bis jetzt:

  • Multithreading
  • Logging (syslog)
  • rennt als Daemon (und schreibt eine PID-File)
  • Kann User- und Gruppenkontext wechseln
  • Erzeugt Worker-Threads
  • Akzeptiert eingehende Verbindungen
Soweit ich das überschauen kann, habe ich (hoffentlich) keine ungeprüften Pufferzugriffe drin, und (hoffentlich) auch keine Formatstring-Schwächen. Eine Garantie dafür gibt's aber natürlich nicht...

Code hier (bezieht sich auf r5) : https://svn.my-universe.com/stormrose/trunk
“Some humans would do anything to see if it was possible to do it. If you put a large switch in some cave somewhere, with a sign on it saying 'End-of-the-World Switch. PLEASE DO NOT TOUCH', the paint wouldn't even have time to dry.” — Terry Pratchett, Thief of Time