Category Archives: Webtechniken

1000MB / Sek Disk IO Performance KVM VServer

Kürzlich habe ich etwas Hardware im RZ für unseren KVM VServer Cluster erweitert. Nun schafft unser Disk-Subsystem 1000MB/sek:

 

 

Benchmark mit 1MB Blocksize, unlimitiertem Disk-IO und 4 Cores, 4 GB RAM, normale KVM VServer haben ein Disk-IO Limit bei 50MB/s read, 30MB/s write.

 

Endlich weniger IO-Wait 🙂

Yippie!

E-Mail Encoder – mailto Links vor Spam-Crawlern schützen

Weil es doch öfter mal vorkommt, dass man in Webseiten mailto Links einbauen möchte und man meist
vermeiden will, dass die E-Mail Adressen von Spam-Crawlern erfasst werden gibt es hier mehrere Möglichkeiten dem entgegenzuwirken.

Weit verbreitet scheint das verschlüsseln der Mail-Adresse mittels Java-Script. Dies hat jedoch den Nachteil, dass der Browser Java-Script aktiviert haben muss. Gutes Webdesign sollte Java-Script nicht vorraussetzen. Man kann auch die E-Mail Adresse im mailto-Link durch dezimale HTML Entitäten darstellen, so dass diese im Browser ganz normal angezeigt werden und der mailto Link auch vom User benutzt werden kann, der E-Mail Harvester sieht jedoch nur HTML und kann daher die Adresse nicht parsen.

Den Encoder kann man hier testen.

Hier die zugehörige PHP-Funktion:


function spamschutz($email,$href = true) {
$returnemail=preg_replace( "/(.)/se", " '&#' . ord( '\\1' ) . ';' ", $email );
if ($href) {
return "$returnemail";
} else {
return $returnemail;
}

}

MySQL NDB Cluster 7.09a mit nur 2 Nodes (nicht 3!)

in der Dokumentation von mysql cluster wird immer darauf hingewiesen, dass man für ein redundantes Setup mindestens 3 Server benötigt: 2 Server für die NDB-Datenknoten und einen weiteren Server als separater Management-Server. Dies ist jedoch unschön, wenn man nur 2 physikalische Maschinen verwenden will/kann.

Mit etwas Konfigurationsarbeit und dem Linux VServer Patch (auf welchem auch die Vserver bei vlinux.biz laufen) lässt sich das Setup dennoch mit nur 2 Servern durchführen wobei auch ein Server komplett ausfallen kann, ohne dass der mysql cluster down ist oder crashed.

Man installiere ein Debian Lenny oder neuer, wähle entweder den bei Debian mitgelieferten VServer Kernel (linux-image-vserver-bigmem) oder baue seinen eigenen (z.B. 2.6.31.7-vs2.3.0.36.27 ) auf jeweils beiden Systemen.

Dann legt man auf den Servern vier virtuelle Server an:

vserver sql0[1-4] build –context 700[0-3] –hostname sql0[1-4]-n sql0[1-4] –interface sql0[1-4]=eth0:192.168.0.10-14 -m debootstrap — -d lenny

Danach wie gehabt mysql ndb herunterladen und installieren (z.B. mysql-cluster-gpl-7.0.9-linux-i686-glibc23) in /usr/local/ entpacken, und einen symlink auf /usr/local/mysql setzen.

Dann die Konfiguration (config.ini) wie folgt aufsetzen:

[NDBD DEFAULT]
NoOfReplicas: 2

DataDir: /var/lib/mysql-cluster
FileSystemPath: /var/lib/mysql-cluster

# Data Memory, Index Memory, and String Memory

DataMemory: 900M
IndexMemory: 300M
BackupMemory: 128M

MaxNoOfConcurrentOperations=100000

StringMemory=25
MaxNoOfTables=4096
MaxNoOfOrderedIndexes=2048
MaxNoOfUniqueHashIndexes=512
MaxNoOfAttributes=24576

TimeBetweenLocalCheckpoints=20
TimeBetweenGlobalCheckpoints=1000
TimeBetweenEpochs=100

