FastNetMon

Thursday 17 January 2008

Решение проблемы с Apache2::ModSSL OpenSuse 10.3

При установке данного модуля высыпается несколько проблем -- первая из них, идёт много ругани на отсутствие mod_perl.h, но если путь с этим файликом жёстко прописать в Makefile.PL (который был предварительно сгенерирован посредством perl Makefile.PL, все файлы лежат по пути ~/.cpan/build/Apache2-ModSSL-0.03-некоторые_символы):
INC = -I/usr/include/apache2 -I/usr/include/apache2/modules/perl


То высыпется ещё целая прорва ошибок сборки, которая решается прописыванием путей к заголовочным файлам библиотеки apr:
INC = -I/usr/include/apache2 -I/usr/include/apache2/modules/perl -I/usr/include/apr-1


Ну и конечно же, devel версии пакетов Apache2 и mod_perl должны стоят в системе :)

Wednesday 16 January 2008

Немного о CPAN

Как удалить модуль с хранилища модулей (локального, конечно же) CPAN?

В общем случае никак (?), но бывают исключения. В конфигурационном файле CPAN (/usr/lib/perl5/5.8.8/CPAN/Config.pm) есть переменная ('build_dir'), отвечающая за расположение папки для временного хранения модулей перед установкой. Как можно понять, в этой папке хранятся инсталяцонные файлы модулей, которые представляют из себя стандартный комплект -- Makefile.PL / Build.pl и обычно уже созданный Makefile (т.к. данные модули уже были установлены Вами), который и устанавливает модуль в хранилище. А у Данного Make файла присутствует цель uninstall, т.е. можно выполнить make uninstall и либо удалить модуль сразу, либо получить рекомендации для удаления.

Но, к несчастью, данный метод не универсальный, но почти во всех случаях, когда мне было необходимо по тем или иным причинам удалить модуль, он срабатывал :)


Конфигурирование CPAN.

CPAN при запуске очень любит доставать вопросами о конфигурации. Чтобы отучить его заниматься сим противным занятием давайте напрямую отредактируем конфиг файл /usr/lib/perl5/5.8.8/CPAN/Config.pm
(его расположение меняется от дистрибутива к дистрибутиву, так что если что проявите смекалку и отыщите его). Ниже привожу свой конфиг файл.


# This is CPAN.pm's systemwide configuration file. This file provides
# defaults for users, and the values can be changed in a per-user
# configuration file. The user-config file is being looked for as
# ~/.cpan/CPAN/MyConfig.pm.

$CPAN::Config = {
'build_cache' => q[100],
'build_dir' => q[/home/nrg/.cpan/build],
'cache_metadata' => q[1],
'cpan_home' => q[/home/nrg/.cpan],
'cpan_version_check' => q[1],
'dontload_hash' => { },
'ftp' => q[/usr/bin/ftp],
'ftp_proxy' => q[],
'getcwd' => q[cwd],
'gpg' => q[/usr/bin/gpg],
'gzip' => q[/bin/gzip],
'histfile' => q[/home/nrg/.cpan/histfile],
'histsize' => q[100],
'http_proxy' => q[],
'inactivity_timeout' => q[0],
'index_expire' => q[1],
'inhibit_startup_message' => q[0],
'keep_source_where' => q[/home/nrg/.cpan/sources],
'lynx' => q[],
'make' => q[/usr/bin/make],
'make_arg' => q[],
'make_install_arg' => q[],
'makepl_arg' => q[INSTALLDIRS=site],
'ncftp' => q[],
'ncftpget' => q[],
'no_proxy' => q[],
'pager' => q[/usr/bin/less],
'prerequisites_policy' => q[follow],
'scan_cache' => q[atstart],
'shell' => q[/bin/bash],
'tar' => q[/bin/tar],
'term_is_latin' => q[1],
'unzip' => q[/usr/bin/unzip],
'urllist' => [q[ftp://cpan.makeperl.org/pub/CPAN], q[ftp://cpan.nx1.ru/], q[ftp://cpan.rinet.ru/pub/mirror/CPAN/], q[ftp://ftp.aha.ru/CPAN/], q[ftp://ftp.chg.ru/pub/lang/perl/CPAN/], q[ftp://ftp.spbu.ru/CPAN/], q[http://ftp.silvernet.ru/CPAN/], q[http://mirror.rol.ru/CPAN/]],
'wget' => q[/usr/bin/wget],
};
1;
__END__


Вот примерно такой вид должен иметь наш конфиг файл, но в случае проблем при его использовании придётся переконфигурировать Цпан вручную, это делается довольно просто -- удаляем указанный конфиг файл Цпана и запускаем сам cpan :)

А вот для пользователей убунту данный конфиг стоит искать по адресу: /etc/perl/CPAN/Config.pm

Как бороться с ошибками вида: "Has already been unwrapped into directory /root/.cpan/build/ИМЯ_модуля-некая_уникальная_последовательность" ?

Такое бывает, когда сваливаются тесты модуля или Вы любите поэксперементировать с Цпаном. Это решается в лоб: rm -r /root/.cpan/build/ИМЯ_модуля-*

Monday 14 January 2008

Новое в Перл 5.12 и немного о my и local

В то время, как весь мир судачит о грядущем Перл6, разработчики 5го Перла прикручивают очень вкусные фишки к языку, вот ссылочка с примерным списком нововведений.

Вот уже третий день усиленно вычитываю статьи на opennet.ru, вот сегодня наткнулся на очень хорошее описание разницы (хотя не совсем разницы, скорее указываются тонкости применения каждого из них) между my и local в Перл5, а вот и ссылка.

Sunday 13 January 2008

MVC Catalyst + Apache2 mod_perl

Ах, кто к нам такой пришёл ?) А пациентом у нас сегодня будет Perl приложение (простите, но скриптом уже язык не поворачивается называть) на очень прогрессивном MVC фреймворке Catalyst... стоп, а что за Каталист-то? А вот, пожалуйста статья.

