I'm on Windows 7 (using a VirtualBox VM) to do some development. I have PHP/5.5.13, Apache 2.4.9, Chrome 35.0.1916.153. I'm seeing some very inconsistent behavior when I run the following code :
index2.php
<?php
echo "Load time before 'file_get_contents': ".(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'])."<br/>\r\n";
echo file_get_contents('http://custom.local/index3.php');
echo "Load time after 'file_get_contents': ".(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'])."<br/>\r\n";
exit;
?>
index3.php
<?php
echo "Load time inside 'index3.php': ".(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'])."<br/>\r\n";
exit;
?>
Here is the results in Chrome (I get consistent response time between 8 and 28 seconds after curl_exec). Response time fluctuates a lot as well:
Load time before 'file_get_contents': 0.002000093460083
Load time inside 'index3.php': 0.0026569366455078
Load time after 'file_get_contents': 15.411452054977
It seems that after all it was an Apache issue.
Chrome's advanced options "Predict network actions to improve page load performance" would use more threads than provisioned by the default Apache config (Windows 2.4.9 Windows build).
The fix is simple in httpd.conf :
AcceptFilter http none
More details here:
http://www.apachelounge.com/viewtopic.php?p=28142#28142
Related
Context
I am working on a PhP Server-sent event application running on PhP 7.4 and Apache 2.4 on Ubuntu 20.10. The app does what it's supposed to, but, presumably, increased number of users (connections? SSE connections?) causes server to hang. I am expecting/would like to be able to handle a relatively large number of users (~1000), but my SSE events fire rarely (~3x in 15 min) and only look for and send a few string values found in a textual file on server.
Problem
My problem is that under some circumstances including increased number of clients (~70 to 100) Apache starts hanging. New HTTP requests are not reported in access log, no errors are reported in errors log, and any requests sent from browser seem to be loading forever with no server answer. Server load (processor, RAM) in that moment is minimal and I can access the server via SSH or FTP normally.
What I've tried
This happens with the default Apache configuration so following online advice I tried turning off mpm_prefork module and activating mpm_event and php7.4-fpm. Not much changed except the number of clients going up for a few dozens but that also might not be true since I cannot test that manually, just have the application live-tested when I have a chance.
I've tried turning off the SSE element in the application and in that case I have no Apache hanging issues (but I can't update clients' info for which I need SSE). That means SSE are probably causing an overload/Apache hang with regard to something, but I don't know what.
I assume Apache hanging has to do with number of open connections or processes. As much as I've learned, I can control that only in /etc/apache2/apache2.conf (I tried setting MaxKeepAliveRequests 0) and in /etc/php/7.4/fpm/pool.d/www.conf (I tried setting pm.max_children = 250, pm.start_servers = 10, pm.min_spare_servers = 5, pm.max_spare_servers = 15, pm.max_requests = 1000) but to no avail.
My questions
what can I do to increase Apache supported number of connections/SSE processes running?
what can I do to find out what causes Apache to hang or what typically causes that?
any other ideas/suggestions on how to solve Apache hanging?
My server-side code is
<?php
header('Content-Type: text/event-stream; charset=utf-8');
header("Cache-Control: no-store");
header('Connection: keep-alive');
header('Content-Encoding: none;');
set_time_limit(0);
while (true) {
if (configurationChanged()) {
echo "data: " . newConfiguration() . "\n\n";
ob_end_flush();
flush();
} else {
sleep(3);
}
if (connection_aborted()) break;
}
?>
My client code is
var source = new EventSource('myScript.php', {withCredentials: false});
source.onopen = function (event) {
console.log("Connection opened.");
};
source.onmessage = function(event) {
console.log(event.data);
// Do stuff with the obtained data here
}
Thanks for reading this.
The solution
My main problem was I didn't expect Apache to hang while there were resources available on my server. A lack of experience caused me to waste many hours before I realized I should look for causes in
Apache error log /var/log/apache2/error.log
FPM log /var/log/php7.4-fpm.log
I tried re-configuring mpm-event module according to link given in the comment. While it helped to increase the number of concurrent users for a few dozens, the same problem started occurring when number of users further increased.
What did help was setting pm = ondemand in /etc/php/7.4/fpm/pool.d/www.conf to avoid having to manually defining parameters. I'm not sure why is that not a default or not more widely recommended. My problem seemed to be solved.
However, a new issue started occurring. FPM log /var/log/php7.4-fpm.log started reporting 2 kinds of errors:
[mpm_event:error] ... AH03490: scoreboard is full, not at MaxRequestWorkers.Increase ServerLimit.
which would leave my web application hanging for users for a few minutes, then going back to normal without any intervention.
[proxy_fcgi:error] ... (70007)The timeout specified has expired: ... AH01075: Error dispatching request to : (polling), referer: ...
which would kill my web application for my users (so I added JavaScript to reload target php script to my users if the SSE connection ended)
For 1.
I tried to follow the error message instructions "Increase ServerLimit" and added "ServerLimit 250" to /etc/apache2/mods-enabled/mpm_event.conf. That didn't solve the problem.
I found this Apache bug report, but I was using a version where that should have been fixed. I then found this page suggesting I should change mpm-event to mpm-worker. Worked like a charm and solved problem 1.
For 2.
Problem 2 was related to my PhP SSE application, in specific to the SSE script timeout. What did NOT help was simply adding set_time_limit(0); to my PhP script. Timeout was reached by proxy_fcgi according to the error, so I had to edit /etc/apache2/apache2.conf and set
Timeout 3600
ProxyTimeout 3600
This increased any script max execution time to 1 hour (3600 seconds). This is not an ideal solution, but I haven't been able to find a solution to allow only particular script (in my case SSE PhP script running in an infinite loop) execution time.
Hope this helps someone!
I've set up an Apache Server as localhost in a openSUSE 13.1 64 bit system and I'm currently testing my PHP scripts.
In Konquerer 4.11.5 everything seems fine, but with Firefox 29.0.1 there is a strange phenomenon:
Every 10th time or so the connection fails. Firefox reports: "Connection determined".
The failed connection is listed neither in error_log nor in access_log.
The error must be quite "early". Because my PHP script output.php calls "itself" via
header("Location: output.php?changed_url");
almost immediately, but the Firefox error is BEFORE output.php is opened for the second time.
I have no idea what to do about this. It's a quite annoying issue.
All answers will be appreciated! Thanks in advance!
I guess you are missing
exit;
after the header() location change.
So you have an open script, firefox redirecting to the next (itself) and still having one open, ... I think firefox doesn't like this kind of loop ;)
Do you have any .htaccess file there? Have you tried using firefox from different OS or computer? I bet it's related to your installation of firefox :) (i ain't pro take it as guess)
I haven't had this problem on any other server, so I'm wondering if anyone else experienced this issue. The strange part is that the lock up happens at random - sessions will work fine for 10 minutes to an hour, then I'll make a request and I'll just see the browser waiting for reply. It never times out and I have to restart Apache2 to get sessions running.
My test.php script:
error_reporting(E_ALL);
session_start();
print_r($_SESSION);
echo 'got here';
When I get a lock up, commenting out the session_start(); shows 'got here'. So it's something to do with PHP sessions. It's setup to use files in /var/lib/php/session. Opening an incognito window doesn't help.
Potentially relevant details:
Web Server: Apache2 with Prefork
OS: CentOS 6.4 x64
HD: 5+ GB free
Memory: 10+ GB free
If you need any other info please ask!
in my system i install lamp,
i disable my varnish,
now i update my php code, and when i reflesh my browser, the php code like never change,
after i service apache2 restart, then the code are shown.
the scenario are
at first i submit
<?php
echo time();
?>
then i restart apache 2
screen will print timestamp
and then i modify code without restart apache2 services
<?php
echo time();
echo time();
?>
its still showing one timestamp,by right it should display 2 time stamp.
and everytime i reflesh the timestamp are changing ,so this is not a varnish issue.
but after i service apache2 restart, then 2 timestamp will show....
in my AWS ubuntu i do not hav opcache, and im using php 5.3.10
may i know how to disable this caching mechanism?
or anything i miss
some other case in mamp, it refer to something call opcache, but i did not use any or this.
FYI i install apc and memcache, but should not causing this problem, because i got another server also install the same thing.
Anyone please help , thanks
It's probably opcode cache.
<?php
ini_set('wincache.ocenabled', false); //<-- this desactivate it. (you may as well edit your php.ini file to edit this option.
echo time();
?>
If that doesn't work, a hack consists in calling your script passing a random parameter to it :
http://server.com/script.php?t=1
then update your code, and if you call :
http://server.com/script.php?t=2
The result should be updated.
I am getting a peculiar problem. Apache closes connection after 12 seconds or so. This leads to a "connection reset by peer" message on the browser.
I am on Linux Centos 5. Using apache2/php5.x/mod_gzip. (php with eAccelerator)
I tested some variations:
Usually, I will print all the HTML output as the last step. It always closes connection when the processing time goes above 12 seconds.
If the print happens quicker ( < 12 secs ), connection is not closed and I get the page on the browser.
If I print something regularly (every second or so), the connection is not closed even if the processing time goes above 12 secs.
What could be the possible issue here? Any suggestions on fixing this issue?
Edit - More details:
apache access-log shows status code is 200.
TimeOut directive is set. Timeout value is set at 60.
php.ini: max_execution_time is set at 30 secs.
client and server on different machines. It is a direct connection (no proxies in between Edit2: The ISP routes all requests through its proxy.).
Apache is standalone.
On the software side,
What status code is logged in access.log?
Do you (per-chance) have a Timeout directive in your httpd.conf (or inside any other files that may be included from httpd.conf)?
What is max_execution_time configured to be in php.ini?
Is your Apache being used as a reverse-proxy, or is it stand-alone?
On the network side,
Are the server and your client (browser PC) on the same machine, or is there a proxy, firewall or router in-between?