1

On our dev server, I hit /bigreport.php, which connects to MySQL and runs a report. It takes a few minutes.

In another browser tab, I navigate to /smallreport.php, which connects to MySQL and runs a smaller report (but it still takes a minute). The second query to smallreport.php doesn't even start until bigreport.php finishes. This is the same dev server.

2nd window: the browser spinner spins, nothing appears on the page. In MySQL, SHOW PROCESSLIST only shows the first one (from bigreport.php). It would seem that PHP is not even running for the 2nd request.

While 1st request is running (bigreport.php), I can load up test.html and it loads instantly. BUT, if I open a sample PHP page instead, phpinfo.php, the connection hangs and won't even start until bigreport.php is finished. There is no database connection in this phpinfo.php page. Just to be sure, I wrote a simple test PHP page which just: sleep(10); with the same results.

I've checked MySQL SHOW VARIABLES LIKE 'max%connections' and it's all default/normal. There are no connection limits per user, and the default for all connections is 151. It does not seem to be a problem with MySQL.

I searched for PHP limiting connections, but it does not even seem to have a mechanism for this. PHP is run by the webserver, whether it be Apache or IIS or something else.

So this seems to be a problem (or configuration) in IIS 7.5. I've tried searching for "IIS7 multiple connections per browser/user" but all I find is help in configuring IIS for more than one website (or virtualhost) per IP.

I can hit bigreport.php from my browser, then from another machine pull up smallreport.php and it runs at the same time. It's a little bit slower, but the server is not stressed. I can watch the CPU activity and memory usage from Task Manager and not see anything happen while both these reports are running. But if I try and load both bigreport.php and smallreport.php at the same time from the same browser, only one will work at a time. Once that one finishes completely, then the next will start. The order doesn't matter.

I can load up multiple .html pages at the same time while bigreport.php is running. Those standard .html pages load nearly instantly. Maybe it's a problem / configuration issue with FastCGI?

I can load up bigreport.php from Firefox, then hit smallreport.php from Chrome and it does run at the same time! Same IP, same machine (mine). But not from another tab in Firefox.

In the appPool, I tried changing Maximum worker Processes from the default 1 to 2 with no effect.

Windows Server 2008 R2 Standard, IIS 7.5.7600.16385.

Any help would be appreciated.

UPDATE 2019-05-03:

I wrote a PHP script to loop through ten seconds, echoing the number once per second (with flush()) so I can see it count. I load this page in Firefox window #1, then window #2: window #2 waits for #1 to finish before it starts.

I open two windows in Chrome for same counting page: window #1 runs fine, window #2 waits for #1 to finish.

Then I reload them all: Firefox window #1 starts, but Firefox #2 hangs waiting for Firefox #1. Chrome window #1 starts, but Chrome #2 waits for Chrome #1 to finish.

It seems to be a connection limit (of 1) PER BROWSER.

wtftech
  • 31
  • 5
  • I guess a file/IO timeout. Try a simple phpinfo() page, if it work multiple time, I would doubth a bottleneck happen in your report. – yagmoth555 May 03 '19 at 02:28
  • 1
    @yagmoth555: you were on the right track; it was the session info file lock. – wtftech May 03 '19 at 21:40

1 Answers1

1

It has nothing to do with the way IIS is configured, nor FastCGI. It was an issue with the Windows filesystem and PHP session information being stored in files. In one browser, a PHP session file is opened and LOCKED until that request is completed. The 2nd request (from same browser) was simply waiting for the session info file lock to release. But another browser was a different session.

If sessions had not been configured to be started automatically, I might not have noticed this on a simple PHP page, like the counter script I wrote. But I would have noticed it running bigreport.php and then smallreport.php right after it, as those are dependent on sessions for logins 'n such.

The solution is easy: Call session_write_close() just before running the report query. In my case, no session information was required after that point. If it had been, I could have saved that session info into a custom array like: $mysession = $_SESSION; right before session_write_close(); and then referenced $mysession later.

wtftech
  • 31
  • 5