Archiv ‘Web’

Dienstag, 12. Juni 2007

PHP aussagekräftiger benchmarken

In einer vor einigen Jahren programmierten Web-Applikation (ANIBILL; Übernachtungsstatistik und Rechnungsstellung für einen Tierstall) gab es vor einigen Wochen gewisse Performance-Engpässe, die sich in einer äusserst schleppenden Antwortzeit äusserten. Nach einigen ersten Untersuchungen isolierte ich MySQL (respektive unoptimierte Queries) als Ursache der Probleme.

Die richtige Vorgehensweise

Doch was nun? Klar konnte ich nun temporäre Änderungen an der Applikation auf einem Test-Server vornehmen und hoffen, dass ich den Fehler reproduzieren konnte. Oder aber: Ich änderte den Code dermassen, dass die Applikation künftig bei jedem Aufruf Zeitmessungen vornahm, mit denen ich ein aussagekräftigeres Bild erhielt. PHP-Programmierer werden es zu schätzen wissen, wenn sie Optimierungen auf Grund von 1’000 Messungen anstelle von 1-2 Probeläufen vornehmen können.

Die Lösung

Heraus kamen zwei Funktionen: anibill__get_db_data() und anibill__dump_microtime(). Durch die erste Funktion werden alle SQL-Queries „kanalisiert“, die mit SELECTs arbeiten. Zur Beruhigung der versierten Leser: Diese Funktion war seit Beginn der Applikation vorhanden, ich musste also nicht 1’000 Codezeilen nach mysql_query() durchstrählen …

Innerhalb dieser Funktion messe ich mittels microtime(), wie lange mysql_query() zum Ausführen meines SQL-Queries benötigt (und nur das, der Rest interessiert mich nicht). Bevor ich die aus der Datenbank gelesenen Daten zurückgebe, rufe ich die Benchmark-Funktion anibill__dump_microtime() auf, die mir einerseits die Laufzeit des Queries als auch gleich die aufrufende Funktion in eine Datenbank-Tabelle speichert. Bis zu diesem Zeitpunkt kannte ich die PHP-Funktion debug_backtrace() nicht – dabei ist sie äusserst mächtig. Ihre Ausgabe führt genau Buch, welche Funktionen seit dem Aufruf des Scripts ausgeführt wurden. Und nicht nur das – sogar die Zeilennummer des die Funktion enthaltenden PHP-Scripts ist angegeben. Ein Traum!

function anibill__get_db_data($str_sql_query,$bol_die_on_err = TRUE) {
 ...
 
 // Benchmark current MySQL query
 $arr_time[0] = microtime();
 $obj_db_data = mysql_query($str_sql_query,$res_db_conn);
 $arr_time[1] = microtime();
 
 ...
 
 // Store benchmark to database
 anibill__dump_microtime($arr_time,$str_sql_query);
 
 return $arr_db_data;
}

function anibill__dump_microtime($arr_time,$str_sql_query) {
 ...
 
 // Still using PHP4 and therefore wrestling with microtime()'s format
 $arr_start    = explode(" ", $arr_time[0]);
 $arr_end    = explode(" ", $arr_time[1]);

 $int_seconds            = $arr_end[1] - $arr_start[1];
 $flo_microseconds       = $arr_end[0] - $arr_start[0];

 $flo_runtime            = $int_seconds + $flo_microseconds;
 
 // Which function called anibill__get_db_data() in the first place?
 $arr_debug = debug_backtrace();
 if(isset($arr_debug[2]['function']))
   $str_function = $arr_debug[2]['function'];
 else
   $str_function = NULL;

 if(isset($arr_debug[1]['line']))
   $str_line = $arr_debug[1]['line'];
 else
   $str_line = NULL;
 
 ...
 
 return TRUE;
}

Ich möchte all die Christians, Andreas und Silvans da draussen um Gnade bitten – mein Coding-Stil wird wohl nicht der effektivste sein (zu viele Zeilen, zu viele Einzüge etc.), doch die Lesbarkeit liegt mir am Herzen. Und ja, von OOP keine Spur …

Selbstverständlich generiert das Benchmarken und Backtracen einen gewissen Overhead, doch aus meiner Sicht ist die vorgestellte Methode geeignet, die Performance kleinerer Web-Applikationen mit wenigen gleichzeitigen Zugriffen zu messen – ohne kostenpflichtige Tools einzukaufen und grosse Profiling-Sessions zu starten.

Zum Schluss

Erfinde ich das Rad neu? Gibt es elegantere Lösungen? Die Kommentarfunktion ist ab sofort geöffnet.

Tags:
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 3. Juni 2007

Der Algorithmus hinter Google

„When search first started, if you searched for something and you found it, it was a miracle. Now, if you don’t get exactly what you want in the first three results, something is wrong.“

Quelle: Google Keeps Tweaking Its Search Engine

Auch wenn Googles Qualität immer noch überzeugend ist – bis heute verstehe ich nicht, wieso die offizielle Herstellerseite eines Produktes nicht auf Rang 1 erscheint, wenn ich danach suche. Stattdessen ist die erste Seite mit Links auf unzählige Web-Shops gefüllt, die das Produkt in ihrem Sortiment führen.

Tags:
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Samstag, 2. Juni 2007

Drupal 5.1 zickt unter Umständen bei Clean URLs

Auf einem bei Hostpoint gehosteten Web-Server eines Kunden laufen …

  • Apache 1.3.37
  • PHP 5.1.6 (als CGI)
  • Drupal 5.1, 2007-01-29

Rufe ich die Test-Seite auf, die die korrekte Arbeitsweise von „Clean URLs“ überprüft, gibt es Probleme beim Laden der Stylesheets.

Nach etwa einer geschlagenen Stunde debugging weiss ich nun endlich, wieso:

Die Funktion base_path() in /includes/common.inc, die unter anderem auch von drupal_get_css() aufgerufen wird, liefert in der obigen Server-Konfiguration (PHP als CGI, verdammt seist du!) einen falschen Pfad zurück:

Aktuelle URL: http://www.server.tld/node/8
PHP-Snippet: print($GLOBALS['base_path']);
Ausgabe: /node/

Deshalb werden die @imports auf die Stylesheets mit einem falschen Pfad versehen, was wiederum die in der .htaccess angegeben mod_rewrite-Regeln (die Zeilen sind übrigens ein Höchstmass an Effizienz, da werden meine Augen jedesmal feucht) zum Fehlglauben verleitet, die angefragten Stylesheets existierten nicht:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

Stattdessen wird die Anfrage an das Script index.php weitergeleitet, das nun text/html ausliefert und die Browser ausser Tritt bringt. Seiten werden so pro eingebundenem Stylesheet um je 10KB schwerer für den Download.

Lösung

(Gemäss problem with clean url – duplicate path and other strange issues)

Man aktiviere in der Datei /sites/default/settings.php folgende Einstellung (ca. Zeile 115):

$base_url = 'http://www.server.tld'; //NO trailing slash!

Die nun mit SEF-URLs ausgelieferte Seite funktioniert tadellos und enthält die korrekten Verweise im Header:

<style type="text/css" media="all">@import "/modules/node/node.css";</style>
<style type="text/css" media="all">@import "/modules/system/admin.css";</style>
<style type="text/css" media="all">@import "/modules/system/defaults.css";</style>
<style type="text/css" media="all">@import "/modules/system/system.css";</style>
<style type="text/css" media="all">@import "/modules/user/user.css";</style>
<style type="text/css" media="all">@import "/themes/garland/style.css";</style>
<style type="text/css" media="all">@import "/themes/garland/ride.css";</style>
<style type="text/css" media="print">@import "/themes/garland/print.css";</style>

Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 30. Mai 2007

Hostpoint tut endlich etwas gegen das Spam-Problem!

Eine kurze Leitung kann man dem wohl grössten Schweizer Hoster Hostpoint nicht vorwerfen. Am 2. Januar 2006 schrieb ich zum leidigen Thema Spam:

Spam

Bei Genotec werkelt seit einiger Zeit ein sehr zuverlässiger Spam-Filter – ich werde kaum noch von unerwünschten Mails belästigt. Auch in dem IMAP-Ordner ‚Spam‘ findet sich kaum je noch eine Nachricht. Bravo.

Nicht so bei Hostpoint – verschiedene Kunden haben sich bei mir über das gehäufte Spam-Aufkommen der letzten Zeit beklagt. Dies betrifft insbesondere Adressen, die bei Hostpoint als Forwards eingerichtet sind. Anscheinend werden eingehende Nachrichten einfach durchgeleitet, ohne irgendwelche Spam-Tests durchzuführen.

[…]

Mein Vorschlag an Hostpoint, mittels Grey- und Blacklisting zu arbeiten und auch Forwards auf Spam-Verdacht zu überprüfen wurde aber abgelehnt:

Greylisting sehen wir nicht als Option, weil dadurch nur sich falsch
benehmende Spam-Mailer blockiert werden. Gegen einen Spammer der ein reguläres
Mailsystem (wie z.b. die gängigen Unix-Mailer Exim, Postfix oder Qmail)
benutzt oder missbraucht hilft es nicht im geringsten. Es ist nur
Pflästerlipolitik gegen einige momentane Spambots.

Quelle: Peter Keel an Mario Aeby vom 13. Dezember 2005, 16 Uhr 30.

Quelle: Hostpoint am Arsch

Verspätete Einsicht

Im heute verschickten Newsletter erreicht mich endlich die seit mehr als einem Jahr erwartete Botschaft, dass Hostpoint das Problem doch noch erkannt und etwas dagegen unternommen hat:

Haben Sie gewusst, dass wir vor einem Monat eine neue Technik zur Spamabwehr eingeführt haben? Erweiterte Tests prüfen die Nachricht vor der Annahme durch unsere Server. Damit haben wir das eingehende Spamvolumen um zwei Drittel reduziert.

Quelle: Hostpoint Newsletter – Mai 2007 vom 30. Mai 2007

Anscheinend hat also ein Umdenken eingesetzt. Ob Hostpoint nun wirklich Greylisting einsetzt (das bei Genotec immer noch erstaunlich gut funktioniert, wenn auch vermehrt „Aktien-Tipps“ und „Gartenfakeln“ eintreffen) oder die Nachricht empfängt und mit einem Wortfilter testet, ist mir hingegen nicht bekannt.

Tags: ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Samstag, 26. Mai 2007

The Next Big Thing

Of course good ideas alone are not enough. There are always plenty of good ideas. The real money is in taking existing ideas and twisting the idea just far enough to make it work in a fantastic new way. Think Google vs. AltaVista; Apple vs. all previously existing laptops and mp3 players; YouTube vs. all previously existing video sites, etc. In addition to ideas, you need creativity, resources, connections, and luck [..]

Quelle: The Final Days of Google

Sag ich doch schon lange: Im Grunde genommen ist es nicht derart schwer – man nehme ein Geschäftsmodell, dass in der realen Welt erfolgreich ist, und übertrage es auf das Internet. Selbstverständlich nicht 1:1, sondern durch geschickte Anpassungen dort, wo dem Benutzer ein Mehrwert geliefert wird. Fertig ist „The Next Big Thing“. Nach diesem Schritt braucht man noch ganz viel Venture-Kapital, ein Old-Boys-Network und etwas Publizität – fertig.

Tags:
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 23. Mai 2007

Leserzahlen von RSS-Artikeln messen (war: Claude syndiziert …)

Nachfolgend ein Mail, das ich soeben an einen Mitarbeiter von gfs.bern gesendet habe, der sich über meinen Artikel Claude syndiziert nicht standardkonform beschwert hat:

Lieber D.

1.     Die Art und Weise deines Blog-Beitrags ist beleidigend geschrieben

