Philipp Hasenfratz: OT: performanter Server für HTTP-Logging

Beitrag lesen

Halihallo Andreas

Da hätt ich noch ein zwei Tipps für dich:
Du schreibst ein C++ Programm, welches sich an Port 80 "anheftet" (es sei denn, du
möchtest parallel noch ein Webserver betreiben).
was meinst Du damit? Meine Idee war ja gerade die einen eigenen Mini-"Webserver" zu schreiben(bin durch Kay auf die Idee gekommen), also einen C++ Dämon der wie beschreiben auf Port 81 lauscht, HTTP Request direkt in eine File schriebt, nicht analysiert, und dem Client einen 200 Status-Code und ein gif zurücksendet.

Yo, das meinte ich. Ein Super-Schlanker-Mini-Webserver ;)
Ich glaube, wir meinen das selbe.

Dieser Dämon würde ja _superschlank_  und schnell sein, theoretisch.

Yo, das einzige, was er zu tun braucht, ist: Socket auslesen (Request-Header/Content)
und gleich ins Nirvana senden (die Daten werden ja u. U. gar nicht gebraucht), dann
Datei öffnen, Pageview (oder was anderes halt) registrieren und zwei drei printf-
Anweisungen, fertig... Damit kommst du wohl sogar auf ca. 2000 Requests/s :-)

Ich habe keien AHnung wie man das macht da sman so einen Dämon-Prozess forkt(das ist sicher nicht schwer),

Mit der gleichnamigen Funktion ;)

aber das problem was ich erstmal sehen würde - wie verteile ich die Requests aif die verschiedenen Prozesse? Also es läuft meiN Dämon udn 50 Kopien dieses Prozesses. Lauschen jetzt alle an Port 81, wer entscheidet werd jetzt den Request entgegennimmt und bearbeitet? Oder muß da noch was "vor"?

Ich weiss leider nicht, wie die "Inter-Programm-Kommunikation" beim Apachen aussieht.
Aber, das schliesse ich mal aus, lauschen bestimmt nicht alle an Port 81.
Ich könnte mir vorstellen, dass es einen Request-Empfänger gibt (das Queueing-System)
und dieser dann über ein zweites Socket die Daten an die Clients (preforked processes)
verteilt; diese lauschen z. B. an Ports aufsteigend ab 19498 oder so...
Oder man verwendet UNIX-Domain-Sockets (FIFO-Queue, die die Clients auslesen können).
Oder http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_11.html#SEC225
von http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_toc.html

Aber: Was, wenn 200 Requests/s eintreffen? - Lineares abarbeiten der Request Queue ist
hier einfach verdammt langsam. Besser geht's mit dem vorgeschlagenen preforking, optinal,
um's etwas einfacher zu machen, für jeden Request ein neuer Prozess (fork).
Ist preforking Unix-spezifisch oder Apache-spezifisch? Ich kenen das nur vom Apachen, und da läuft das halt von alleine. Wenn ich das selbst implementieren wollte, ginge das auch in PERL?

Ich glaube POSIX-spezifisch. POSIX definiert ein OS-Standard, der von Unix vollständig
erfüllt ist, u. a. ist eben auch fork() verfügbar. Das preforking als "Technologie"
gibt es jedoch auch auf anderen Betriebssystemen. Und ja, preforking ist auch über
Perl möglich. Alles was du brauchst, ist die Funktion fork() und die Möglichkeit
mit den anderen Prozessen zu kommunizieren (hier seien auch Semaphoren genannt, eine
weitere Möglichkeit, nur kenne ich mich damit nicht aus).

Naja, mit Prozess-Lomunikation... muss ich mich wohl erstmal auseinandersetzen, das gibt es in PHP nicht wirklich, daher kenne ich es nicht wirklich ;-)

Ich glaube ich bin jetzt lieber still und verkneif mir Kommentare
(zu PHP) :-)))
   [in letzter Zeit sind davon ja genug von meiner Seite gekommen, aber: sie sind
    ja nicht wirklich ernst gemeint ;)]

Aber dann habe ich ne ganze Menge Overhead für diese einfache Anwendung.

Findest du? - mod_perl lässt sich IMHO konfigurieren, wieviele parallele Instanzen
verwaltet werden sollen. Woraus hier ein grosser Overhead entsteht ist mir nicht klar.
Hm, vielleicht irre ich mich auch. 99,99% der einkompilierten und geladenen Apache und mod_perl Funktionalitäten brauche ich nicht. Wäre es nicht günstiger einen Dämon zu schreiben der nur genau das kann  und läd was ich brauche?

Ja, doch. Ich meinte nur, dass du mit mod_perl und Apache vergl. m. IIS-Benutzern schon
sehr viel besser bedient ist :-)
Und wenn etwas im Speicher ist, muss es ja noch nicht Performance verbrauchen und
letzteres ist ja jetzt wichtig, oder? - Aber, du hast schon recht. Natürlich hast du
bei einer eigenen Lösung weniger Speicheroverhead.

Aber ich weiß auch das ich nicht so effizient programmieren kann wie die Apache oder mod_perl Leute, daher ist es fraglich ob die Apache + mod_perl Variante nicht vielleicht doch die bessere Variante ist. ODer vielleicht sollt man einen anderen Server einsetzen: Zeus, thttpd, tux, khttpd sollen für statisches HTML schneler sin, nur vermutlich gibt es dafpr nict sowas effizientes wie mod_perl. Außerdem passt sich das Betriebssystem der Anforderung an, und hält genau die richtigen Dinge im Speicher. Schwirige Frage. Ich kenne mich da leider noch nicht genug aus.

Ich leider auch nicht, sorry :-(

Oder kann man auch einen PERL Prozess(bzw. mehrere) im Speicher halten, also das 1. nicht immer der Interpreter angeworfen werden muss(das ware das schlimmste)

Aber natürlich ;)
Mit Perl lassen sich ganz einfach und sehr schöne Daemonen programmieren und darum geht
es hier.
Hm? Sind mod_perl und perl-dämonen nicht 2 verschiedene paar Schuhe? Mod-Perl ist doch "nur" eine Webgserver - Schnittstelle, so ähnlich wie CGI, nur das es ebe nicht über CGI geht sondern über die Apache SAPI, und das ist eben erheblich effizienter. Hierüber können über das Internet PERL-Script aufgerufen werden, die aber immer interpretiert werden müssen, wobei der Interpreter nicht jedesmal geladen werden muss.

Ja, der Vergleich ist etwa richtig. Zudem werden die kompilierten Code-Bäume (bereits
geparste Scripts) im Speicher behalten, was die "Kompilierung" der Scripte beschleunigt.
Und ja, es sind zwei paar Schuhe. Ich sprach davon, wie du dies mit Perl selber
"nachmachen" könntest, in Falle Apache-mod_perl hast du das ja schon gegeben.

Das ist aber doch was anderes als ein Dämon, der feritg im Maschinencode läuft und auf Anfragen wartet, der muss doch nur einmal interpretiert werden und wenn der dann läuft bekommt er Daten an STDIN oder liest Daten von einem Socket (aber da kenne ich mich leider noch nicht aus).

Jein. Ein Perl-Daemon ist eine "Perl-Interpreter-Instanz" + "Optimierter-Code-Baum". Aber
interpretieren muss der Perlinterpreter das Script dennoch, nur nicht mehr parsen und
optimieren. Nur bei C oder einer anderen kompilierten Sprache hast du Maschinencode
vorliegen. Java ist hier so ne Mischform (Pseudomaschinen-Code).

Wenn das Script also läuft dürfte es doch eigentlich nicht mehr viel langsamer sein als C, oder? Der größte GEschwindigkeitsvorteil von C besteht ja darin das es nicht mehr interpretiert weden muss.

Das ist leider falsch. Genau _wegen_ dem letzteren. Das Parsen braucht natürlich schon
auch viel Zeit, aber das Interpretieren mindestens genauso viel (kommt natürlich sehr
stark auf das Programm an).

So ist mein Verständnis von der Sache, aber vielleicht liege ich ja auch falsch(kann durchaus sein!), dann wäre es nett wenn DU mich berichtigtst ;-)

Alle Angaben wie immer ohne Gewähr! :-)

udn 2. das es schon im RAM ist und so nicht noch von der Platte geholt werden muss.
Was ist im RAM? - Die Perlinstanz?
Der fertige Maschinecode des Scriptes. Aber was ist eine Perl-Instanz? Ein Prozess?

