On Wed, 12 May 1999, Artem Chuprina wrote:
> >>>>> On Wed, 12 May 1999 12:01:51 +0300 (IDT), "Stanislav Malyshev a.k.a
>Frodo" <frodo@sharat.co.il> said:
>
> VBW> изменения, после чего байт-код живет внутри той копии HTTPD, которая его
> VBW> выполнила, и
> VBW> при следующем запуске overhead отсутствует. Зато растет расход памяти.
>
> SMakaF> Кстати, вопрос - "той копии" это значит, что у каждого подпроцесса
>свой
> SMakaF> Registry?
>
> Не понял вопроса. Попробую ответить. Там для каждой копии httpd
> создается свой namespace и все данные погружаются в этот namespace, и
> живут в каждой копии httpd отдельно. Так что штатными средствами фигня с
Это не совсем так. Во-первых, каждая копия httpd это отдельный процесс,
который общих переменных с другими не имеет. Как только случился fork,
у каждого ребенка началась отдельная история. При этом, благодаря
стандартному системному механизму copy on write, страницы данных, которые
не изменяются (например, байткод уже загруженных перловых модулей) не
тиражируются, а живут в одном экземпляре.
Скрипты, которые подгрузились после fork, в процессе выполнения запроса,
естественно, в каждой копии httpd свои. А отдельный namespace создается
для каждого скрипта, запускаемого через Apache::Registry.
В связи с этим есть определенные синтаксические конструкции в perl,
которые работают в CGI, но не работают в registry. Например my-переменные
уровня файла. Нет в mod_perl уровня файла скрипт registry это с точки
зрения выполняющего его скрипта не файл, а процедура некоего пакета.
Поэтому использование my-переменных уровня файла приводит к очень
странному эффекту - процедуры в скрипте, их использующие, превращаются в
closure и при повторном вызове скрипта в той же копии httpd изменить из
скрипта переменные, которыми пользуются процедуры нельзя. Поэтому мои
скрипты на registry выглядят так
use strict;
use CGI;
&main;
sub main {
my $cgi=new CGI;
.....
}
> тем, что http - stateless, не обходится. Скрипт тоже компилируется в
> каждый httpd отдельно, и если он _подгружает_ какие-то модули, то и
> они. Ключевое слово "подгружает". Если грузить модуль при запуске
> apache, то копия будет одна. И данных тоже. Но как я подозреваю, могут
> появиться нежелательные побочные эффекты. Вообще использование mod_perl
> требует аккуратности, а такое - особенно.
С модулями как раз проще. Глобальные переменные модулей тоже подчиняются
принципу copy on write. Единственный недостаток модулей, это то что в
отличие от Registry скриптов, их изменение не обнаруживается
автоматически. Поэтому приходится слать апачу USR1, а в конфиге не
забывать писать PerlFreshRestart.
> VBW> Кроме того, если скрипт работает с базой данных, коннект к
> VBW> БД кешируется
> VBW> и экономится время на соединение при следующем запуске. Правда
> VBW> соединений к БД будет m*n где m число копий httpd а n - число разных
> VBW> коннектов к БД которые бывают
>
> Опять же, загрузкой модуля при старте apache это вроде бы можно
> вылечить. Но недаром Apache::DBI этого не делает...
Недаром. Я очень удивлюсь, если хотя бы один из существующих на рынке
sql-серверов не сойдет с ума, когда одним и тем же коннектом с ним
начнут пользоваться 20-30 независимых процессов.
> SMakaF> Т.е. создать, скажем, query, и воспользоваться его результатами на
> SMakaF> следующем запросе (постраничный просмотр) нельзя? А как можно?
Нужен внешний по отношению к апачу брокер запросов. Им может работать сам
SQL сервер, например при помощи опции LIMIT в операторе Select Postgres
6.5beta, может какой-нибудь transaction monitor типа zope, может FastCGI
или JServer. Я в свое время именно с этой целью писал свой собственный
брокер на Tcl.
> Как обычно с http. Поскольку он stateless, и никакой гарантии, что ты
> попадешь к тому же демону, нет, увы. Хотя в одном и том же переменные
> сохраняются, что позволяет, например, сделать авторизацию по принципу
> "авторизационный скрипт открывает коннект, а выдающий данные использует
> хендл этого коннекта". Насколько я понимаю, Витус Вагнер этим нагло
> пользуется еще и в варианте с SSI, поскольку в процессе выдачи одного
> документа все SSI-директивы выполняются в одном httpd.
И не только все SSI директивы, но и страницы, подгруженные через include
virtual. С точки зрения Apache это subrequest, но в пределах того же
процесса, а следовательно, глобальные переменные перловых модулей - общие.
А коннект у меня открывается при инициализации копии httpd в
PerlChildInitHandler, а используется на всех остальных стадиях запроса -
URI translation, FixUp, при генерации контента посредством perl-SSI.
В дальнейшем планируется все данные, требуемые для генерации страницы,
вытаскивать в память на стадии FixUp, чтобы любая perl-SSI процедура могла
располагать всем контекстом страницы, а не только той его частью, которая
сформировалась до ее вызова.
> --
> Artem Chuprina E-mail: ran@pirit.com
> Network Administrator FIDO: 2:5020/371.32
> PIRIT Corp. Phone: +7(095) 115-7101
> =============================================================================
> = Apache-Talk@lists.lexa.ru mailing list =
> Mail "unsubscribe apache-talk" to majordomo@lists.lexa.ru if you want to quit.
> = Archive avaliable at http://www.lexa.ru/apache-talk =
>
--------------------------------------------------
Victor Wagner vitus@ice.ru
Programmer Office:7-(095)-964-0380
Institute for Commerce Home: 7-(095)-135-46-61
Engineering http://www.ice.ru/~vitus
=============================================================================
= Apache-Talk@lists.lexa.ru mailing list =
Mail "unsubscribe apache-talk" to majordomo@lists.lexa.ru if you want to quit.
= Archive avaliable at http://www.lexa.ru/apache-talk =