Я написал скрипт php, который отправляет большой файл (больше 1 ГБ) клиенту http.
Когда на стороне сервера пишут журнал, что «передача файла завершена» (lighttpd accesslog и мой собственный журнал php) после завершения отправки, на стороне клиента продолжается загрузка.
Я вызвал ob_flush () и flush () после последнего отправленного сегмента.
Но разница во времени между сервером и клиентом составляет несколько десятков секунд.
Информация о моей тестовой среде:
— сервер & клиент подключен с тем же локальным гигабитным коммутатором
— redhat 6.4, lighttpd 1.4.28, php 5.3.3
— Параметр sysctl на стороне сервера:
net.ipv4.tcp_wmem = 4096 16384 4194304
net.ipv4.tcp_rmem = 4096 16384 4194304
— Размер буфера php.ini:
memory_limit = 16M
Как я могу уменьшить промежуток времени между сервером и клиентом?
lighttpd читает выходные данные CGI так быстро, как может, чтобы CGI мог завершить обработку и освободить ресурсы. Многие экземпляры CGI-скриптов, работающие параллельно, часто используют гораздо больше памяти, чем один процесс lighttpd.
Поведение по умолчанию в lighttpd заключается в буферизации всего ответа перед отправкой клиенту, а для локального производителя и удаленного клиента локальное производство может быть намного быстрее, чем по сети. Для ЛВС может происходить обратное, особенно когда производитель (внутренний CGI) работает медленно.
В lighttpd 1.4.40 и выше вы можете установить server.stream-response-body = 1
в lighttpd.conf и lighttpd будут пытаться передать ответ клиенту, когда он получил его от CGI бэкэнда. lighttpd 1.4.40+ по-прежнему будет буферизоваться на диск, если серверная часть отправляет ответ быстрее, чем lighttpd может отправить его в сеть. Если вы хотите, чтобы lighttpd 1.4.40+ выполнял минимальную буферизацию (и потенциально блокировал бэкэнд-производителя, если клиент или сеть медленнее, чем производитель), вы можете установить server.stream-response-body = 2
Других решений пока нет …