Es tut mir leid, wenn du meine Kritik persönlich aufgefasst hast. Das war nicht beabsichtigt – es ging mir um die Sache. Der Feed funktioniert nun, ich lese begierig Claudes Texte und lasse dementsprechend das „Motzen“ sein. Danke für deine Bemühungen!

2.     Nicht dem XML-Files wurde Javascript beigefügt, sondern dem index.php, so wie es Google empfielt (Hat aber trotzdem zu einem Fehler geführt)

Der Code kann selbstverständlich in ein PHP-Script eingefügt werden – sofern es schlussendlich (einigermassen gültigen!) HTML-Code an den Browser liefert (text/html)! Das von dir erwähnte PHP-Script (wp-rss2.php) hingegen produziert einen RSS-Feed (RSS ist ein XML-Format), weshalb JavaScript-Code – wenn überhaupt – innerhalb des Nachrichtentextes eines *jeden* Artikels eingefplanzt werden muss, um Leserzahlen zu messen. Selbst dann ist eine repräsentative Messung nicht möglich: Mein RSS-Reader NetNewsWire führt beispielsweise kein JavaScript aus.

Wenn euch wirklich wichtig ist, die Leserzahlen zu messen, empfehle ich den Einbau eines Blind-GIFs, das auf euren Server verweist. Mit Hilfe eines angehängten GET-Parameters kann der Artikel eindeutig unterschieden werden:

http://www.kommunikationsblog.ch/stats/blind.gif?id=1234

Mittels mod_rewrite würde ich so eintreffende Requests an ein PHP-Script weiterleiten, welches die entsprechenden Parameter (User-Agent, IP-Adresse, etc.) in eine Datenbank abspeichert. Bei der Realisation dieser Lösung aber bitte nicht vergessen, am Schluss dennoch ein standardkonformes GIF zurückzusenden.

Es gibt genug Jammertanten in dieser Welt.

In der Tat.

Tschüss
Mario

Labels: Blogosphäre, Web

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 13. Mai 2007

Crédit Suisses Direct Net mit Usability-Schwächen


Crédit Suisse Direct Net
(Close-Up)

Originally uploaded by emeidi.

Crédit Suisse hat vor Kurzem ihre Internetbanking-Software Directnet aufgefrischt. Sowohl die Strukturierung der Funktionen als auch die graphische Aufmachung erhielten eine Frischzellenkur.

Obwohl das Update aus meiner Sicht im Grossen und Ganzen gelungen ist (CSS, wow!), habe ich doch eine grosse Schwachstelle bezüglich der Usability feststellen müssen:

  • Zurücksetzen Vor langer, langer Zeit fand ein Entwickler der Seitenbeschreibungssprache HTML, dass es doch äusserst nett wäre, Formularen eine „Reset“-Möglichkeit mitzugeben. Daraus resultierte ebendiese Funktion. Schön und gut, doch ich mag mich nicht erinnern, in den letzten fünf Jahren diese Funktion a) jemals benutzt noch b) diese in letzter Zeit bei irgendwelchen Web-Formularen angetroffen zu haben. Obwohl Banken ein konservatives Image und eine gewisse Trägheit anhaftet – dieser Knopf wäre nun echt nicht nötig gewesen.
  • Vorwärts » • « Zurück Nicht wenige Benutzer müssen sich seit dem Update deutlich mehr in Acht nehmen, wenn Sie das Zahlungsformular benutzen. Entgegen jeden Regeln der Usability ist der „Weiter“-Knopf nicht unten am äussersten rechten Rand platziert. Dort steht unlogischerweise der (überflüssige!) Zurücksetzen-Knopf. Wie viele User wohl bereits auf diesen fiesen Trick der Entwickler hereingefallen sind? Ich empfehle die Lektüre der Introduction to Apple Human Interface Guidelines: Dialogs, wobei mir besonders der Abschnitt „Dismissing Dialogs“ von Wichtigkeit erscheint. Dort steht:

    Usually the rightmost button or the Cancel button is the default button. The default button should be the button that represents the action that the user is most likely to perform if that action isn’t potentially dangerous.

    Obwohl ich mit der Bank einer Meinung bin, dass Überweisungen „potentiell gefährlich“ sind (Unerwünschtes Resultat: Mein Vermögen verringert sich!), denke ich doch, dass gerade bei einem Überweisungsformular die Überweisung das schlussendliche Vorhaben des Benutzers ist. Wohl oder übel sollte der unheilbringende Knopf folglich ganz rechts stehen.

