Diese Woche hatte ich zahlreiche Schreckminuten - eine Kernelpanic nach der nächsten... obwohl genau diese Konfiguration eine Uptime von >450 Tagen hatte und immer problemlos funktioniert hat.
Ich habe den Linux-Kernel des Hosts auf meinem VServer-System getauscht (von 2.6.22.18 auf 2.6.26.2) und auch das Update von Debian "Etch" nach "Lenny" vollzogen.
Stutzig wurde ich als der neue Kernel auch ein "Segfault" nach dem nächsten (verschiedene!) meldete...
Ein "memtester"-Aufruf im laufenden Betrieb unter Linux brachte sehr schnell eine Kernelpanic... Ein memtest86+ bestätigte meine Vermutung: Nach wenigen Sekunden hatte memtest86+ schon RAM-Fehler festgestellt (im Bereich um 305MB).
Nach dieser Erkenntnis habe ich den ersten RAM-Riegel ausgebaut und den 2ten in die erste Bank gesteckt. Dann nochmal einen memtest86+ und einen memtester unter Linux gemacht - alles ohne Probleme. Jetzt läuft mein Server wieder mit mageren 1000MB RAM - aber er läuft wieder.
Fazit: Auch wenn man Markenspeicher eines renommierten Herstellers verwendet kann es nach 3-4 Jahren auch zu Problemen kommen - oder die Staubschicht auf dem RAM und der RAM-Bank war etwas zu hoch ;)
Und zum Abschluss noch ein Kernel-Zitat:
"Eeek! page_mapcount(page) went negative! (-1)".
Posts mit dem Label server werden angezeigt. Alle Posts anzeigen
Posts mit dem Label server werden angezeigt. Alle Posts anzeigen
Montag, 27. Juli 2009
Dienstag, 14. Juli 2009
Tip: Tomcat 5.x Encoding-Problematik...
Das Encoding-Problem ist wohl vielen bekannt - ich wollte mir auch schon ein "Schei* Encoding" T-Shirt bestellen...
Im Apache Tomcat 6 reichte bei mir immer ein
Natürlich sollte man das wie z.B. im Spring-Framework wenn möglich in einen eigenen Servlet-Filter (siehe CharacterEncodingFilter) auslagern.
Beim Tomcat 5.x hatte ich mit diesem Vorgehen leider kein Glück. Weder die Context-Konfigurationsoptionen "URIEncoding" noch "useBodyEncodingForURI" in der Konfigurationsdatei brachten Besserung. Dieses Problem hatten aber wohl schon mehrere Anwender - siehe hier.
Bisher konnte ich das Problem leider nur auf folgendem Weg lösen:
Update 14.07.2009: Ich konnte mit folgender Testseite alle drei Tomcat-Versionen:
Wirklich komisch - ich muss nochmal genau nachforschen warum das ältere Projekt im Tomcat 6.x problemlos mit dieser Variante funktionierte und bei Tomcat 5.x Probleme bereitet hatte.
Update 15.07.2009: Das Rätsel ist gelöst! eine jar-Datei hat zu diesem Phänomen bei dem alten Projekt geführt. In meinem Fall eine jar-Datei des CMS FirstSpirit namens "fs-access.jar". Wenn diese aus dem "WEB-INF/lib"-Verzeichnis entfernt wird und "setCharacterEncoding" verwendet wird funktioniert auch im Tomcat 5.x alles wie erwartet. Evtl. ist die "fs-access.jar" in diesem Fall eine veraltete Version. Warum der Tomcat 5.x damit ein Problem hat und der Tomcat 6.x nicht ist mir aber immer noch ein Rätsel.
Update 15.07.2009 / 2: Die Kontext-Konfiguration "URIEncoding" wirkt sich nur auf das URI-Encoding aus! d.h. das muss verwendet werden wenn man die Parameter z.B. im Querystring übergibt (HTTP-Methode GET). Wenn das in der server.xml konfiguriert wurde kann man sich das Umwandeln von "ISO-8859-1"-Zeichenfolgen nach "UTF-8" sparen.
Weitere Informationen:
Im Apache Tomcat 6 reichte bei mir immer ein
request.setCharacterEncoding("UTF-8");
bei folgendem Seitenkopf in der JSP <%@ page pageEncoding=”UTF-8″ contentType=”text/html; charset=UTF-8″%>und ich konnte die Anfrageparameter in UTF-8 ohne Probleme auslesen.
Natürlich sollte man das wie z.B. im Spring-Framework wenn möglich in einen eigenen Servlet-Filter (siehe CharacterEncodingFilter) auslagern.
Beim Tomcat 5.x hatte ich mit diesem Vorgehen leider kein Glück. Weder die Context-Konfigurationsoptionen "URIEncoding" noch "useBodyEncodingForURI" in der Konfigurationsdatei brachten Besserung. Dieses Problem hatten aber wohl schon mehrere Anwender - siehe hier.
Bisher konnte ich das Problem leider nur auf folgendem Weg lösen:
String firstname = request.getParameter("firstname");
if (firstname != null) {
firstname = new String(firstname.getBytes("ISO-8859-1"),"UTF-8");
}In diesem Fall konvertiere ich den Parameter von "ISO-8859-1" nach "UTF-8". Das sollte laut Tomcat FAQ auch kein Problem darstellen, da das Default-Encoding bei Servlets laut dem FAQ auch "ISO-8859-1" sein sollte:Default Encoding for POST
ISO-8859-1 is defined as the default character set for HTTP request and response bodies in the servlet specification (request encoding: section 4.9 for spec version 2.4, section 3.9 for spec version 2.5; response encoding: section 5.4 for both spec versions 2.4 and 2.5). This default is historical: it comes from sections 3.4.1 and 3.7.1 of the HTTP/1.1 specification.
Update 14.07.2009: Ich konnte mit folgender Testseite alle drei Tomcat-Versionen:
- 5.0.28
- 5.5.27
- 6.0.20
Wirklich komisch - ich muss nochmal genau nachforschen warum das ältere Projekt im Tomcat 6.x problemlos mit dieser Variante funktionierte und bei Tomcat 5.x Probleme bereitet hatte.
Update 15.07.2009: Das Rätsel ist gelöst! eine jar-Datei hat zu diesem Phänomen bei dem alten Projekt geführt. In meinem Fall eine jar-Datei des CMS FirstSpirit namens "fs-access.jar". Wenn diese aus dem "WEB-INF/lib"-Verzeichnis entfernt wird und "setCharacterEncoding" verwendet wird funktioniert auch im Tomcat 5.x alles wie erwartet. Evtl. ist die "fs-access.jar" in diesem Fall eine veraltete Version. Warum der Tomcat 5.x damit ein Problem hat und der Tomcat 6.x nicht ist mir aber immer noch ein Rätsel.
Update 15.07.2009 / 2: Die Kontext-Konfiguration "URIEncoding" wirkt sich nur auf das URI-Encoding aus! d.h. das muss verwendet werden wenn man die Parameter z.B. im Querystring übergibt (HTTP-Methode GET). Wenn das in der server.xml konfiguriert wurde kann man sich das Umwandeln von "ISO-8859-1"-Zeichenfolgen nach "UTF-8" sparen.
Weitere Informationen:
Labels:
firstspirit,
java,
programmierung,
server,
tip,
tomcat
Mittwoch, 4. März 2009
Tip: Server-Konfigurationsdateien in einer verteilten Versionsverwaltung
Das Problem
Konfigurationsdateien auf einem Server (i.d.R "/etc") ändern sich häufiger - und man möchte eine Historie - wann, was, warum modifiziert wurde. Das Problem wird noch schlimmer wenn mehrere Personen einen Server konfigurieren. Person A sollte wissen wann, was und warum Person B z.B. die Webserverkonfiguration modifiziert hat.
Welches SCM
Zuerst dachte ich an Subversion, da ich dieses SCM schon von der Programmierung kannte.
Folgende Punkte sprechen aber dagegen:
Lösung: eine verteilte Versionsverwaltung.
Für diesen Zweck habe ich mir folgende verteilte Versionsverwaltungen angesehen:
Entscheidung: Ich habe mich für Mercurial aus folgenden Gründen entschieden:
Wie wird es gemacht
Schritt 1: man initialisiert ein neues Repository im "Root" des Dateisystems ("cd /"). Das geschieht mit dem Kommando "hg init". Nun legt Mercurial ein .hg-Verzeichnis in / an (es wird aber wirklich nur ein einziges Verzeichnis angelegt!).
Schritt 2: Dateien aus "/etc" zum Repository hinzufügen (unter Versionskontrolle stellen) geht mit dem Kommando "hg add /etc".
Schritt 3: Mit einem "hg commit" werden die neu hinzugefügten Dateien ins Repository übertragen.
Hier noch ein paar nützliche Kommandos:
Status abfragen: "hg status -amrd" (added, modified, removed, deleted)
Dateien umbenennen: mit "hg rename QUELLE ZIEL" kann man dann Dateien umbenennen. Man sollte also anstatt "mv" in Zukunft einfach dieses Kommando verwenden.
Dateien löschen: mit "hg remove DATEI/VERZEICHNIS" kann man die Datei oder das Verzeichnis aus der Versionierung nehmen. Ohne Parameter löscht "hg remove" auch die lokale Datei oder das Verzeichnis. Wenn man nur die Datei oder das Verzeichnis aus der Versionskontrolle nehmen will diese aber lokal behalten möchte sollte man "hg remove -Af DATEI/VERZEICHNIS" verwenden.
Unterschiede ansehen: mit "hg diff DATEI/VERZEICHNIS" kann man sich den Unterschied zwischen der lokalen Version und der im Repository befindlichen Version ansehen.
Repository für andere zugänglich machen: den eingebauten kleinen Webserver kann man mit "hg serve" starten. Dann kann man über "http://IP:8000" auf das Repository zugreifen. Hier ein paar Screenshots:



Repository "klonen": mit dem Kommando "hg clone http://URL ZIEL" kann man eine Repository-Kopie erstellen.
Grafischer Repository-Browser: sogar ein grafischer Repository-Browser ist bei Mercurial enthalten. Diesen bekommt man mit dem Kommando "hg view":

Konfiguration: Es gibt eine globale Konfiguration in "/etc/mercurial/hgrc" und pro User eine im Home-Verzeichnis "~/.hgrc". Mehr Informationen hierfür gibts mit "man hgrc".
Shell completion: Mercurial liefert wohl auch eine zsh-Completion mit. Dazu evtl. in einem folgenden Blog-Beitrag mehr.
Debian: Wer wie ich immer noch Debian Etch verwendet findet eine aktuellere Version von Mercurial im Backports-Reporitory.
Übrigens: das Projekt FSVS ist mir auch in den Sinn gekommen. Ich fand die Bedienung zu kompliziert und das Programm verwendet das SVN-Backend, was meiner Meinung nicht die beste Wahl hierfür ist. Dieses Programm berücksichtigt dann noch die Dateirechte und Benutzer/Gruppe. Das kann die hier vorgestellte Lösung nicht.
Update 14.03.2009: Wie ich heute gesehen habe gibt es auch das Projekt etckeeper das man mit mercurial, git, darcs und bzr verwenden kann. Es bietet Paketmanager-Integration und speichert Metadaten (u.a. Rechte) der Dateien mit ab. Sehr interessante Sache - das werde ich mal versuchen.
Weitere Links:
Konfigurationsdateien auf einem Server (i.d.R "/etc") ändern sich häufiger - und man möchte eine Historie - wann, was, warum modifiziert wurde. Das Problem wird noch schlimmer wenn mehrere Personen einen Server konfigurieren. Person A sollte wissen wann, was und warum Person B z.B. die Webserverkonfiguration modifiziert hat.
Welches SCM
Zuerst dachte ich an Subversion, da ich dieses SCM schon von der Programmierung kannte.
Folgende Punkte sprechen aber dagegen:
- Subversion erzeugt in jedem Verzeichnis in der "Working Copy" ein ".svn"-Verzeichnis
- die Geschwindigkeit bei vielen Dateien ist bei Subversion "nicht der Renner"
- das Subversion-Backend ("Dateisystem") wird schnell sehr groß
- das Konzept der "Working Copy" (welche erst ausgecheckt werden muss) und dem zentralen Repository ist hier leider etwas umständlich
Lösung: eine verteilte Versionsverwaltung.
Für diesen Zweck habe ich mir folgende verteilte Versionsverwaltungen angesehen:
Entscheidung: Ich habe mich für Mercurial aus folgenden Gründen entschieden:
- einfache Verwendung
- gute Performance, Repository-Größe klein
- integrierter Webserver
Wie wird es gemacht
Schritt 1: man initialisiert ein neues Repository im "Root" des Dateisystems ("cd /"). Das geschieht mit dem Kommando "hg init". Nun legt Mercurial ein .hg-Verzeichnis in / an (es wird aber wirklich nur ein einziges Verzeichnis angelegt!).
Schritt 2: Dateien aus "/etc" zum Repository hinzufügen (unter Versionskontrolle stellen) geht mit dem Kommando "hg add /etc".
Schritt 3: Mit einem "hg commit" werden die neu hinzugefügten Dateien ins Repository übertragen.
Hier noch ein paar nützliche Kommandos:
Status abfragen: "hg status -amrd" (added, modified, removed, deleted)
Dateien umbenennen: mit "hg rename QUELLE ZIEL" kann man dann Dateien umbenennen. Man sollte also anstatt "mv" in Zukunft einfach dieses Kommando verwenden.
Dateien löschen: mit "hg remove DATEI/VERZEICHNIS" kann man die Datei oder das Verzeichnis aus der Versionierung nehmen. Ohne Parameter löscht "hg remove" auch die lokale Datei oder das Verzeichnis. Wenn man nur die Datei oder das Verzeichnis aus der Versionskontrolle nehmen will diese aber lokal behalten möchte sollte man "hg remove -Af DATEI/VERZEICHNIS" verwenden.
Unterschiede ansehen: mit "hg diff DATEI/VERZEICHNIS" kann man sich den Unterschied zwischen der lokalen Version und der im Repository befindlichen Version ansehen.
Repository für andere zugänglich machen: den eingebauten kleinen Webserver kann man mit "hg serve" starten. Dann kann man über "http://IP:8000" auf das Repository zugreifen. Hier ein paar Screenshots:



