Die Funktion gethostbyaddr() ist sehr langsam!

webdoktor

Angesehenes Mitglied
Hallo zusammen

Ich habe eine eigene kleine Statistk individuell für mich programmiert.
Dort ermittle ich den Hostname des Users anhand der IP mit dem Befehl:

gethostbyaddr ()

Nun funktionierte die Statistik zwar einwandfrei, es ging aber immer 30
Sekunden bis die Seite geladen war bei etwa 300 Benutzer d.h. 300 IP
Adressen welche es abfragen musst.

Sobald ich den Befehl gethostbyaddr() entfernt habe geht es einwandfrei
innert Millisekunden.

Ist das ein generelles Problem dieser Funktion? Gibt es evt. eine alternative?

Freue mich über Eure Antworten.

PS:"Mir ist klar, dass es etwas Zeitbraucht anhand der IP den Hostname ausfindig
zu machen - aber gerade 30 Sekunden...?!"

Marco
 
Ich gehe davon aus, dass es um eine Statistik des Webserver-Logfiles o.ä. geht.

Weshalb fragst du die Hostnamen erst bei der Auswertung ab?
Ich würde vorschlagen bei jedem Besuchen der Webeite den Hostnamen gleich abzufragen und in einer Datenbank zu speichern.
Für die Statistik musst du dann nur noch die Datenbank abfragen.
 
gethostbyaddr() ist ja keine reine PHP-Funktion. Um eine IP-Adresse nachzuschlagen, muss gethostbyaddr() Nameserver abfragen, und das kann natürlich dauern. Falls Du die Adressen brauchst solltest Du es machen, wie gregi vorschlägt. Einfach zu geeigneter Zeit in eine Datenbank schreiben und dann dort auslesen. (Nur dran denken, dass sich die Einträge im Laufe der Zeit ändern)
 
Hey zusammen

genau, das ist ein super Tipp werde es wärend des Zugriffes
machen und nicht nachträglich. Wobei dann dauert es aber auch
einwenig länger und der User hat ganz kleine Verzögerungen.

Hmm?

Marco
 
QUOTE (webdoktor @ Do 25.10.2007, 19:57) Wobei dann dauert es aber auch
einwenig länger und der User hat ganz kleine Verzögerungen.

Mach es am Ende der HTML Ausgabe....

Dann ist die Seite komplett geladen und dem User kann es egal sein, wenn Dein Script noch 2 Sekunden braucht...

echo"</html>";
gethostbyaddr();
?>
 
Na ja, 30 Sekunden für 300 Adressen geht doch noch. Das sind 10 Adressen pro Sekunde.

Ich hatte auf einem lokalen Rechner schon das Problem, daß das Abfragen einer IP-Adresse bis zu 8 Sekunden brauchte. Schließlich stellte sich heraus, daß mehrere, von der FRITZ-Card erzeugte Netzwerkkarten der Reihe nach abgefragt wurden: Die erste fand nix, weil die IP-Adresse in keinem Nameserver drin war, also wurde die zweite abgefragt - dasselbe Spielchen.

Im Augenblick ist bei dir unsichtbar, ob 10 Adressen pro Sekunde bewältigt werden oder ob bsp. die Hälfte der Adressen schon gecacht / bekannt sind und der Rest umso länger braucht. Allerdings muß man normalerweise bei NS-Abfragen bis zu 2 Sekunden einplanen - nix für den Turbo.

In .NET wäre mein Vorschlag: Starte einen Hintergrundthread, der die IP-Adresse auflöst, dann kann die Seitenverarbeitung weiterlaufen. In PHP könnte vielleicht ein Script aufgerufen werden, ohne daß auf dessen Ende gewartet wird (weiß nicht, ob PHP das unterstützt).
 
gethostbyaddr() ist eine sehr, sehr langsame PHP-Funktion. Leider gibt es keine wirklich schnellere Alternative. Einzig die Funktion dns_get_record ist geringfügig schneller (rentiert sich eigentlich nur bei Massenabfragen, wie sie z.B. in Logparsern vorkommen).

CODE
<?php
/**
* This functions tries to resolve the IPv4 address for a hostname. It uses PHP's dns_get_record()
* because in my benchmarks this function was faster than gethostbyname. However, dns_get_record()
* does not work on Windows nor *BSD, so a fallback to gethostbyname() is implemented.
*
* @param  integer $domain: The domain.
* @return mixed: The IPv4 address or false if the query failed.
*/
$operating_system = strtolower(php_uname('s'));
if(strpos($operating_system, 'windows') !== false || strpos($operating_system, 'bsd') !== false) {
function resolve_ipv4($domain) {
 $bad_ip_addresses = array(
  '206.112.100.132', // http://slashdot.org/article.pl?sid=07/02/15/0432259
  '208.67.219.40', '208.67.219.41', '208.69.32.130' // http://www.opendns.com/faq/#do_you_wildcard_domains
 );
 $ip_address = gethostbyname($domain);
 if($ip_address != $domain && !in_array($ip_address, $bad_ip_addresses)) {
  return $ip_address;
 } else {
  return false;
 }
}
} else {
function resolve_ipv4($domain) {
 $bad_ip_addresses = array(
  '206.112.100.132', // http://slashdot.org/article.pl?sid=07/02/15/0432259
  '208.67.219.40', '208.67.219.41', '208.69.32.130' // http://www.opendns.com/faq/#do_you_wildcard_domains
 );
 $dns_data = @dns_get_record($domain, DNS_A);
 if(is_array($dns_data) && array_key_exists(0, $dns_data) && !in_array($dns_data[0]['ip'], $bad_ip_addresses)) {
  return $dns_data[0]['ip'];
 } else {
  return false;
 }
}
}
?>
 
Zurück
Oben