По ссылке довольно хорошее введение в предмет, так что не думаю, что возникнет много вопросов. В этой же статье описывается создание простейшего (но вот "простоту" своего нового Стартапа определяете сами :) приложения на данной платформе, у меня оно будет расположено по следующему пути: /home/nrg/dev/my_catalyst_app/lib, так что все последующие конфиги будут идти с учётом оного.

А вот по данной ссылке можно наблюдать описание процесса настройки mod_perl2 для исполнения Каталист приложений. Открываем конфиг файл /etc/apache2/conf.d/mod_perl.conf и внутри тегов <IfModule mod_perl.c> и </IfModule> после всех остальных записей добавляем следующее:

PerlSwitches -I/home/nrg/dev/my_catalyst_app/lib
PerlModule my_catalyst_app
<Location /cat>
SetHandler perl-script
PerlResponseHandler my_catalyst_app
</Location>

Строчка с PerlSwitches указывает веб серверу путь, по которому искать наш обработчик событий для mod_perl (им и будет наше приложение), директива "PerlModule my_catalyst_app" указывает о том, что компиляция нашего проекта будет проведена сразу после запуска Апача, а о назначении остальных строк, думаю, можно догадаться самим, там всё предельно просто - указываем тип обработчика и выбираем наше приложение обработчиком.

После данных манипуляция, перезапускаем Апача - service apache2 restart и смотрим tail -n20 /var/log/apache2/error_log, если там присутствует ошибка Can't locate Catalyst/Engine/Apache2/MP20.pm in @INC, то от имени суперпользователя root устанавливаем недостающий модуль: cpan Catalyst::Engine::Apache2::MP20

Ну вот, пожалуй, и всё, снова перезапускаем сервер и открываем страницу http://127.0.0.1/cat, где видим красивый лейбл Каталиста :)

Добавление от 24 июня.

Вот приобрел хостинг на Дебияне, нашел более удобный способ конфигурирования -- добавить все настройки в отдельный файл /etc/apache2/mods-available/perl.load (который создан ранее).

В итоге у меня получился вот такой небольшой конфиг для Каталиста на отдельном домене:

LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so

PerlSwitches -I/home/nrg/MyApp/lib

<VirtualHost 72.4.76.1:80>

ServerName www.goosync.ru
ServerAlias host.ru *.host.ru

<IfModule mod_perl.c>
PerlModule MyApp
SetHandler perl-script
PerlResponseHandler MyApp
</IfModule>

</VirtualHost>

Saturday 12 January 2008

Циклические ссылки и сборщик мусора в Perl (perl trash garbage)

Я, конечно, понимаю, что из-за одной ссылки делать целый пост аморально, но статья очень хорошая и для разработчика под mod_perl и FastCGI относится к разряду MUST READ, ссылка в студию: http://www.opennet.ru/base/dev/perl_destruction.txt.html

Apache2 MPM Worker + mod_perl2 на OpenSuse 10.3

В установке данной связки ничего сильно сложного нету, но тем не менее на некоторые моменты стоит обратить внимание. Для начала ставим пакеты apache2, apache2-worker, apache2-utils, apache2-mod_perl и apache2-example-pages через Yast2 или вручную, это уже зависит от Ваших предпочтений. В заголовке статьи я специально сделал акцент на то, что настройка именно для Опенсусе, т.к. некоторые моменты при конфигурировании могут отличаться от дистрибутива к дистрибутиву. Все рассуждения и выводы будут основаны на данной статье.

