5 Stimmen

Beschleunigung einer seifenbasierten Website

Wir sind derzeit in tun einige Performance-Optimierung auf einer Website, die stark auf einem Soap-Webservice angewiesen ist. Aber ... unsere Server stehen in Belgien und der Webservice, mit dem wir uns verbinden, steht in San Francisco, also ist die Verbindung gelinde gesagt sehr weit.

Unsere Website ist PHP-basiert und verwendet die in PHP integrierte SoapClient-Klasse. Im Durchschnitt dauert ein Aufruf des Webservice 0,7 Sekunden, und wir haben etwa 3-5 Anfragen pro Seite. Alle möglichen Anfrage-/Antwort-Zwischenspeicher sind bereits implementiert, so dass wir jetzt nach anderen Möglichkeiten zur Verbesserung der Verbindungsgeschwindigkeit suchen.

Dies ist der Code, der den SoapClient instanziiert. Was ich jetzt suche, sind andere Wege/Methoden, um die Geschwindigkeit bei einzelnen Anfragen zu verbessern. Hat jemand Ideen oder Vorschläge?

private function _createClient()
{
    try {

        $wsdl = sprintf($this->config->wsUrl.'?wsdl', $this->wsdl);
        $client = new SoapClient($wsdl, array(
            'soap_version'       => SOAP_1_1,
            'encoding'           => 'utf-8',
            'connection_timeout' => 5,
            'cache_wsdl'         => 1,
            'trace'              => 1,
            'features'           => SOAP_SINGLE_ELEMENT_ARRAYS
        ));

        $header_tags = array('username' => new SOAPVar($this->config->wsUsername, XSD_STRING, null, null, null, $this->ns),
                             'password' => new SOAPVar(md5($this->config->wsPassword), XSD_STRING, null, null, null, $this->ns));
        $header_body = new SOAPVar($header_tags, SOAP_ENC_OBJECT);
        $header = new SOAPHeader($this->ns, 'AuthHeaderElement', $header_body);

        $client->__setSoapHeaders($header);

    } catch (SoapFault $e){
        controller('Error')->error($id.': Webservice connection error '.$e->getCode());
        exit;
    }

    $this->client = $client;
    return $this->client;
}

5voto

Arkh Punkte 8340

Das eigentliche Problem ist also die Anzahl der Anträge, die Sie stellen müssen. Was ist mit der Erstellung gruppierter Dienste?

  • Wenn Sie für die Webservices zuständig sind, können Sie spezialisierte Webservices erstellen, die mehrere Vorgänge gleichzeitig ausführen, so dass Ihre Hauptanwendung nur eine Anfrage pro Seite stellen kann.
  • Wenn nicht, können Sie Ihren App-Server in die Nähe von SF verlagern.
  • Wenn eine Verlagerung des gesamten Servers nicht möglich ist und Sie keine neuen spezialisierten Webservices erstellen können, können Sie eine Bridge in der Nähe des Webservices-Servers einrichten. Diese Brücke würde die spezialisierten Webservices bereitstellen und für den Aufruf der atomaren Webservices zuständig sein. Anstelle von 0,7s * 5 hätten Sie dann zum Beispiel 0,7s + 5 * 0,1.

3voto

Brant Messenger Punkte 1421

PHP.INI

output_buffering = On
output_handler = ob_gzhandler
zlib.output_compression = Off

3voto

Adam Hopkinson Punkte 27521

Sind Sie sich sicher, dass es die Netzwerklatenz ist, die jede Anfrage verlangsamt? 0,7s scheint eine lange Zeit zu sein, wie Benoit sagt. Ich würde versuchen, einige Benchmarking zu tun - Sie können dies mit curl tun, obwohl ich nicht sicher bin, wie dies mit Ihrem Soap-Client funktionieren würde.

Etwa so:

$ch = curl_init('http://path/to/sanfrancisco/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
$info = curl_getinfo($ch);

$info gibt ein Array mit Elementen für total_time , namelookup_time , connect_time , pretransfer_time , starttransfer_time y redirect_time . Anhand dieser Daten sollten Sie herausfinden können, ob es der DNS-Server, die Anfrage, der eigentliche Soap-Server oder die Antwort ist, die die Zeit in Anspruch nimmt.

Eine offensichtliche Sache, die mir gerade in den Sinn gekommen ist, ist, ob Sie den SOAP-Server über eine Domäne oder eine IP-Adresse anfordern. Wenn Sie eine Domäne verwenden, könnte Ihr DNS die Dinge erheblich verlangsamen (obwohl es in mehreren Stufen zwischengespeichert wird). Überprüfen Sie Ihre lokale DNS-Zeit (in Ihrem Soap-Client oder in der php.ini - bin mir nicht sicher) und die TTL Ihrer Domain (in Ihrer DNS-Zone). Richten Sie eine statische IP für Ihren SanFran-Server ein und referenzieren Sie ihn auf diese Weise, falls noch nicht geschehen.

2voto

powtac Punkte 39079

Optimieren Sie die HTTP-Antwort des Servers (nicht des Clients!) durch Caching und HTTP-Komprimierung. Sehen Sie sich die Tipps bei yahoo an http://developer.yahoo.com/performance/rules.html

1voto

Benoit Punkte 3504

1 Sie können sicherstellen, dass Ihr Soap-Server gzip-Kompression für http-Inhalte verwendet, ebenso wie Ihre Website-Ausgabe. Ein 0,7s Roundup zu SF scheint ein bisschen lang, es ist entweder Webservice ist lange zu beantworten, entweder gibt es eine wichtige natwork Latenz. Wenn Sie können, versuchen Sie es mit anderen Hosting-Unternehmen für Ihren belgischen Server, in Frankreich haben einige eine viel bessere Konnektivität zu den USA als andere. Ich habe die Erfahrung gemacht, dass sich die Netzwerklatenz zwischen Paris und New York fast verdoppelt hat, und mein Kunde, der viele Besucher aus den USA hat, war sehr unzufrieden damit. Die Lösung, den Webserver nach SF zu verlagern, kann eine Option sein, Sie werden eine viel bessere Konnektivität zwischen den Servern erhalten, aber seien Sie vorsichtig mit der Latenz, wenn Ihre Besucher hauptsächlich in Europa sind.

2 Sie können einen Opcode-Cache-Mechanismus verwenden, z. B. xcache oder APC. Dies wird die Latenzzeit der Soap nicht verändern, aber die Ausführungszeit von PHP verbessern.

3 Je nachdem, ob sich Seifenanfragen wiederholen und wie lange eine Inhaltsaktualisierung dauern könnte, können Sie eine echte Verbesserung erzielen, indem Sie die Seifenergebnisse zwischenspeichern. Ich schlage vor, dass Sie ein In-Memory-Caching-System verwenden (wie xcache /memcached oder andere), weil sie viel schneller sind als Datei- oder DB-Cache-Systeme.

Von Ihrer Klasse ist die createclient-Methode nicht die am besten angepasste Beispielfunktionalität, die zwischengespeichert werden sollte, aber für jede Leseoperation ist es einfach der beste Weg, um :

private function _createClient()
{
  $xcache_key = 'clientcache'
  if (!xcache_isset($key)) {
      $ttl = 3600; //one hour cache lifetime
      $client = $this->_getClient(); ///private method embedding your soap request          
      xcache_set($xcache_key, $client, $ttl);
      return $client;
   }
   //return result form mem cache
   return xcache_get($xcache_key);
}

Das Beispiel bezieht sich auf die xcache-Erweiterung, aber Sie können andere Systeme auf ähnliche Weise verwenden

4 Um noch weiter zu gehen, können Sie einen ähnlichen Mechanismus verwenden, um Ihre php-Verarbeitungsergebnisse zu cachen (z.B. Template-Rendering-Ausgabe und andere ressourcenverbrauchende Operationen). Der Schlüssel zum Erfolg mit dieser Technik ist es, genau zu wissen, welcher Teil gecached wird und wie lange er ohne Aktualisierung bleibt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X