Как Apache выполняет буферизацию STDOUT из сценария CGI?

В рамках разрабатываемой мной системы управления контентом у меня есть сценарий, который извлекает файлы изображений ( JPEG, GIF, PNG и т. Д.) В ответ на ПОЛУЧЕНИЕ браузером URL-адреса вида http: //myserver/getimage.cgi/virtual/path/to/image . На сервере файлы изображений хранятся вне DOCUMENT_ROOT как капли со случайным именем, а база данных отслеживает метаданные, в частности соответствие между виртуальным путем, именем файла большого двоичного объекта и типом MIME. Сценарий выглядит следующим образом: -

#!/usr/bin/perl

use CGI::Simple;
use File::Copy;
use MYSTUFF 'dblookup';

my $q = new CGI::Simple;
my ($mimetype, $filepath) = dblookup($q->path_info);

$| = 1; # enable autoflush so header is output before calling copy()
print $q->header(-type=>$mimetype);
copy($filepath, \*STDOUT);

Функция dblookup экспортируется MYSTUFF.pm и извлекает mimetype и путь к файлу для виртуального пути, переданного через стандартную переменную среды CGI $ PATH_INFO.

Меня беспокоит то, как вывод сценария CGI буферизуется сервером Apache, прежде чем он начнет отправлять его обратно в браузер. Если он буферизует весь вывод, то потенциально существует потребность в огромном объеме места для буферизации на сервере, потому что файлы изображений могут иметь размер от 10 до 100 МБ, а когда я начну поддерживать видеофайлы, они могут увеличиться до ГБ.

Достаточно ли разумен сервер Apache, чтобы буферизовать поток STDOUT из сценария CGI только до точки, где он получил все заголовки (т.е. первый "\ n \ n", который создается $ q-> header ( ) ), а затем начать копирование буфера данных из STDOUT в любой сокет, подключенный к HTTP-соединению, обратно в браузер? В документации для File :: Copy предполагается, что он будет использовать буфер размером 1K, поэтому, если Apache ведет себя так, как я обрисовал в общих чертах, тогда у меня действительно нет проблем, не так ли, поскольку IPC-сокеты / каналы будут обеспечивать управление потоком в моем CGI-скрипте, устраняя необходимость в дальнейшем пространстве спула за пределами буферов которые уже есть ??

-1
задан 8 January 2017 в 13:16
1 ответ

Я не знаю, как Apache с этим справляется. Однако, если вы спрашиваете об этом из соображений производительности, тогда мне интересно, почему вы используете CGI для начала ...

Несколько альтернатив, которые вы можете рассмотреть:

  • Поместите файлы в корень вашего документа используйте mod_negotiate , чтобы выбрать правильный тип MIME на основе конфигурации на стороне сервера и клиента.
  • Используйте mod_rewrite , чтобы сообщить Apache, что он должен прочитать определенный файл в ответ на конкретный запрос. Здесь можно изменить полученный результат на основе, например, файлов cookie или других параметров, установленных запросом; для получения более подробной информации см. документацию mod_rewrite
  • Если ваш сценарий делает больше, чем просто чтение файла с диска, и ни одна из двух вышеперечисленных опций не работает, посмотрите mojolicious для современного Perl веб-фреймворк, не требующий CGI.
0
ответ дан 5 December 2019 в 20:26

Теги

Похожие вопросы