После того, как всё было успешно (а я ,надеюсь, это так и будет) установлено переходим к настройке. Для начала запустим Апач командой service apache2 start, после этого будет выведено: Starting httpd2 (worker) done, это означает, что запуск веб сервера Apache2 c MPM Worker выполнен успешно.

Далее нам необходимо просмотреть список модулей, которые загружаются сервером, для этого можно воспользоваться командой: apache2ctl -t -D DUMP_MODULES, как можно видеть, там нету perl_module (именно так зовётся модуль mod_perl), поэтому нам нужно сообщить серверу о том, что мы хотим использовать именно его. Список модулей, загружаемых Apache2, хранится в файле /etc/apache2/sysconfig.d/loadmodule.conf, но его особенность в том, что все изменения в нём живут до перезапуска сервера, т.к. в это время конфиг файл затирается и приводится в первоначальную форму. Как можно понять, добавлять в этот конфиг mod_perl2 бесполезно, но куда же его прописывать? Некоторое время поломав голову, я-таки понял, что где-то есть внешний конфиг файл, где и хранится список модулей, на основе которого и создаётся loadmodule.conf - это файл /etc/sysconfig/apache2. Открываем его на редактирование любимым редактором текстов, например vim, ищем строку APACHE_MODULES="а здесь список модулей" и добавляем в неё mod_perl, не забывая, что имена модулей отделяются друг от друга пробелами.

Далее снова ерезапускаем Apache2 и смотрим список модулей командой apache2ctl -t -D DUMP_MODULES, теперь же в этом списке должен появиться "perl_module (shared)". Ещё один способ убедиться в успешной загрузке mod_perl - это команда tail -n20 /var/log/apache2/error_log, далее ищете в лог файле строку наподобие вот этой:
[Sat Jan 12 11:51:58 2008] [notice] Apache/2.2.4 (Linux/SUSE) mod_ssl/2.2.4 OpenSSL/0.9.8e mod_perl/2.0.3 Perl/v5.8.8 configured -- resuming normal operations

Теперь попробуем запустить обычный perl cgi скрипт. Просмотрев конфиг файл /etc/apache2/default-server.conf, можно понять, что обычным местом для CGI приложений является папка /srv/www/cgi-bin (если её нету, то Вам потребуется её создать). В указанной папке создаём файл hello.pl следующего содержания:
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "Standard CGI!\n";

После этого нам нужно поставить права 755 для файла hello.pl, для этого можно использовать команду chmod a+rx hello.pl. Всё, можете пробовать открыть ссылку http://127.0.0.1/cgi-bin/hello.pl, если отобразится "Standard CGI!", то с настройкой обычного CGI мы закончили. Переходим непосредственно к настройке к mod_perl.

Создадим папку для наших mod_perl2 приложений - mkdir /srv/www/cgi-fast. Далее переименуем старый конфиг mod_perl2 mv /etc/apache2/conf.d/mod_perl.conf /etc/apache2/conf.d/conf_old, т.к. мы его будем заменять на новый, а старый лишь сохраняем на всякий случай, вдруг пригодится.

Создаём файл /etc/apache2/conf.d/mod_perl.conf следующего содержания:
Alias /cgi-fast/ /srv/www/cgi-fast/

<IfModule mod_perl.c>
PerlRequire "/etc/apache2/mod_perl-startup.pl"
<Location /cgi-fast/>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
# PerlResponseHandler ModPerl::PerlRun 
# выбор конкретного модуля определяется
# условиями решаемой задачи
# более подробно про модули на search.cpan.org
PerlOptions +ParseHeaders
Options +ExecCGI
Order allow,deny
Allow from all
</Location>
</IfModule>


Далее в папке /srv/www/cgi-fast создаём файл test.pl следующего содержания:
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "Standard CGI from mod_perl folder!\n";
print $ENV{MOD_PERL};


Выставляем права chmod a+rx test.pl, проверяем http://127.0.0.1/cgi-fast/test.pl, скрипт должен напечатать строки: Standard CGI from mod_perl folder! и mod_perl/2.0.3, что повествует о работоспособности mod_perl. Как можно понять, в этом случае мы произвели запуск обыкновенного Perl скрипта через mod_perl.

Создаём в папке /srv/www/perl-lib подпапку MyApache2 и во вновь созданной папке создаём файл Rocks.pm следующего содержания:
#file:MyApache2/Rocks.pm
#----------------------
package MyApache2::Rocks;

use strict;
use warnings;

use Apache2::RequestRec ();
use Apache2::RequestIO ();

use Apache2::Const -compile => qw(OK);

sub handler {
my $r = shift;

$r->content_type('text/plain');
print "mod_perl2 application rocks!!!\n";

return Apache2::Const::OK;
}
1;



Теперь добавляем в конфиг /etc/apache2/conf.d/mod_perl.conf следующий блок:
<Location /rocks>
SetHandler perl-script
PerlResponseHandler  MyApache2::Rocks
</Location>


