Hi all,
I've made a few SOAP services with Zend_Soap_Server by now. The most recent
one is very simple. However, the data returned is quite large.
I've done some tests: write out to a log a file with a timestamp at variuos
places in the execution flow. From that I know the DB (MySQL) is returning the
data quickly. The data is on a server on the WAN. However, I am developing the
SOAP service on a server on the LAN. In both cases, the data is returned
fairly quickly:
WAN server (data is local):
0.00317716598511 - fetching query
0.463740110397 - query fetched - returning data
LAN server (data is remote):
0.168507099152 - fetching query
1.93645906448 - query fetched - returning data
So I know the bottleneck is not that.
These numbers are the interesting ones.
WAN server:
0.0345900058746 - creating soap server
27.5670559406 - soap finished
LAN server:
0.0059220790863 - creating soap server
4.71519494057 - soap finished
In case you want to see where these numbers are coming from:
fwrite($log, (string)(microtime(true) - $starttime) . ' - creating soap
server' . PHP_EOL);
$soap = new Zend_Soap_Server('http://' . $_SERVER['SERVER_NAME'] . '/' .
basename(dirname(__FILE__)) . '/server.php?wsdl'); // this current wsdl file
here
$soap->setClass('HTCache');
$soap->handle();
fwrite($log, (string)(microtime(true) - $starttime) . ' - soap finished' .
PHP_EOL);
Wether or not it is because of data transfer, I can't tell. The response is
about 14MB. So it's possible that the network is to blame. However, over 20
seconds for 14MB is pretty slow for my 100MB fiber connection. Is this kind of
performance expected?
Another thing is that data being returned from the db is being sent over the
wire as is. So it's an array:
fwrite($this->log, (microtime(true) - $this->starttime) . ' - fetching
query' . PHP_EOL);
$result = $this->db->fetchAll($select);
fwrite($this->log, (microtime(true) - $this->starttime) . ' - query
fetched - returning data' . PHP_EOL);
return $result;
This makes a pretty big SOAP response because of the <item> structure of array
in SOAP XML:
<item>
<key xsi:type="xsd:string">date</key>
<value xsi:type="xsd:string">2011-04-01 00:00:00.</value>
</item>
Perhaps this is all quite normal, and 14MB of data is a lot. I admit, I was
surprised. However, there will be times when that amount of data is being
transfered.
Perhaps rather than returning an array, I can return something that would take
up less "space" as XML - if indeed the network is the bottleneck. Does anyone
know how I could go about avoiding the large structure of arrays in SOAP/XML?
Would making each row into an object waste even more resources and take longer
to execute?
One more questions: how can I test how long Zend_Soap_Server is taking create
the response? I think my testing on two separate servers shows it's the
network, but I can't be sure as one is Gentoo and the other is Debian.
Using tcpdump it looks like the response starts being returned in multiple
packets quite soon. Though all of them need to be put together on the client
side to have the complete response. Does that make sense? Is that how
Zend_Soap_Server does it's work? Wireshark runs out of memory (1.5GB free is
not enough?!?) parsing the dump file. So I can't really be sure what is
happening.
Any ideas? Sorry for the long email.
Thanks!
Simon