Ich werde Crédit Suisse gleich nach der Veröffentlichung dieses Artikels benachrichtigen. Mal schauen, wie lange eine solche minime Änderung durch die Mühlen der Bankenbürokratie aufgehalten werden wird …

Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 26. April 2007

Formular-Spam nimmt weiter zu

In den letzten Tagen musste ich leider feststellen, dass das Formular auf der Web-Site Tageskarte Gemeinde unzählige Male mit wirren Angaben abgesendet wurden.

Ziel des „Angriffs“ war es höchstwahrscheinlich, Links auf fremden Seiten zu platzieren, damit die Zielseiten bei Suchmaschinentreffern in den ersten Rängen angezeigt werden. Eine der beworbenen URLs war

brom . bilbidon . r u

(Leerzeichen zwecks Verstümmelung)

Glücklicherweise werden Neueintragungen nicht automatisch aufgeschaltet, sondern müssen von mir begutachtet und anschliessend aktiviert werden.

Für jeden Eintrag erhalte ich eine elektronische Benachrichtigung, die unter anderem die IP-Adresse des Formularkriegers enthält. In meinem Falle waren es unzählige Maschinen – einige aus Brasilien, einige aus Deutschland. Die Vermutung liegt nahe, dass es sich um gekaperte Windows-Kisten handelt, die nun als Spam-Bots im Netz unterwegs sind.

Altbekanntes Problem

Bereits im Januar 2007 erhielt ich die Meldung eines Kunden, dass das Gästebuch auf seiner Site regelmässig zugespammt werde. Ich löste das Problem, indem ich einen Turing-Test einbaute (inspiriert von einem Blog-Eintrag von Namics). Seither herrscht Ruhe.

Tags:
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 1. März 2007

Fleischmärkte Partyguide & Co.


FACTS 9/07: "Hemmungslos im Netz"
Originally uploaded by emeidi.

Im heute erschienen FACTS befasst sich die Journalistin Ruth Brüderlin mit den Schattenseiten von Party-Sites. Wer als sensibilisierter Leser dieses Blogs dabei aber primär an Datenlecks denkt, ist auf der falschen Fährte: Es geht viel eher um beleidigende und rassistische Kommentare, die die Leute in solchen Communities auf die digitale Pinwand pinnen. Und um Minderjährige, die sich in anzüglichen Posen zur Schau stellen.

Heisser Sommer

Und ja, liebe Argonauten, das musste ja so kommen: Natürlich habe ich eure Hommage an meinereiner sofort bemerkt. Merci! Schön, dass Sicherheit nun auch für euch kein Fremdwort mehr zu sein scheint … Leider gibt es noch ein ungestopftes Datenleck, doch dazu in Bälde mehr …

Tags:
Labels: Gesellschaft, Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 22. Februar 2007

User Agent ‚Feedfetcher‘ nun mit Abonnenten-Zahl

Google just began reporting its readership numbers last week (previously, all a publisher like me knew was that Google was downloading my feed, with no indication of how many people were actually subscribed via Google). […]

Quelle: The RSS reader is dead

Und siehe da:

Feedfetcher-Google; (+http://www.google.com/feedfetcher.html; 14 subscribers; feed-id=4188551576149804949

14 Nasen haben meine atom.xml in ihrem Google Feed-Reader abonniert … Boah! *zwinker*

Labels: Web

Keine Kommentare | neuen Kommentar verfassen