Ja, eine Perlinstanz ist ein Prozess. Genauer meinte ich eben den Perlinterpreter +
optimierter Codebaum. Diese zwei darf man _nie_ trennen. Ein Perlscript läuft nicht ohne
den Perlinterpreter, anders ein kompiliertes C-Programm. Es gibt keinen fertigen
Maschinencode eines Scriptes. Bei Perl gibt es höchstens einen optimierten Parse-Baum
und den Maschinencode des Perlinterpreters (ja, _der_ ist in Maschinencodem, nicht aber
das Script). Naja, ich übertreibe hier wohl etwas; was ich sagen will ist, dass ein
Script immer ein Script bleiben wird und selber, ohne Interpreter nicht lauffähig ist.
Das ist für mich der Unterschied zwischen Programm und Script.

--- optimierter Parse-Baum ---

davon hab ich ja jetzt einiges gesprochen, vielleicht noch ein zwei Worte dazu, falls
du das noch nicht weisst: Was ist ein Perl/PHP-Script? - Nix weiter als Text. Text,
der irgendwann mal was tun soll; dazu braucht es aber ein Programm, welcher diesen Text
interpretiert => Perl/PHP-Interpreter (soweit ist's ja jedem klar). Was machen nun diese
Interpreter (ich spreche jetzt vom Perl-)? - Er parsed den Text und bringt ihn in eine
interne Form (bei Perl ist das der Codebaum, eine baumartige Struktur, die reich
verzweigt ist und jedes Blatt ist irgendweine "Aktion" <- Operator [bei Perl gibt's glaub
ich etwa 300 Operatoren]). Wenn nun diese "Kompilierphase" beendet ist, fängt Perl
oben an und je nach aktuellem Kontext gehts nach links oder rechts im Baum (evtl. noch
komplizierter natürlich); aber am Anfang des Programmes kannst du den Weg noch nicht
absehen. Nun gut, ein kompiliertes Perl-Programm ist nicht Maschinencode, sondern eine
ziemlich weitverknüpfte, komplexe Datenstruktur. Eine Datenstruktur, die eben nur
zusammen mit einem Interpreter von Nutzen ist. Bei mod_perl wird diese Datenstruktur
auch im Speicher gehalten und somit fällt das langsame parsen und optimieren weg; zudem
sind die Perlinterpreter auch schon im Speicher => gar kein Festplattenzugriff mehr
nötig.

Tjo, wer (du?) sich dafür mehr interessiert, sollte sich die B-Module von Perl mal
ansehen.
Da kann man selber durch diesen ParseBaum "durchbrowsen" oder ein Perl-Script wirklich
"kompilieren" (den Parsebaum binär abbilden und dann wieder z. B. über eine Datei
einlesen und den Parsebaum überschreiben, etwas performanter, als wenn das Script im
"text/plain" vorliegt.)

---

Viele Grüsse

Philipp

0 40

Eigener Webserver in Delphi

Kay
  • sonstiges
  1. 0
    Philipp Hasenfratz
  2. 0
    Philipp Hasenfratz
    1. 0
      Kay
    2. 0
      Andreas Korthaus
      1. 0
        Philipp Hasenfratz
        1. 0

          OT: performanter Server für HTTP-Logging

          Andreas Korthaus
          • webserver
          1. 0
            Philipp Hasenfratz
            1. 0
              Andreas Korthaus
              1. 0
                Philipp Hasenfratz
              2. 0
                Michael Schröpl
            2. 0
              Sven Rautenberg
              1. 0
                Philipp Hasenfratz
                1. 0
                  Andreas Korthaus
                  1. 0
                    Philipp Hasenfratz
                    1. 0
                      Andreas Korthaus
                      1. 0
                        Andreas Korthaus
                        1. 0
                          Philipp Hasenfratz
                          1. 0
                            Andreas Korthaus
                            1. 0
                              Philipp Hasenfratz
                              1. 0
                                Andreas Korthaus
                                1. 0
                                  Philipp Hasenfratz
                              2. 0
                                Michael Schröpl
                                1. 0
                                  Andreas Korthaus
                            2. 0
                              Michael Schröpl
                        2. 0
                          Michael Schröpl
                          1. 0
                            Andreas Korthaus
                      2. 0
                        Philipp Hasenfratz
                        1. 0
                          Andreas Korthaus
                          1. 0
                            Philipp Hasenfratz
                            1. 0
                              Andreas Korthaus
                              1. 0
                                Philipp Hasenfratz
                                1. 0
                                  Andreas Korthaus
                                  1. 0
                                    Philipp Hasenfratz
                          2. 0
                            Michael Schröpl
                            1. 0
                              Andreas Korthaus
                              1. 0
                                Michael Schröpl
                  2. 0
                    Michael Schröpl
                    1. 0
                      Andreas Korthaus
                      1. 0
                        Michael Schröpl