MemReportFrequency=30
BackupReportFrequency=10

### Params for setting logging
LogLevelStartup=15
LogLevelShutdown=15
LogLevelCheckpoint=8
LogLevelNodeRestart=15

### Params for increasing Disk throughput
BackupMaxWriteSize=1M
BackupDataBufferSize=16M
BackupLogBufferSize=4M

[MGM DEFAULT]
PortNumber: 1186
DataDir: /var/lib/mysql-cluster

[NDB_MGMD]
Id:1
HostName: sql01

[NDB_MGMD]
Id:2
HostName: sql02

[NDB_MGMD]
Id:3
HostName: sql03

[NDB_MGMD]
Id:4
HostName: sql04

[NDBD]
Id:5
HostName: sql01

[NDBD]
Id:6
HostName: sql02

[NDBD]
Id:7
HostName: sql03

[NDBD]
Id:8
HostName: sql04

[API]
Id:9
HostName: sql01

[API]
Id:10
HostName: sql02

Nun die Management-Knoten auf allen vier VServern starten / initialisieren. Dazu in /usr/local/mysql

ndb_mgmd –initial -f config.ini

ausführen, anschliessend die 4 ndb Knoten starten (ndbd –initial)

Für die API Nodes natürlich noch mit ./scripts/mysql_install_db die mysql Datenbanken anlegen und anschliessend mit chmod mysql.mysql data -R die Rechte passend setzen.

Anschliessend sollte man mit ndb_mgm => show folgenden Output erhalten:

Cluster Configuration
———————
[ndbd(NDB)]     4 node(s)
id=5    @192.168.0.10  (mysql-5.1.39 ndb-7.0.9, Nodegroup: 0)
id=6    @192.168.0.12  (mysql-5.1.39 ndb-7.0.9, Nodegroup: 0, Master)
id=7    @192.168.0.11  (mysql-5.1.39 ndb-7.0.9, Nodegroup: 1)
id=8    @192.168.0.13  (mysql-5.1.39 ndb-7.0.9, Nodegroup: 1)

[ndb_mgmd(MGM)] 4 node(s)
id=1    @192.168.0.10  (mysql-5.1.39 ndb-7.0.9)
id=2    @192.168.0.12  (mysql-5.1.39 ndb-7.0.9)
id=3    @192.168.0.11  (mysql-5.1.39 ndb-7.0.9)
id=4    @192.168.0.13  (mysql-5.1.39 ndb-7.0.9)

[mysqld(API)]   2 node(s)
id=9    @192.168.0.10  (mysql-5.1.39 ndb-7.0.9)
id=10   @192.168.0.12  (mysql-5.1.39 ndb-7.0.9)

Nun sollte jeweils ein ndbd einer Nodegroup (0 und 1) auf einem physikalschen Server liegen, d.h. fällt ein Server aus, so sind immer noch mind. ein ndbd aus der jeweiligen Nodegroup verfügbar und der Cluster läuft weiterhin problemfrei.

Natürlich habe ich vorrausgesetzt, dass die Installation soweit fertig gestellt ist, d.h. mysql user angelegt, Datenverzeichnis angelegt (/var/lib/mysql-cluster – kann auch anders sein..) wurde etc. und in der my.cnf die Einträge für ndb gemacht wurden:

[mysql_cluster]
ndb-connectstring=sql01

[ndb_mgmd]
config-file=/usr/local/mysql/config.ini

PHP IPv6 ip2long und long2ip Funktionen

php bietet aktuell ip2long() und long2ip() nur für IPv4 an, für IPv6 gibt es aktuell soweit ich weiss noch keine native Funktionen, deshalb hier meine zwei Funktionen um ip2long und long2ip auch für IPv6 zu verwenden – diese Funktionen benötigen die php gmp-lib, unter Debian: apt-get install php5-gmp:

$ipv6 = “2001:4860:a005::68”;
function ip2long6($ipv6) {
$ip_n = inet_pton($ipv6);
$bits = 15; // 16 x 8 bit = 128bit
while ($bits >= 0) {
$bin = sprintf(“%08b”,(ord($ip_n[$bits])));
$ipv6long = $bin.$ipv6long;
$bits–;
}
return gmp_strval(gmp_init($ipv6long,2),10);
}

