Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Perl ISAPI подключение к БД


Автор: Itsys 20.8.2009, 17:06
Добрый день,

Может, кто сталкивался.
Разрабатываю интернет магазин платформа Win Server 2003+IIS+Active Perl.
Перед разработкой, прочитав документацию по Active Perl, решил запускать его в режиме расширения ISAPI.
Выдержка из документации:
Код

Why should I use Perl for ISAPI rather than Perl for Win32 (perl.exe)?
The short answer is: it's faster. The long answer gets kind of technical, but it goes like this:

The main advantage of PerlIS over perl.exe is that PerlIS runs as a DLL in the web server's process space. Because Win32 platforms set up a protected memory space for each process that is started, there's a lot of overhead in starting a new process or program. Passing scripts to an interpreter, such as perl.exe, requires starting a new process for every script, which gets expensive in terms of system resources.

DLLs, on the other hand, don't need their own process space; they use the space of the process that calls them. They don't require nearly as much overhead to start, and once loaded they stay loaded until the calling process ends. PerlIS therefore runs Perl scripts with a quicker turn-around time than perl.exe.

Extra care should be taken when you write PerlIS applications. It is difficult to crash the web server using CGI, but because the PerlIS DLL runs in the process space of the server, your web server is more susceptible to crashes and hangs caused by programming errors.


Повышение производительности было не главное при выборе. К сожалению, уже не помню где читал, но была такая вещь: что при работе именно в режиме ISAPI, модули, которые подключаются через use и блоки кода, которые находятся в блоках BEGIN или END кешируются, в дальнейшем при повторном выполнении какого-нибудь скрипта, соответственно не должны перекомпилироваться и повторно исполняться.

Из-за этого для коннекта к БД был создан отдельный модуль, подключаемый во все скрипты через use. По идее, изложенной выше, коннект к базе данных должен производиться только один раз при первом обращении к этому модулю, и в дальнейшем должно использоваться открытое соединение.

Но процедура подключения к БД выполняется при каждом обращении к скриптам сайта.

В чем может быть проблема?

Автор: ginnie 20.8.2009, 17:20
Itsys, Вы не указали, как производится подключение к БД. В функции import() или как?

Автор: Itsys 20.8.2009, 17:21
через DBI, перменная хендл экспортируется из модуля

Добавлено через 40 секунд
Вся суть в том, что сервер БД - MS SQL, находится на другом сервере...

Автор: ginnie 20.8.2009, 17:22
Покажите код.

P.S. сделайте отладочный вывод PID (идентификатора процесса)

Автор: Itsys 20.8.2009, 17:35
Модуль подключения:
Код

package Values;

