<?xml version="1.0"?>
<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.de.xsl"?>
<modulesynopsis metafile="mod_unique_id.xml.meta">
<name>mod_unique_id</name>
<description>Stellt eine Umgebungsvariable mit einer eindeutigen Bezeichnung
für jede Anfrage zur Verfügung.</description>
<status>Erweiterung</status>
<sourcefile>mod_unique_id.c</sourcefile>
<identifier>unique_id_module</identifier>
<summary>
<p>Dieses Modul stellt eine Umgebungsvariable mit einer
Bezeichnung für jede Anfrage zur Verfügung, die unter bestimmten
Bedingungen für jede Anfrage eindeutig ist. Diese Bezeichnung
ist auch für unterschiedliche Rechner eines korrkt konfiguierten
Rechnerblocks eindeutig. Die Umgebungsvariable <code>UNIQUE_ID</code>
wird für jede Anfrage gesetzt. Eindeutige Bezeichnungen werden für
verschiedene Zwecke benötigt, die über den Rahmen des eigentlichen
Dokuments hinausgehen.</p>
</summary>
<section id="theory">
<title>Hintergrund</title>
<p>Es folgt eine kurze Zusammenfassung der Funktionsweise des
Apache-Servers unter Unix funktioniert. (Unter Windows NT wird dieses
Modul nicht unterstützt.) Auf Unix-Rechnern erzeugt der Apache
mehrere Kindprozesse für jeweils eine Anfrage. Jeder Kindprozess kann
während seiner Lebensdauer mehrere Anfragen bedienen. Im Zusammenhang
dieser Erläuterung wird davon ausgegangen, dass die Kindprozesse keine
Daten gemeinsam nutzen. Sie werden als HTTPD-Prozesse bezeichnet.</p>
<p>Die Website operiert mit einem oder mehreren Rechnern, die in
ihrer Gesamtheit als Cluster bezeichnet werden. Jeder Rechner kann mehrere
Apache-Instanzen ausführen, die hier in ihrer Gesamtheit als
"Universum" bezeichnet werden. Unter bestimmten Voraussetzungen kann dieses
Universum eindeutige Bezeichnungen für jede Anfrage erzeugen, ohne
dass dafür
eine ausführlichere Kommunikation zwischen den Rechnern des Clusters
erforderlich ist.</p>
<p>Die Rechner des Clusters sollten die folgenden Anforderungen
erfüllen
(selbst wenn nur ein Rechner vorhanden ist, sollte des Uhr mit
NTP synchronisiert werden):</p>
<ul>
<li>Die Uhrzeit des Rechners wird über NTP oder ein anderes
Netzwerkprotokoll synchronisiert.</li>
<li>Die Host-Namen der Rechner unterscheiden sich voneinander, so
dass das Modul eine Suche nach Host-Namen durchführen kann und
für jeden Rechner des Clusters eine andere IP-Adresse
erhält.</li>
</ul>
<p>Hinsichtlich des Betriebssystems wird davon ausgegangen, dass die
Pids (Prozess-IDs) 32 Bit groß sind. Verwendet das Betriebssystem
mehr als
32 Bit für eine Pid, dann lässt sich der Code leicht anpassen.</p>
<p>Ausgehend von diesen Voraussetzungen, kann zu einem bestimmten
Zeitpunkt jeder HTTPD-Prozess eines beliebigen Rechners aus dem
Cluster von allen anderen HTTPD-Prozessen unterschieden werden. Hierfür
reichen die IP-Adresse des Rechners und die Pid des HTTPD-Prozesses
aus. Um eindeutige Bezeichnungen für jede Anfrage erzeugen zu
können,
müssen lediglich die verschiedenen Zeitpunkte unterschieden werden.</p>
<p>Für diese Unterscheidung wird ein Unix-Zeitstempel
(die seit dem 1. Januar 1970 (UTC) vergangegenen Sekunden) und ein
16-Bit-Zähler verwendet. Der Zeitstempel hat nur eine Genauigkeit von
einer Sekunde, weshalb mit dem Zähler 65.536 Werte
innerhalb einer Sekunde erzeugt werden. Dieses Quartett aus
<code>ip_addr</code>,
<code>pid</code>, <code>time_stamp</code> und Zähler reicht
aus, um 65.536 Anfragen pro Sekunde und HTTPD-Prozess zu
nummerieren. Die Tatsache, dass die Prozess-IDs im Laufe der
Zeit wiederverwendet werden, wird durch den Zähler abgefangen.</p>
<p>Wird ein HTTPD-Kindprozess erzeugt, wird der Zähler mit
dem Restwert der Division der Anzahl der vergangenen Mikrosekunden
durch 10 dividiert durch 65.536 initialisiert, um Varianzprobleme
mit den niederwertigen Bits des Mikrosekunden-Zeitgebers einiger
Systeme zu vermeiden. Für das Erzeugen einer eindeutigen Bezeichnung
wird der Zeitstempel der Eingangszeit der Anfrage beim Webserver benutzt.
Der Zähler wird beim Erzeugen einer Bezeichnung immer
inkrementiert (und darf überlaufen).</p>
<p>Der Serverkern erzeugt beim Aufspalten jedes Prozesses eine Pid
(bei vielen Unix-Systemen ist sie 16 Bit und bei neueren 32 Bit
groß), bei
der es irgendwann zum Überlauf und damit zur Wiederverwendung der
Pids kommt. Erfolgt diese Wiederverwendung jedoch nicht innerhalb der
gleichen Sekunde, wird die Eindeutigkeit des Quartetts nicht gestört.
Es wird also
davon ausgegangen, dass das System nicht mehr als 65.536 Prozesse
pro Sekunde startet (bei einigen Unix-Systemen können es zwar bis zu
32.768 Prozessen sein, was allerdings sehr unwahrscheinlich ist).</p>
<p>Wiederholt sich die Zeit aus irgendwelchen Gründen (wenn
beispielsweise
die Systemuhr zurückgegestellt wird), kann es zu einer
Wiederverwendung der Pid und des Zeitstempels kommen, was durch
die Initialisierung des Zähler aufgefangen werden soll. Er soll mit
einer
echten Zufallszahl initialisiert werden, die aber bei den meisten Systemen
nicht
zur Verfügung steht (die Funktion <code>rand()</code> kann nicht
verwendet werden, weil der Generator bei einer Zeitauflösung von einer
Sekunde mit der gleichen Zeit operieren würde). Diese Lösung ist
nicht perfekt.
</p>
<p>Wie gut ist die Lösung? Angenommen ein Rechner bedient
500 Anfragen pro Sekunde (was eine realistische Obergrenze ist, weil die
Systeme in der Regel mehr leisten, als nur statische Dateien zu
verschieben).
Hierfür benötigt er eine Reihe von Kindprozessen, deren Zahl von
der Anzahl der konkurrierenden Clients abhängt. Bei einer
pssimistischen
Einschätzung kann ein einzelner Kindprozess bis zu 500 Anfragen pro
Sekunde bedienen. Daraus ergeben sich 1.000 mögliche Anfangswerte
für den
Zähler, so dass sich zwei Sequenzen von 500 Anfragen überlappen.
Bei einer
Zeitwiederholung und einer Zeitauflösung in Sekunden besteht daher eine
Wahrscheinlichkeit von 1,5 % für eine Wiederholung des
Zählerwertes und
für eine Aufhebung der Eindeutigkeit. Dies ist eine sehr pessimistische
Ausgangssituation, die in der Praxis wahrscheinlich nicht eintreten wird.
Ist ein Rechner so beschaffen, dass dennoch eine Chance besteht, dass diese
Situation eintritt, dann sollte ein 32-Bit-Zähler benutzt werden
(hierfür
muss der Code geändert werden).</p>
<p>Das Zurückstellen der Zeit bei der Umstellung von Winter- und
Sommerzeit
kann außer Acht gelassen werden, weil die hier verwendte UTC-Zeit
immer
vorgestellt wird. Bei x86-Unixrechnern kann eine korrekte Konfiguration
erforderlich sein. Die Uhr der Hauptplatine muss für die Kompensation
auf
UTC-Zeit eingestellt werden. Bei Verwendung des NTP-Protokolls ist die
UTC-Zeit aber unmittelbar nach dem Rechnerstart korrekt.</p>
<p>Die Umgebungsvariable <code>UNIQUE_ID</code> wird durch
Verschlüsselung des 112 Bit großen Quartetts (32-Bit-IP-Adresse,
32-Bit-Pid, 32-Bit-Zeitstempel, 16-Bit-Zähler) mit Hilfe des Alphabets
<code>[EMAIL PROTECTED]</code> in einer mit der
MIME-base64-Verschlüsselung
vergleichbaren Form mit 19 Zeichen konstruiert. Das MIME-base64-Alphabet
umfasst eigentlich die Zeichen <code>[A-Za-z0-9+/]</code>, die Zeichen
<code>+</code> und <code>/</code> müssen in URLs jedoch speziell
kodiert werden und sind daher nicht so erwünscht. Alle Werte werden
in der Netzwerk-Bytereihenfolge kodiert, so dass die Verschlüsselung
bei Architekturen mit unterschiedlicher Bytereihenfolge vergleichbar ist.
Die
tatsächliche Reihenfolge der Verschlüsselung lautet: Zeitstempel,
IP-Adresse,
Pid, Zähler. Diese Reihenfolge hat einen Sinn und sollte von
Verschlüsselungsprogrammen nicht durcheinander gebracht werden.
Programme sollten die komplette kodierte <code>UNIQUE_ID</code>
als in sich geschlossene Einheit betrachten, die nur mit anderen
<code>UNIQUE_ID</code>-Variablen auf Gleichheit verglichen
werden kann.</p>
<p>Die Reihenfolge wurde gewählt, damit die Verschlüsselung
geändert werden
kann, ohne dass es Probleme mit vorhandenen
<code>UNIQUE_ID</code>-Datenbank gibt. Bei den neuen
Verschlüsselungen sollte der Zeitstempel ebenfalls an erster Stelle
stehen
und das gleiche Alphabet und die Bitlänge in anderer Weise verwendet
werden. Da die Zeitstempel im Wesentlichen eine ansteigende Sequenz sind,
reicht ein Sekunden-Flag für die Sekunde aus, zu der alle Rechner des
Clusters
die Verarbeitung von Anfragen unterbrechen, das Verschlüsselungsformat
wechseln und anschließend die Arbeit mit der neuen
Verschlüsselung wieder
aufnehmen.
</p>
<p>Diese tragbare Lösung kann auch für Multithread-Systeme wie
Windows NT übernommen und zukünftigen Bedürfnissen angepasst
werden. Die erzeugten Bezeichnungen sind im Prinzip ewig gültig,
weil zukünftige Bezeichnungen länger sein können. Eine
Kommunikation zwischen den Rechnern des Clusters ist abgesehen von der
nicht weiter ins Gewicht fallenden NTP-Synchronisation nicht erforderlich.
Eine Kommunikation zwischen den HTTPD-Prozessen ist ebenfalls nicht
notwendig (sie findet implizit über die vom Serverkern zugewiesene Pid
statt). In ganz speziellen Situationen kann die Bezeichnung verkürzt
werden
(die 32 Bit große IP-Adresse ist beispielsweise übertrieben, es
gibt jedoch keine
geeignete kürzere Ersetzung). </p>
</section>
</modulesynopsis>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]