function long2ip6($ipv6long) {

$bin = gmp_strval(gmp_init($ipv6long,10),2);
if (strlen($bin) < 128) {
$pad = 128 – strlen($bin);
for ($i = 1; $i <= $pad; $i++) {
$bin = “0”.$bin;
}
}
$bits = 0;
while ($bits <= 7) {
$bin_part = substr($bin,($bits*16),16);
$ipv6 .= dechex(bindec($bin_part)).”:”;
$bits++;
}
// compress

return inet_ntop(inet_pton(substr($ipv6,0,-1)));
}

print $ipv6long =  ip2long6($ipv6).”\n”;
print $ipv6 = long2ip6($ipv6long).”\n”;

Ergebnis:

42541956150894553250710573749450571880
2001:4860:a005::68

Typo3 4.2.8 und PHP5.3 Kompatibilitäts-Patch

Heute hatte ich mal etwas Zeit über, und konnte mich einem weiteren kleinen Problem welches aus dem Upgrade auf PHP5.3 resultiert widmen. Einige Funktionen sind bei PHP5.3 nicht mehr verfügbar, oder werden mit PHP6.0 nicht mehr unterstüzt. Auf der php Webseite gibt es eine Liste aller veralteten Funktionen.

In Typo3 4.3.0alpha3 ist davon zwar Einiges, wenn nicht sogar Alles behoben, im aktuellen Stable 4.2.8 gibt es jedoch eine Menge Probleme, wenn man auf PHP5.3 umstellt. Deshalb hier der von mir erstellte Patch für typo3 4.2.8 mit PHP5.3

typo3-4.2.8-php5.3-compat-patch

Falls jemand wider Erwarten einen Fehler findet und mir mitteilt, so werde ich den neuen Patch ebenfalls hier veröffentlichen.

Einen komplett gepatchten source gibt es hier zum download, da viele User nicht wissen wie man mit patch umgeht:

http://www.netz-guru.de/wp-content/uploads/2009/07/typo3_src-4.2.8-compat-patched-php5.3.tgz

XTC Xt-Commerce Fix für Multihomed Mailserver

Bei vielen Shop-Systemen wird XT-Commerce eingesetzt, da es vielseitig und flexibel ist um den meisten Anforderungen gerecht zu werden. Will man XTC jedoch in einer Cluster-Umgebung einsetzen, und hat einen Mailserver-Cluster zur Verfügung, gibt es ein Problem sobald XTC versucht, einen Connect zu einem Mailserver aufzubauen, der gerade nicht erreichbar ist. Obwohl weitere Server des Mailserver-Clusters verfügbar sind, gibt XTC nach einmaligem Versuch auf.

Hier ein kleiner Fix für XTC, damit zu einem Hostname alle verfügbaren IP-Adressen zum versenden von Mail durchprobiert werden:

In Zeile 106 in

/includes/classes/class.smtp.php

einfügen:

		// retry connections 
 		$hosts = gethostbynamel($host);
 		while ((empty($this->smtp_conn)) && (count($hosts) > 0)) {
        	$this->smtp_conn = fsockopen(array_pop($hosts), # server
                                      $port,    # the port to use
                                      $errno,   # error number if any
                                      $errstr,  # error message if any
                                      $tval);   # give up after ? secs
 		}

Damit versucht nun XTC mehrmals Mails zuzustellen, wenn der erstmalige Connect zu einem MTA fehlschlägt.

Verteiltes Dateisystem GlusterFS

Durch den Post vom vom 12.01.2009 / http://www.netz-guru.de/2009/01/12/die-ultimative-e-mail-losung-the-ultimate-e-mail-solution/ und die Kommentare darauf angeregt, habe ich versucht das gleiche Setup auch ohne dbmail zu versuchen. Sirko hatte in seinem Kommentar erwähnt, dass man mit einem verteilten Filesystem auch so einen Mailcluster betreiben kann. Bis zu diesem Zeitpunkt war mir eigentlich nur DRBD als einziges Filesystem bekannt, welches maximal 2 Nodes zu einer Art Netzwerk-RAID1 verbindet.

