![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| salexx |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 22.8.2007 Репутация: нет Всего: нет |
Здравствуйте!
Есть сервер, на нем стоит Apache/2.0.55, mod_perl 1.99. Есть библиотека условно LIB.pm. Так как работа над ней ведется, что называется, без отрыва от производства, то необходимо иметь стабильную и рабочую (тестовую) версии библиотеки. Я решил это следующим способом: положил библиотеку в 2 папки /lib1/LIB.pm и /lib2/LIB.pm. Так как mod_perl загружает скрипт и зацикливает его, то для использования отдельно двух версий библиотеки сделал 2 скрипта: script1.cgi: #!/usr/bin/perl use lib qw( /lib1/ ); use LIB; ... и script2.cgi: #!/usr/bin/perl use lib qw( /lib2/ ); use LIB; ... Я расчитывал на то что mod_perl загрузит и зациклит каждый скрипт с отдельной библиотекой. Но получается так, что в script1.cgi может оказаться загружена библиотека из /lib2/, хотя переменная @INC при этом не сожержит путь /lib2/. Может быть есть способ исправить такое поведение mod_perl или какие есть еще способы организации работы, чтобы была стабильная версия библиотек для работы текущих сервисов и экспериментальная, которая тестируется перед копированием на место основной? |
|||
|
||||
| Nab |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 582 Регистрация: 25.3.2006 Где: Kiev Репутация: 26 Всего: 37 |
Вы это утверждение проверяли? Или так, абы сказать... Я не проверял ибо не имею mod_perl, но даже если и так, то @INC содержит всего лишь пути поиска библиотек. А загружена она или нет перлом проверяеться в путях в последнюю очередь.. Сначала проверяеться %INC, содержащий список загруженных модулей. И ваш модуль будучи загруженным должен быть сначала выгружен. короче, это должно быть приблизительно вот так:
no use lib qw( /lib1/ ); делать можно по разному, можно вручную манипулировать порядком следования путей поиска в массиве @INC, но лучше как я указал. Добавлено через 4 минуты и 33 секунды Да я вот что еще хотел сказать, производить тестирование на продакшен сервере по минимуму не здоровое решение :( Сделайте себе для тестирования отдельное окружение.... -------------------- Чтобы правильно задать вопрос нужно знать больше половины ответа... Perl Community FREESCO in Ukraine |
||||
|
|||||
| salexx |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 22.8.2007 Репутация: нет Всего: нет |
Да, проверял. Я не ожидал такой реакции от системы, поэтому все перепроверил 10 раз. В script1.cgi выводил @INC - путь /lib2/ отсутствует, и выводил $INC{"LIB.pm"} = "/lib2/LIB.pm" Делал no use LIB; не помогало не пробывал только no use lib qw( /lib1/ ); Манипулировал @INC - бесполезно, так как с этим массивом все в порядке. Пришел к такому выводу что mod_perl не только зацикливает скрипт, но и не загружает в новый скрипт библиотеку по другому пути, если библиотека с таким именем уже была загружена в память.
Да, вы правы на 100%. |
|||
|
||||
| Nab |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 582 Регистрация: 25.3.2006 Где: Kiev Репутация: 26 Всего: 37 |
no use LIB: вы не делали, ибо такая конструкция ошибочна в принципе
так как я писал прямо в форум, то мне такая описка простительна, а вам в тестировании нет манипулирование @INC не бесполезно, потому как именно это мы делаем когда говорим... use lib qw(...) или no lib qw(...); это влияет на порядок поиска модулей. И вообще:
use выполняеться при компиляции, думаю для вашего случая наилучшим вариантом будет такая организация скрипта:
для обоих скриптов. Возможно я гдето ошибась, нужно проверять... Это сообщение отредактировал(а) Nab - 22.8.2007, 20:01 -------------------- Чтобы правильно задать вопрос нужно знать больше половины ответа... Perl Community FREESCO in Ukraine |
||||
|
|||||
| Ramirez |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 305 Регистрация: 18.1.2005 Где: Moscow, ExUSSR Репутация: 4 Всего: 5 |
мод перл, насколько мне известно, компилирует либу 1 раз (на каждый процесс апача). поэтому, не исключено, что когда вы 1 раз обратились из скрипта к LIB.pm он ее подгрузил, а потом из второго скрипта снова вызвали LIB.pm, но он не полез ее искать в путях, т.к. она уже в памяти есть (ищет-то оне ее по имени, а не пути). Все это происходит в рамках одного дочернего процесса апача, который обслуживает данное подключение.
Я бы проверил это так: 1.запускаем апач, обращаемся к скрипту любому, смотрим откуда либа берется. 2.перезапускаем апач (или ждем пока чилд по таймауту не помрет, либо с другого компа заходим). повторяем с другим скриптом. 3.снова смотрим пути Есть подозрение, что все зависист к какому скрипту первому обратиться, та либа в памяти и останется. Это при условии что в директиве PerlRequire эта либа не фигурирует, иначе она вообще компилируется 1 раз при старте апача и общая на всех детей. еще можно в апаче добавить:
потом зайти http://<domain>/perl-status будет куча инфы. какие модули загружены, кем, откуда итд.... причем, если я не ошибаюсь, все это применительно к текущему контексту. PS: так и есть, проверил. Причем либа остается скомпиленной в том чилде, который обслуживал запрос к скрипу, вызывающему эту либу. Причем прикол в том, что когда этот чилд потом пойдет других клиентов обслуживать, эти либы в нем так висеть и останутся. это видно в том-же перл-статусе: он в шапке показывает pid чилда апача, который данный запрос обработал (перл-статус). а так ка они чередуются (они = чилды. если конечно KeepAlive не очень большой стоит, т.к. после запроса текущий чилд ждет KeepAlive-секунд повторного запроса от текущего клиента, и только потом уходит обрабатывать других клиентов), то пощелкав кнопкой F5 (но не чаще чем 1 раз в KeepAlive-секунд) можно дождаться когда тебя обработает именно тот чилд, из которого ты скрипт с либой вызывал. Так вот, в нем либы будут видны В твоем случае, я думаю, получается, что у каждого чилда апача (который хоть раз обслуживал обращение к скрипту 1 или 2) своя либа внутри загружена. Причем откуда эта либа загружена зависит от того к какому скрипту обратились первый раз (с момента рождения чилда). После этого либа всегда берется из памяти. Так этот чилд и остается жить с этой либой внутри, пока не обслужит MaxRequestsPerChild-запросов и не помрет. Или пока весь апач не перезагрузят. PPS: путей к модулям perl-статус не показывает, но различать либы с одинаковы ми именами можно по версиям. Добавь в каждую либу
извиняюсь за сумбурное изложение =) Это сообщение отредактировал(а) Ramirez - 23.8.2007, 12:36 |
||||
|
|||||
| salexx |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 22.8.2007 Репутация: нет Всего: нет |
Всем спасибо, я понял что побороть такое поведение не получится. Будем разделять рабочие и тестовые сервера.
|
|||
|
||||
| Ramirez |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 305 Регистрация: 18.1.2005 Где: Moscow, ExUSSR Репутация: 4 Всего: 5 |
почему невозможно, возможно:
http://perl.apache.org/docs/2.0/api/ModPer...unload_package_ производительность, конечно снизится (насколько, зависит от размеров модуля), если на каждом запросе выгружать и загружать заново бибилиотеку. Хотя, если в отладочных целях, и для одной конкретной библиотеки, то вполне можно. Это сообщение отредактировал(а) Ramirez - 23.8.2007, 13:10 |
|||
|
||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |