Ich glaube ich erwähnte es schon: eines meiner Steckenpferde bei der Arbeit ist das Monitoring, also die Überwachung von Rechnern. Bei bestimmten Überwachungen bietet es sich an, den überwachten Rechner seine Messwerte selbst schicken zu lassen. Oft heißt es „es reicht wenn wir den Wert alle fünf Minuten kriegen“, also bietet sich ein Cronjob mit einem geschickt platzierten „*/5“ an.
Nachteil dabei: unter Umständen wird das Monitoring genau alle fünf Minuten zeitgleich mit hunderten Werten von hunderten Rechnern beworfen.
Um das zu entzerren habe ich mir was formschönes ausgedacht:
1 |
sleep $((0x$(echo "$HOSTNAME$0$@" | md5sum | cut -c1-4) % 300)) |
Diese Zeile bewirkt am Anfang eines Skriptes, dass vor der Ausführung eine variable Zeit gewartet wird. Das charmante daran: die Zeit ist abhängig vom Hostnamen, dem Skriptnamen und den Parametern die dem Skript übergeben werden. Es ist keine wirklich zufällige Zeit, das heißt dass man sich darauf verlassen kann dass das Skript ziemlich genau alle fünf Minuten einen Wert ausgibt.
Oh, falls das cut irritiert: wenn ich die hexadezimale Prüfsumme einfach mit $((0x…)) dezimal mache kommt da unter Umständen ein negativer Wert raus. Meine sleep-Version unterstützt leider keine Zeitreisen…
Hat jemand einen Vorschlag wie ich das noch eleganter hinkriegen würde?
EDIT: Vielleicht ist diese Variante noch schöner. Man umgeht mit Awk den ‚bashismus‘ mit dem Modulo, dafür spart man sich aber auch den Aufruf von cut.
1 |
sleep $(echo "$HOSTNAME$0$@" | md5sum | awk '{sub(/./,"");print $1 % 300}') |
Sorgt das mod300 nicht dafür das du eine Schlafzyklus zwischen Null und 299 Sekunden bekommst?
Würde es nicht mehr Sinn machen, eine Zahl zwischen Null und N zugenerieren und das dann auf
300-(N/2) zu addieren? Am besten schön zufällig verteilt, damit die Last entsprechend verteilt ist.
Wenn ich das richtig verstehe, soll es zwar möglichst verteilt sein, aber dann doch zuverlässig im 5 Minuten Intervall, ich vermute, damit zum Beispiel irgendwelche Counter wie „Connections pro 5 Minuten“ nicht driften und schwanken.
Da ergibt modulo 300 ja durchaus Sinn. Okay, je nachdem wäre 301 korrekter.
Also, das scheint mir für den Anwendungsfall durchaus eine coole Lösung zu sein. Nein, ich habe sowas noch nicht nötig gehabt, und was eleganteres ist mir noch nicht untergekommen.
@ft: Manuel hat das richtig erkannt, ich will bei jedem Aufruf gleich lange schlafen wenn das Skript auf dem gleichen Rechner mit den gleichen Parametern aufgerufen wird. Ein anderes Skript soll sich eine andere Zeit ausdenken, auf einem anderen Rechner soll auch eine andere Zeit geschlafen werden. Es soll nur sichergestellt sein dass das Skript jeweils im Abstand von fünf Minuten läuft, der exakte Zeitpunkt ist zweitrangig.