Gänzlich unbekannt war mir bis heute jedoch GlusterFS, welches ebenfalls ein verteiltes Filesystem über das fuse-Modul bereitstellt. Hier hat man jedoch keine Limitierung auf max. 2 Nodes. GlusterFS bietet Automatic File Replication auch über mehr als 2 Nodes. Weiterhin kann man mit Unify mehrere RAID1-Knoten zu einem einzigen FS zusammenfassen. GlusterFS bietet noch mehr Möglichkeiten, hier mal ein Überblick:

Mit einem Setup wie unter “Distributed Replicated Storage” beschrieben, lässt sich so ein gemeinsammes /var/spool für die Mailserver generieren. Die Konfiguration der Server kann man dann entweder in einer Datenbank oder LDAP ablegen, oder man verwendet die vom MTA vorgegebenen Konfig-Files, diese kann man auch auf einem verteiltem Filesystem speichern.

Den Source für GlusterFS kann man sich hier downloaden:

http://europe.gluster.org/glusterfs/2.0/LATEST/

Die Entwickler empfehlen ausserdem ein gepatchtes fuse-Kernel-Modul, welches GlusterFS erheblich beschleunigen soll:

http://europe.gluster.org/glusterfs/fuse/

Das Setup an sich ist relativ einfach. Unter Debian Etch fuse-Source entpacken, ./configure –enable-kernel-module –prefix=/usr  && make && make install && ldconfig

Dann glusterfs entpacken und ./configure –with-fuse=/usr/src/pfadzufuser &&  make && make install

Konfigurationsbeispiele gibt es unter www.gluster.org. Es sind auch kombinierte AFR,Stripe,Unify Filesysteme möglich, allerdings ist das Setup dann etwas komplizierter.

Weiterhin bietet GlusterFS neben normalem TCP/IP  auch direkte Verbindung über Infini-Band an. Auch redundante Verbindungen zur Storage werden unterstützt. Die Maximale Größe des Filesystems kann bis zu mehrere Petabytes betragen.

Möchte man viele kleine Dateien in glusterfs speichern, so kann glusterfs diese im DBD Berkeley DB Format speichern.

GlusterFS ist unter der GNU GPL v3 lizenziert.

Weitere Infos zu GlusterFS gibts auch bei der Wikipedia.

PHP Klasse für www.online-mahnantrag.de

Mahnbescheide automatisiert erstellen

Heute habe ich eine PHP-Klasse für www.online-mahnantrag.de geschrieben. Mit dieser Klasse ist es möglich, die Barcode PDF Anträge direkt aus einem PHP Skript heraus zu erstellen, und so zum Beispiel ein automatisiertes Mahnwesen zu erweitern, so dass nach Ablauf der letzten Mahnung automatisch das gerichtliche Mahnverfahren eröffnet werden kann.

Welche Verfahren werden angeboten?

Unter www.online-mahnantrag.de gibt es derzeit zwei Möglichkeiten, ein Mahnverfahren zu starten. Zum einen gibt es die schriftliche Version, d.h. man füllt online alle benötigten Felder aus, und erstellt abschließend einen Mahnbescheid mit maschinenlesbarem Barcode. Die zweite Alternative ist die Übermittlung der Daten mittels elektronischer Signatur. Die Klasse unterstüzt derzeit nur das Barcode Verfahren, da dies mir persönlich ausreicht und ich selbst nicht über eine digitale Signatur und entsprechendes Equipment verfüge. Wenn man die Funktion gen_pdf() der Klasse aufruft, übermittelt diese alle erforderlichen Daten an www.online-mahnantrag.de und liefert als Ergebnis das fertige Barcode-PDF zurück.

Einen neuen Mahnbescheid mit der Klasse erstellen

mit der Klasse lässt sich dann relativ einfach so ein Barcode-Antrag erstellen, hier mal ein Code-Beispiel:

Continue reading PHP Klasse für www.online-mahnantrag.de