use strict;
use vars qw ($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
use DBI;
use CGI;
require Exporter;

@EXPORT_OK = qw($SQLFastbook $SQLFastbookOld $siteadress $sitepath $pricelistpath $RuStrLow $RuStrCap 
                %PARTS %PARAMS %SQLPARAMS $cgi @BooksColums @BooksAutorType &DateSQL %Images
                &normalizeParams);
%EXPORT_TAGS = (ALL => [qw($SQLFastbook $SQLFastbookOld $siteadress $sitepath $pricelistpath $RuStrLow $RuStrCap 
                            %PARTS %PARAMS %SQLPARAMS $cgi @BooksColums @BooksAutorType &DateSQL %Images
                            &normalizeParams)],
                RUSTR => [qw($RuStrLow $RuStrCap)],
                SQL => [qw($SQLFastbook %SQLPARAMS $cgi @BooksColums @BooksAutorType &DateSQL $sitepath)],
                Img => [qw($sitepath %Images $cgi %PARAMS @BooksColums)]);
@ISA = qw(Exporter);

our $SQLFastbook  = DBI->connect("dbi:ODBC:driver={SQL Server};Server=***;database=***;uid=***;pwd=***;") or die "$DBI::errstr\n";
$SQLFastbook->{PrintError} = 0;
$SQLFastbook->{AutoCommit} = 1;
$SQLFastbook->{LongReadLen} = 2000000;


Использвование:
Код

use Values qw(:SQL);
        my $query = <<"(END)";
    DECLARE \@myid uniqueidentifier
    SET \@myid = NEWID()
    INSERT S (Id, Expire)
    VALUES (\@myid, $expire)
    SELECT * FROM S WHERE Id = \@myid
(END)
        my $sth = $SQLFastbook->prepare($query);
        $sth->execute || die "~~" . $sth->errstr . "<br>\n" . $query;


Автор: ginnie 20.8.2009, 17:41
Itsys, не уверен на счет use CGI; в модуле, т.к. его код, скорее всего до запроса выполняется.

Надо сделать в модуле отладочный вывод PID (идентификатора процесса).

Автор: Itsys 20.8.2009, 17:47
Просто я сделал модуль Values, в котором поключаю БД, задаю некоторые настройки, считываю и преобразую параметры, переданные в скрипт через CGI и т.д. Т.е. для того, чтобы все работало, как я хочу надо делать отдельный модуль, в котором будет только подключение к БД?


Цитата(ginnie @  20.8.2009,  17:41 Найти цитируемый пост)
Надо сделать в модуле отладочный вывод PID (идентификатора процесса).

Имеется в виду, удостовериться, что модуль запускается одним и тем же процессом... это 100%, при запуске сервера появляется 1 процесс, кроме него никаких большще дополнительныз процессов не возникает.

Автор: ginnie 20.8.2009, 17:54
Itsys, отладочный вывод - надежный механизм анализа происходящего. Если он покажет, что действительно модуль несколько раз компилируется, это один алгоритм, если компилируется только один раз - алгоритм дальнейших действий другой.

Автор: Itsys 20.8.2009, 18:13
Сори но я не понимаю, что ты предлагаешь сделать... 

то, что коннект идет несколько раз - отслеживал по трайсеру MS SQL...

что надо включить 

Автор: ginnie 20.8.2009, 18:19
Itsys, реконнекты могут быть не связаны с перезагрузкой модуля, возможно это DBI пересоединяется при каких-то условиях. Есть сложности с добавлением отладочного вывода? Как именно сделать отладочный вывод под ISAPI не знаю, может warn работает?

Автор: Itsys 20.8.2009, 18:20
что надо добавить в отладку? pid?

Автор: ginnie 20.8.2009, 18:24
Из лога нам надо понять, происходит ли многократный вызов DBI->connect из Values, и если происходит, надо убедиться, что это делается в рамках одного процесса.

Автор: Itsys 20.8.2009, 20:02
Вот лог:
Код

1250787634::4544::/card/13262/sid145ACA7C-FE4C-4F88-9096-CD75B017F8D6
1250787637::4544::/catalog/1390/1/10/sid145ACA7C-FE4C-4F88-9096-CD75B017F8D6
1250787642::4544::/card/13262/sid145ACA7C-FE4C-4F88-9096-CD75B017F8D6
1250787646::4544::/catalog/1390/1/10/sid145ACA7C-FE4C-4F88-9096-CD75B017F8D6
1250787649::4544::/basket/sid145ACA7C-FE4C-4F88-9096-CD75B017F8D6

формат time::$$::$ENV{QUERY_STRING}

Стоит сразу после коннекта в БД.

Автор: ginnie 20.8.2009, 21:57
Itsys, судя по логу ISAPI работает не так, как написано. Либо мы как-то неверно его воспринимаем. На твоем месте я бы заменил IIS на Apache+mod_perl и спокойно работал дальше (я так и сделал в свое время).

Автор: Itsys 20.8.2009, 22:24
На самом деле я бы не парился, если бы все работало нормально... Но сайт работает работает и работает довольно шустро, но потом бац и виснет... на полминутки потом опять отвисает и все ок. В моменты подвисания в логе ошибок всплывает ошибка о том, что время подключения к базе остекло.

Я уже всю голову себе сломал... что же это может быть

Автор: ginnie 21.8.2009, 09:10
Itsys, я не совсем понял, вот что, у Вас при каждом запросе происходит соединение с базой, правильно? При этом возникает момент "подвисания". На этом запросе происходит соединение с базой? Оно завершается ошибкой об истечении времени подключения к базе?

Автор: Itsys 21.8.2009, 22:16
ginnie, да.

1. При каждом запросе к любому скрипту сайта производится новый коннект к БД, это мы выяснили предыдущими опытами.
2. Иногда, по непонятным причинам (некоторый промежуток времени) все запросы к страницам подвисают, в результате выдается ошибка "время истекло". При этом в логах perl появляются записи о невозможности подключения к базе данных.
3. В эти промежутки времени не замечено каких-либо проблемм в аппаратной или системной области (но не могу это гарантировать, т.к детальное обследование не проводилось) т.к. ошибка вылезает безсистемно - может целый день все рботать нормально (во всяком случае не обнаружаемо мною либо другими сотрудниками офиса) и в то же время, потом моут быть с промежутком 10 минут, или 2 часа т.е. совсем не прогнозируемо.

Вот я и не могу никак понять в чем может быть проблема...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)