Таким образом конфиг примет вид:
Alias /cgi-fast/ /srv/www/cgi-fast/

<IfModule mod_perl.c>
PerlRequire "/etc/apache2/mod_perl-startup.pl"
<Location /cgi-fast/>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
# PerlResponseHandler ModPerl::PerlRun
PerlOptions +ParseHeaders
Options +ExecCGI
Order allow,deny
Allow from all
</Location>
<Location /rocks>
SetHandler perl-script
PerlResponseHandler  MyApache2::Rocks
</Location>
</IfModule>


Теперь открываем http://127.0.0.1/rocks и, надеюсь, радуемся увиденному :)

Apache2 prefork vs worker

Довольно продолжительное время при установке веб сервера Apache я сомневался, ставить ли мне apache2-worker или apache2-prefork, вот и настал момент, когда стоит устранить все неясности в этом выборе и явно описать, что и когда лучше использовать.

Официальная документация сервера говорит о следующем:
Choosing an MPM

Apache 2.x supports pluggable concurrency models, called Multi-Processing Modules (MPMs). When building Apache, you must choose an MPM to use. There are platform-specific MPMs for some platforms: beos, mpm_netware, mpmt_os2, and mpm_winnt. For general Unix-type systems, there are several MPMs from which to choose. The choice of MPM can affect the speed and scalability of the httpd:

* The worker MPM uses multiple child processes with many threads each. Each thread handles one connection at a time. Worker generally is a good choice for high-traffic servers because it has a smaller memory footprint than the prefork MPM.
* The prefork MPM uses multiple child processes with one thread each. Each process handles one connection at a time. On many systems, prefork is comparable in speed to worker, but it uses more memory. Prefork's threadless design has advantages over worker in some situations: it can be used with non-thread-safe third-party modules, and it is easier to debug on platforms with poor thread debugging support.

For more information on these and other MPMs, please see the MPM documentation


Переводить всё не возьмусь, смысла в этом не вижу, но постараюсь описать в двух словах, чем занимаются каждый из указанных модулей.

В документации рассказывается, что у сервера Apache2 мультипоточность реализована посредством подключаемых модулей - MPM (по поводу перевода я сомневаюсь, но, на мой взгляд, лучше перевести как "модули мультипоточной обработки", хотя далее я буду использовать аббревиатуру в виду громоздкости данного названия), которые являются платформозависимыми. Существует две основных модели MPM модулей - это worker MPM и prefork MPM.

Worker работает следующим образом - при запуске создаётся несколько дочерних процессов, по несколько потоков в каждом (сколько именно подразумевается под "несколько" задаётся в конфиг файле Apache2). В качестве преимущества данного модуля указывается пониженное потребление памяти по сравнению с Prefork модулем. Также этот модуль рекомендуется для высоконагруженных веб серверов.

Prefork же создаёт некоторое количество дочерних процессов, но в отличие от Worker, в каждом из них ровно по одному потоку. Т.е. каждый процесс обрабатывает только одно соединение. По поводу скорости указывается, что скорость обоих модулей более-менее соизмерима, но Prefork потребляет больше памяти. Использование безпоточного модуля Prefork предпочтительно в случае использования модулей, который не обладают безопасной мультипоточностью. Также рекомендуется использовать Prefork на платформах, где отладка мультипоточных приложений не реализована на должном уровне (к слову говоря, отлаживать мультипоточные приложения даже на системах с хорошей поддержкой оного - занятие не из простых).


В заключение хотелось бы добавить, что однозначного выбора не существует, всё определятся решаемыми задачами, но следует помнить, что модель Prefork (она, кстати, была единственной моделью, которую поддерживали сервера на Apache 1.3) является заведомо более стабильной, т.к. сбой в одном процессе не затрагивает другие процессы, а в случае Worker сбой в одном потоке может вывести из строя ещё несколько соседних потоков, хотя Worker показывает более высокую скорость в определённом спектре задач (в частности высоконагруженные сервера).

А вот данные реального тестирования: http://www.camelrichard.org/apache-prefork-vs-worker
Стабильности серверов в обоих случаях была 100%, а вот Worker почти в 2 раза обогнал Prefork, но тем не менее это не значит, что и на большем количестве соединений результаты будут в том же самом соотношении да и тест синтетический, в реальных условиях всё может быть иначе.

А вот на тему скорости работы: http://www.camelrichard.org/apache-prefork-vs-worker (mpm worker показывает двухкратный прирост производительности на Solaris!) Для Линукса такого роста, к несчастью, нету: http://www.thrull.com/corner/webserver/prefork-vs-worker/

Сейчас попробуем провести тесты, как будет работать Apache+ mod_fcgi PHP в конфигурациях Prefork и Worker.