nginx / unit

NGINX Unit - universal web app server - a lightweight and versatile open source server that simplifies the application stack by natively executing application code across eight different programming language runtimes.
https://unit.nginx.org
Apache License 2.0
5.25k stars 322 forks source link

"Waiting for Server Response" time consistently different depending on POST DATA Length? #1334

Closed kapyaar closed 6 days ago

kapyaar commented 1 week ago

Testing a UNIT php server on windows docker, if a form with post data is above a specific number of characters, the server response shows a repeatable increase in "waiting for server response" section from few milliseconds to 50+ms. Significant for large number of connections.

Here is what I have.

  1. Dockerfile
FROM unit:1.32.1-php8.2

ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS="0" \
    PHP_OPCACHE_MAX_ACCELERATED_FILES="10000" \
    PHP_OPCACHE_MEMORY_CONSUMPTION="192" \
    PHP_OPCACHE_MAX_WASTED_PERCENTAGE="10"

RUN docker-php-ext-install opcache
COPY opcache.ini /usr/local/etc/php/conf.d/opcache.ini
EXPOSE 80
WORKDIR /var/www/html/
COPY config.json /docker-entrypoint.d/config.json
  1. config.json
{
  "listeners": {
    "*:80": {
      "pass": "applications/php"
    }
  },
  "applications": {
    "php": {
      "type": "php",
      "root": "/var/www/html/",
      "processes": 1,
      "index":"index.php"
    }
  }
}
  1. opcache.ini
    opcache.enable=1
    opcache.revalidate_freq=0
    opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS}
    opcache.max_accelerated_files=${PHP_OPCACHE_MAX_ACCELERATED_FILES}
    opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}
    opcache.max_wasted_percentage=${PHP_OPCACHE_MAX_WASTED_PERCENTAGE}
    opcache.interned_strings_buffer=16 
    opcache.fast_shutdown=1
  2. docker-compose file
services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    working_dir: /var/www/html/
    container_name: phpApp
    ports:
      - 80:80
    volumes:
      - .:/var/www/html/
  1. Test.php. This is mostly an html file. In this particular form, the cutoff is 247. ie, if you type anything 247 or less characters long, and submit, the page submits, and reloads in ~5 ish ms. You can do refresh (to repeat the submit), and the result is repeatable. See screenshots.

Now, add one more character, make it 248 characters, and submit. the submit and reload time jumps to 50+ms.

<?php 
http_response_code(200);
?>
<!DOCTYPE html>
<head></head>
<body>
<br/><br/>
<form id= "img_upload" action="#" method="post"  style="background-color:#ccc;padding:20px;"> 
    <textarea rows="6" cols="50" name="inputText" id="inputText"></textarea>                    
    <input type='submit' value=' Submit '/> 
</form>
<div id="charCount">Character count: 0</div>
<script>
  const textArea = document.getElementById('inputText');
  const charCountDiv = document.getElementById('charCount');
  textArea.addEventListener('input', function() {
    const text = textArea.value;
    const charCount = text.length;
    charCountDiv.textContent = `Character count: ${charCount}`;
  });
</script>
</body>
</html>

Screenshots. Brave Browser, Incognito mode [Version 1.67.116 Chromium: 126.0.6478.71 (Official Build) (64-bit)]

  1. Normal test.php load. ~6-10 ms image

  2. Ready to Submit Text (Length=247 characters) image

  3. Page reloads on Submit image

  4. Form ready with 248 characters image

  5. Page reloads on Submit image

NOTES:

  1. if the 247 cutoff (or even higher length) seems to work for you, please double the length, and submit, see if you can see the time difference. I have seen few different cutoffs, but once you find the cutoff, it is pretty consistent, even by one extra character. I wonder if the cutoff changes because of the overall length including headers/ cookies/ etc. Not sure.
  2. Looks like the same applies even for get request. (eg: localhost/test.php?get=~~ long string~~)

Hope you guys can replicate this. And hopefully get some suggestions to reduce the sudden jump in wait time.

ac000 commented 6 days ago

Hi,

Are you able to reproduce this on Firefox?

With Firefox I can POST >10KiB and it's usually in the 1-2ms range (wait time), with the odd 3-6ms outliers.

With chromium I'm seeing much longer times in general usually around 8ms upto to 26ms...

kapyaar commented 6 days ago

Interesting. And sorry, I should have thought of trying another browser before reporting. Yeah, firefox (127.0.1 (64-bit), and ) seems just fine. I went like 20kb or more, and it submits/ refreshes in ~6-8ms. Went back to Brave, and I can see it jump (from ~7ms to ~55ms) at 337 characters right now.

So, this is more of a Brave artefact then?

ac000 commented 6 days ago

It would seem so...

callahad commented 6 days ago

That's very, very strange though. I'd love to try to nail down where the bad interaction is.

Does it fail on a fresh Brave profile? Other Chromium-based browsers? What if the container is running on macOS or Linux? What if you request 127.0.0.1 instead of localhost? etc.

callahad commented 6 days ago

(If this always crops up for Chromium, and other php servers don't show the same issue, then something in our behavior is violating Chromium's expectations sufficiently that we should try to identify and fix it)

ac000 commented 6 days ago

I'm seeing basically the same thing with Firefox and Chromium against nginx + php-fpm.

Firefox's timing are nice and stable in the low single digit ms. Chromiums are all over the place spiking to over 25ms.

kapyaar commented 6 days ago

Testing on windows/ docker. Just did a quick test on Brave to 127.0.0.1, and the issue seems gone!!. 20kb payload submits refreshes in <10ms. Just to be sure, went back to localhost, and the longer wait-for-server-response delay shows up.

On virtualbox with Ubuntu 24.04, Ran same docker configuration, tested with both Chrome, Brave, Firefox. All three of them loads fast, no noticeable difference, like ~5ms for a 20kb payload.

callahad commented 6 days ago

Okay, so this sounds like something that's specific to Windows / Docker networking and not a defect with Unit.

Thank you so much for the issue report, and for digging into diagnosing it, @kapyaar.

dbit-xia commented 5 days ago

https://github.com/nginx/unit/issues/708 Looks similar to this issue

Interesting. And sorry, I should have thought of trying another browser before reporting. Yeah, firefox (127.0.1 (64-bit), and ) seems just fine. I went like 20kb or more, and it submits/ refreshes in ~6-8ms. Went back to Brave, and I can see it jump (from ~7ms to ~55ms) at 337 characters right now.

So, this is more of a Brave artefact then?