Note that there are some explanatory texts on larger screens.

plurals
  1. PODownload script using php-fpm/Nginx Causes High Load CPU
    primarykey
    data
    text
    <p>I have a good server for a file sharing use, and I am having trouble with the download script. I use PHP-FPM running on nginx.</p> <p>The server specs:</p> <pre><code>2x Intel Xeon E5 CPU: 92GB RAM 10x2TB (RAID6) And we use 1 SSD disk for CashCade </code></pre> <p>When I apllay this script on apache server, it works fine, but I want to run it on nginx server, because apache takes a lot of memory. (RAM) But when I run this script on nginx, something really wired is happening - it takes 30% from the CPU, only one download! Please note that after 3-4 minutes from the begining of the download, the CPU load is go back to normal (but the download continiues).</p> <p>This is the "TOP" in LINUX When im downloading... <img src="https://i.stack.imgur.com/G25Z9.jpg" alt="When I&#39;m Downloading"></p> <p>I don't know why, but the PHP-FPM script is taking a lot from the CPU. The script:</p> <pre><code>class ResumeDownload { private $file; private $name; private $boundary; private $delay = 0; private $size = 0; function __construct($file, $delay = 0) { if (! is_file($file)) { header("HTTP/1.1 400 Invalid Request"); die("&lt;h3&gt;File Not Found&lt;/h3&gt;"); } $this-&gt;size = filesize($file); $this-&gt;file = fopen($file, "r"); $this-&gt;boundary = md5($file); $this-&gt;delay = $delay; $this-&gt;name = basename($file); } public function process() { $ranges = NULL; $t = 0; if ($_SERVER['REQUEST_METHOD'] == 'GET' &amp;&amp; isset($_SERVER['HTTP_RANGE']) &amp;&amp; $range = stristr(trim($_SERVER['HTTP_RANGE']), 'bytes=')) { $range = substr($range, 6); $ranges = explode(',', $range); $t = count($ranges); } header("Accept-Ranges: bytes"); header("Content-Type: application/octet-stream"); header("Content-Transfer-Encoding: binary"); header(sprintf('Content-Disposition: attachment; filename="%s"', $this-&gt;name)); if ($t &gt; 0) { header("HTTP/1.1 206 Partial content"); $t === 1 ? $this-&gt;pushSingle($range) : $this-&gt;pushMulti($ranges); } else { header("Content-Length: " . $this-&gt;size); $this-&gt;readFile(); } flush(); } private function pushSingle($range) { $start = $end = 0; $this-&gt;getRange($range, $start, $end); header("Content-Length: " . ($end - $start + 1)); header(sprintf("Content-Range: bytes %d-%d/%d", $start, $end, $this-&gt;size)); fseek($this-&gt;file, $start); $this-&gt;readBuffer($end - $start + 1); $this-&gt;readFile(); } private function pushMulti($ranges) { $length = $start = $end = 0; $output = ""; $tl = "Content-type: application/octet-stream\r\n"; $formatRange = "Content-range: bytes %d-%d/%d\r\n\r\n"; foreach ( $ranges as $range ) { $this-&gt;getRange($range, $start, $end); $length += strlen("\r\n--$this-&gt;boundary\r\n"); $length += strlen($tl); $length += strlen(sprintf($formatRange, $start, $end, $this-&gt;size)); $length += $end - $start + 1; } $length += strlen("\r\n--$this-&gt;boundary--\r\n"); header("Content-Length: $length"); header("Content-Type: multipart/x-byteranges; boundary=$this-&gt;boundary"); foreach ( $ranges as $range ) { $this-&gt;getRange($range, $start, $end); echo "\r\n--$this-&gt;boundary\r\n"; echo $tl; echo sprintf($formatRange, $start, $end, $this-&gt;size); fseek($this-&gt;file, $start); $this-&gt;readBuffer($end - $start + 1); } echo "\r\n--$this-&gt;boundary--\r\n"; } private function getRange($range, &amp;$start, &amp;$end) { list($start, $end) = explode('-', $range); $fileSize = $this-&gt;size; if ($start == '') { $tmp = $end; $end = $fileSize - 1; $start = $fileSize - $tmp; if ($start &lt; 0) $start = 0; } else { if ($end == '' || $end &gt; $fileSize - 1) $end = $fileSize - 1; } if ($start &gt; $end) { header("Status: 416 Requested range not satisfiable"); header("Content-Range: */" . $fileSize); exit(); } return array( $start, $end ); } private function readFile() { while ( ! feof($this-&gt;file) ) { echo fgets($this-&gt;file); flush(); usleep($this-&gt;delay); } } private function readBuffer($bytes, $size = 1024) { $bytesLeft = $bytes; while ( $bytesLeft &gt; 0 &amp;&amp; ! feof($this-&gt;file) ) { $bytesLeft &gt; $size ? $bytesRead = $size : $bytesRead = $bytesLeft; $bytesLeft -= $bytesRead; echo fread($this-&gt;file, $bytesRead); flush(); usleep($this-&gt;delay); } } } </code></pre> <p>And the <code>download.php</code> (where I run the script)</p> <pre><code>// ... some code that get the file details from extrenal Database... $fileArr = $query-&gt;fetch_assoc(); $file = 'uploads/' . $download['fileid'] . '/' . $fileArr['name']; if(file_exists($file)) { $mysqli-&gt;close(); require 'class.download.php'; set_time_limit(0); $download = new ResumeDownload($file, 0); //delay about in microsecs $download-&gt;process(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload