Tuesday, July 28, 2015

php - Server being hit with quite a few requests per second



I run an image hosting website. My server can get anywhere between 8 requests a second to 20 requests a second during peak hours. I am currently running a server on the current hardware:



Processor AMD Hexa-Core Speed 6 Cores x 2.8 GHz (3.3 Turbo Core)
RAM 16 GB DDR3
ECC Hard-disk space 1,000 GB
(2 x 1,000 SATA) RAID Software RAID 1




Full specifications http://www.1and1.com/ServerPremiumXL?__lf=Static&linkOrigin=ServerPremium&linkId=ct.btn.package.xl I ordered the XL6 server.



I don't statically serve the images since they are stored elsewhere on the server. They are dynamically loaded on each call with readfile(). The server has been taking a beating recently and I want to know how I can optimize the server to be able to handle this kind of traffic with ease.



I have installed eaccelerator which seems to be helping, but not helping enough. I also had X-SendFile installed at one point, which seemed to help also, but I had to remove it temporarily because of issues with Apache, although I want to try to get it back on.



I am basically here asking for advice so I can vamp up my server to easily handle 50 req a second (unless this is just completely unreasonable). I myself am a developer and do not know too much about linux/apache, although i know the basics. I am also willing to learn. Thanks for any information.


Answer



There are a number of things you can do here. For one, you mention that you serve the images with readfile()? This can be a culprit here since it is PHP that is serving the images. That is not inherently much slower than serving them static and does come with multiple benefits (like dynamic image processing), but you can have a number of pitfalls as a result. From server standpoint it is always much faster to serve images as static.




First of all, is your script - the one that returns images - pushing out correct headers? That is, are you sending out Cache-control and Expires headers that tell user agents to cache images? Your traffic might come from the fact that your images are served either all the time or too frequently. Also send a Last-modified header.



You can also send a Not-modified header as a response if a user agent makes a request for a file and you know it has not been modified since the date that user agent provides.



If you already do set all proper headers and make sure that user-agents are not uselessly requesting the data that they already have, then your problem is in your web server. Have you done any performance testing to see if this affects only images or if it affects all requests in general?



I suggest trying to see how powerful your server is when serving regular (PHP) requests. See how long your pages themselves take time and compare it against requests for an image. I suggest a good tool such as Pylot for this (it is command-line, but really useful).



(Note that for comparison it is useful to compare a page with X size to an image of X size so that bandwidth is equal and you can just grade performance).




EDIT:



Cache headers that tell user agents that make the request to cache the file for as long as possible are as follows:



$lastModified=filemtime($myPicture); // File location of your image
$cacheDuration=31536000; // One year
// This tells user agent to keep the cache for one year
header('Cache-Control: public,max-age='.$cacheDuration);
header('Expires: '.gmdate('D, d M Y H:i:s',(time()+$cacheDuration)).' GMT');

// This tells the user agent the last modified time of your image
header('Last-Modified: '.gmdate('D, d M Y H:i:s',$lastModified).' GMT');


Serving Not-modified headers is a bit more complicated:



// Testing if the servers known last modified time is different from the last modified time of file on your server
// If those times are the same, then we will not return the image and just tell the user agent to use their cache
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$lastModified){
// Cache headers (Last modified is never sent with 304 header, since it is often ignored)

header('Cache-Control: public,max-age='.$cacheDuration);
header('Expires: '.gmdate('D, d M Y H:i:s',(time()+$cacheDuration)).' GMT');
// Returning 304 header
header('HTTP/1.1 304 Not Modified');
die();
}

No comments:

Post a Comment

linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...