muli hat geschrieben:Ich steh ein wenig unter Zeitdruck
Hallo muli!
So wie ich das sehe, unterschätzt du die Geschwindigkeit des Apachen und des darunter befindlichen Linux-/Windows-Systems. Wenn du deine Daten in eine Datei schreibst und mit einer Lock-Datei den gleichzeitigen Schreibzugriff unterbindest, dann bist du nicht merkbar langsamer als wenn du alles selbst im Speicher hälst. Warum? Weil die Betriebssysteme nicht blöd sind. Wird eine Datei 100 mal die Sekunde angefordert, dann bleibt die im Cache und wird nicht jedes Mal neu eingelesen. Rein theoretisch könntest du sogar den Apachen ohne Zusatzsoftware für so etwas verwenden. Du installierst dir **mod_dav** und kannst damit direkt über HTTP Dateien auf dem Server verändern. Diese werden dann natürlich vom Apachen ausgeliefert.
Wenn du es komplizierter haben möchtest, und die Daten unbedingt im Speicher liegen müssen, dann brauchst du einen eigenständig laufenden Prozess, der nicht vom Apachen abgewürgt wird. Du kennst ja schon Zope. Zope kann als eigenständiger Prozess laufen. Zope bindet man gerne in den Apachen ein, indem man die Requests mit **mod_proxy** an den Zope-Prozess weiterleitet. Dieser arbeitet den Request ab und gibt den Response wieder an den Apachen zurück, damit dieser ihn an den Browser zurücksenden kann.
Genau so wie du es mit Zope machen kannst, kannst du auch ein CherryPy als eigenständig laufenden Prozess im Hintergrund laufen lassen. Du hast mehrere Möglichkeiten. CherryPy läuft in diesem Fall als eigengständiger Server. Du kannst CherryPy z.B. auf dem Port 8080 horchen lassen. Jede Anfrage eines Browsers, die an diesen Port gesendet wird, wird von CherryPy direkt beantwortet. Der Apache hat nichts damit zu tun. So bekommst du die beste Geschwindigkeit.
Du kannst CherryPy aber auch über **mod_proxy** in den Apachen einbinden. Wie mit Zope. Nur mit dem Unterschied, dass CherryPy sehr leichtgewichtig ist. Das hat den Vorteil, dass die Requests vom Apachen beantwortet werden. So kann der Apache auf Port 80 horchen, die Anfragen an CherryPy weitergeben und dann auch wieder beantworten.
Ich habe dir mit diesen Vorschlägen geantwortet, weil du geschrieben hast, dass du unter Zeitdruck bist. Und wenn du dich schon nicht davon überzeugen lässt, dass es unnötig ist, die Daten im Speicher zu halten, dann musst du in die bittere Pille beißen und die Daten im Speicher halten.
Unter Linux musst du dir zuerst ein aktuelles CherryPy installieren -->
http://halvar.at/python/cherrypy_fastcg ... stallieren
Dann legst du dir am besten einen "Virtuellen Host" an in dem du arbeiten kannst -->
http://halvar.at/python/cherrypy_fastcg ... llen-hosts
Dann musst du den CherryPy-Server beim Linuxstart starten lassen. Das machst du über einen Eintrag in */etc/init.d/* oder einem ähnlichen System. Hier die Datei */etc/init.d/cherrypy-halvar*, mit der ich auf einem Debian-Server den CherryPy-Prozess für
http://halvar.at starte:
http://paste.pocoo.org/show/92753/
Das hier ist die Datei *001_halvar.conf*, mit der ich die Verbindung zwischen dem Apachen und CherryPy herstelle:
http://paste.pocoo.org/show/92755/
Für dich sind hauptsächlich die zwei Zeilen ab Zeile 53 wichtig. Damit wird CherryPy in den Apachen eingebunden.
Jetzt kann CherryPy alle Anfragen des Apachen beantworten und direkt aus dem Speicher holen.
mfg
Gerold
PS: Das hätte ich fast vergessen... So ein Universaldatenspeicher (für GET, POST und DELETE) für Textdaten könnte mit CherryPy so aussehen:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import cherrypy
datenspeicher = {}
class RestService(object):
exposed = True
def GET(self, key, *args, **kwargs):
value = datenspeicher.get(key, None)
if value:
cherrypy.response.headers["Content-Type"] = "text/plain"
return value
else:
raise cherrypy.NotFound
def POST(self, key, value, *args, **kwargs):
datenspeicher[key] = value
def DELETE(self, key, *args, **kwargs):
del datenspeicher[key]
def main():
conf = {"/": {"request.dispatch": cherrypy.dispatch.MethodDispatcher()}}
cherrypy.quickstart(RestService(), config = conf)
if __name__ == "__main__":
main()
PS2: Und so sieht es aus, wenn dir die HTTP-Methoden egal sind:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import cherrypy
datenspeicher = {}
class Root(object):
def get_value(self, key, *args, **kwargs):
value = datenspeicher.get(key, None)
if value:
cherrypy.response.headers["Content-Type"] = "text/plain"
return value
else:
raise cherrypy.NotFound
get_value.exposed = True
def set_value(self, key, value, *args, **kwargs):
datenspeicher[key] = value
set_value.exposed = True
def delete_value(self, key, *args, **kwargs):
del datenspeicher[key]
delete_value.exposed = True
def main():
cherrypy.quickstart(Root())
if __name__ == "__main__":
main()
.