Repository "klonen": mit dem Kommando "hg clone http://URL ZIEL" kann man eine Repository-Kopie erstellen.
Grafischer Repository-Browser: sogar ein grafischer Repository-Browser ist bei Mercurial enthalten. Diesen bekommt man mit dem Kommando "hg view":

Konfiguration: Es gibt eine globale Konfiguration in "/etc/mercurial/hgrc" und pro User eine im Home-Verzeichnis "~/.hgrc". Mehr Informationen hierfür gibts mit "man hgrc".
Shell completion: Mercurial liefert wohl auch eine zsh-Completion mit. Dazu evtl. in einem folgenden Blog-Beitrag mehr.
Debian: Wer wie ich immer noch Debian Etch verwendet findet eine aktuellere Version von Mercurial im Backports-Reporitory.
Übrigens: das Projekt FSVS ist mir auch in den Sinn gekommen. Ich fand die Bedienung zu kompliziert und das Programm verwendet das SVN-Backend, was meiner Meinung nicht die beste Wahl hierfür ist. Dieses Programm berücksichtigt dann noch die Dateirechte und Benutzer/Gruppe. Das kann die hier vorgestellte Lösung nicht.
Update 14.03.2009: Wie ich heute gesehen habe gibt es auch das Projekt etckeeper das man mit mercurial, git, darcs und bzr verwenden kann. Es bietet Paketmanager-Integration und speichert Metadaten (u.a. Rechte) der Dateien mit ab. Sehr interessante Sache - das werde ich mal versuchen.
Weitere Links:
Montag, 2. März 2009
Tip: Server-Überwachung mit Visualisierung
Ich verwende seit ca. 2 Jahren zusätzlich zur Nagios-Überwachung meiner Server auch munin. Munin zeichnet kontinuierlich Daten auf und erzeugt schöne Grafiken daraus. So kann man z.B. feststellen, wann die CPU am wärmsten war oder wie stark die Datenmenge auf der Festplatte über einen Zeitraum zunimmt.
Hier ein paar Beispiele:

Hier kann man sehen, dass meine Daten auf der Festplatte innerhalb eines Jahres (02/2008 bis 02/2009) ziemlich zugelegt haben. Gut zu wissen, dass diese Steilkurve die Backup-Partition mit diversen rsnapshot-Ständen ist :)

...und hier wie die Temperatur zwischen Juni und August "ein Hoch" hat. Auch hier geht der Graph von 02/2008 bis 02/2009.
Die Installation von munin ist sehr einfach. Man installiert einfach auf den Server das Paket munin und für die zu überwachenden Knoten das munin-node Paket. Dann muss man dem Server nur noch die Knoten in der Datei "/etc/munin/munin.conf" mitgeben und fertig. Auf den munin-nodes kann man dann die einzelnen Plugins konfigureren. Tip für Debian-Benutzer: es können noch zusätzliche Plugins mit dem Paket munin-plugins-extra installiert werden.
Hier ein paar Beispiele:

Hier kann man sehen, dass meine Daten auf der Festplatte innerhalb eines Jahres (02/2008 bis 02/2009) ziemlich zugelegt haben. Gut zu wissen, dass diese Steilkurve die Backup-Partition mit diversen rsnapshot-Ständen ist :)

...und hier wie die Temperatur zwischen Juni und August "ein Hoch" hat. Auch hier geht der Graph von 02/2008 bis 02/2009.
Die Installation von munin ist sehr einfach. Man installiert einfach auf den Server das Paket munin und für die zu überwachenden Knoten das munin-node Paket. Dann muss man dem Server nur noch die Knoten in der Datei "/etc/munin/munin.conf" mitgeben und fertig. Auf den munin-nodes kann man dann die einzelnen Plugins konfigureren. Tip für Debian-Benutzer: es können noch zusätzliche Plugins mit dem Paket munin-plugins-extra installiert werden.
Abonnieren
Posts (Atom)