вторник, 28 июля 2009 г.

Отладка PHP скриптов на Debian/Ubuntu

Встала необходимость отреверсить PHP скрипт с закрытыми исходниками, а стандартных средств в поставе PHP не обнаружил. Вспомнил, что есть спецовый экстеншен xdebug (помню его потому, что когда-то стащил из их кода интересный хак Zend engine). Ставим его:
apt-get install php5-xdebug


Смотрим, какие у модуля имеются настройки:
php -i | grep xdebug -i
/etc/php5/cli/conf.d/xdebug.ini,
with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans
xdebug
xdebug support => enabled
xdebug.auto_trace => Off => Off
xdebug.collect_includes => On => On
xdebug.collect_params => 0 => 0
xdebug.collect_return => Off => Off
xdebug.collect_vars => Off => Off
xdebug.default_enable => On => On
xdebug.dump.COOKIE => no value => no value
xdebug.dump.ENV => no value => no value
xdebug.dump.FILES => no value => no value
xdebug.dump.GET => no value => no value
xdebug.dump.POST => no value => no value
xdebug.dump.REQUEST => no value => no value
xdebug.dump.SERVER => no value => no value
xdebug.dump.SESSION => no value => no value
xdebug.dump_globals => On => On
xdebug.dump_once => On => On
xdebug.dump_undefined => Off => Off
xdebug.extended_info => On => On
xdebug.idekey => nrg => no value
xdebug.manual_url => http://www.php.net => http://www.php.net
xdebug.max_nesting_level => 100 => 100
xdebug.profiler_aggregate => Off => Off
xdebug.profiler_append => Off => Off
xdebug.profiler_enable => Off => Off
xdebug.profiler_enable_trigger => Off => Off
xdebug.profiler_output_dir => /tmp => /tmp
xdebug.profiler_output_name => cachegrind.out.%p => cachegrind.out.%p
xdebug.remote_autostart => Off => Off
xdebug.remote_enable => Off => Off
xdebug.remote_handler => dbgp => dbgp
xdebug.remote_host => localhost => localhost
xdebug.remote_log => no value => no value
xdebug.remote_mode => req => req
xdebug.remote_port => 9000 => 9000
xdebug.show_exception_trace => Off => Off
xdebug.show_local_vars => Off => Off
xdebug.show_mem_delta => Off => Off
xdebug.trace_format => 0 => 0
xdebug.trace_options => 0 => 0
xdebug.trace_output_dir => /tmp => /tmp
xdebug.trace_output_name => trace.%c => trace.%c
xdebug.var_display_max_children => 128 => 128
xdebug.var_display_max_data => 512 => 512
xdebug.var_display_max_depth => 3 => 3


Теперь в файле /etc/php5/conf.d/xdebug.ini включаем максимальный уровень логгирования:

xdebug.auto_trace=1
xdebug.collect_params=1
xdebug.collect_return=1
xdebug.collect_vars=1
xdebug.dump.COOKIE=1
xdebug.dump.ENV=1
xdebug.dump.FILES=1
xdebug.dump.GET=1
xdebug.dump.POST=1
xdebug.dump.REQUEST=1
xdebug.dump.SERVER=1
xdebug.dump.SESSION=1
xdebug.dump_undefined=1


Либо, если требуется только профайлер делаем следующее ( включаем профайлер и активируем режим добавления логов без перезаписи ):

xdebug.profiler_enable = 1
xdebug.profiler_append = 1


Теперь запускаем какой-либо скрипт командой php -f some_sript.php и ищем в /tmp файл с именем trace (у меня его звали: /tmp/trace.1422822570.xt), как раз в нем и будет весь трейс работы xdebug :)

Обращаю внимание, что xdebug имеет огромный оверхед на скорость. У меня было падение скорости с 50 запросов / секунду до 12.

Также для удобного просмотра есть отличный веб-интерфейс: http://code.google.com/p/webgrind/

понедельник, 27 июля 2009 г.

Хейтспич про РСУБД

Меня искренне достали СУБД с их огромными схемами, на проектирование которых тратится уйма времени, всякие килограммовые ORM, для построения "схем" к которым приходится часто затратить сил больше, чем для написания оных к самой базе данных напрямую. Также я хочу получать от хранилища не какие-то там rowы с какими-то хешами, а хочу чтобы это сразу же ложилось на объекты моего языка программирования, также надоела волокита с кодировками.

Я хочу:
1) Быстро поставить хранилище
2) На лету (за время, пока мысль у меня в голове) создать необходимый мне список полей для сохранения, а также хочу, чтобы его в пару кликов / команд можно было изменить
3) Обращаться к этому стораджу на нэтивном языке программирования и получать от него ответы в том же виде.
4) Хорошее масштабирование
5) Средства резервирования и анализа нагрузки (ага, проанализируйте нагрузку на MySQL, ага, стандартными средствами)

Поэтому сильно хочу сделать проект без СУБД вообще, в частности на: CouchDB или MongoDB (как подсказывают из комментариев) или ZODB.

Perl vs Python

Очередной раз на меня напал информационный голод, началось все с того, что изучил OpenID, потрясающая, на мой взгляд, технология. Но дело пошло дальше и теперь я сижу усиленно разбираюсь в фичах Питона! Собстна вопрос -- зачем мне Питон, если я знаю Перл? Ну, эээ, для разнообразия :)

Сразу оговорюсь, что Питон я знаю очень поверхностно, с Перлом же все чуть-чуть лучше :)

Недостатки Перла:
1. Куча проблем с UTF8. Разобрались, как победить UTF8 в своем коде, протестировали и успокоились? А теперь готовьтесь к тому, что почти каждый модуль на Цпане будет глючить с UTF8. Когда у вас 10 модулей, это можно пережить, а если 100 или, скажем, 200 (в нашей системе где-то в районе того) ? Проще повесится, вы правы.
2. Нет нормальной системы Thread`ов. До сих пор под многие проблемы Перл собирается бех их поддержки, впрочем, и правильно: нет соблазна юзать заведомо кривую технологию. Этот факт ограничивает использование Перла для разработки различных серверов, работающих без фронтэндов.
3. Много полезных модулей не введены с стандартную библиотеку (например, JSON, некоторые XML парсеры и проч.), а выбор на CPAN модулей велик настолько, что существует вероятность так и остаться на тестах, не дойдя до самой разработки :)
4. Отсутствие нормальных ORM.
5. Неудобное развертывание тяжелых систем, включающих сотни модулей. Почти всегда приходится ставить модули с force, т.к. кто-то да и вольет багавую версию либы, от которой зависит пол CPAN
6. Сложность синтаксиса, почти всегда требуется весьма продолжительная подготовка, чтобы понимать почти любой код. Питон же читается также легко как и технический английский
7. Поддержка исключений, нэтивная, без хаков и извратов.

Таким образом, как я вижу, Перл идеален для "тяжелых и старых монолитных", которые ранее появились как "десяток модулей", а потом выросли в монстров. Т.к. у девелоперов есть опыт сожительства со всеми модулями и проблемы с выбором не часто встают, т.к. функционал добавляется достаточно редко.

Для молодых и новых проектов идеален как раз Питон. Тут вам ORM, UTF8, легкая работа с почтой, стандартные быстрые HTTP сервера, удобное и очень быстрое развертывание через easy_install, которое не тащит за собой половину репозитория, куча отличных фреймворков, а также почти нету проблем с "выбором модулей", модули часто довольно хороши и не имеют полутора сотен подверсий, что сильно положительно сказывается на времени разработки. Кстати, о Питоновском ООП: он очень хорош и выглядит "как влитой", никакого маразма как в С++/Java, где ради этого ООПе надо писать тонны обязательного кода. Да, кстати, от Питона у меня руки не болят :)) Символов набивается даже меньше чем в Перле!

А следующий хейт-спич будет по священ РСУБД.

Динамические языки обязательные для изучения

Недавно рассуждал, что из динамических языков (а не из динамических, пожалуй, я бы оставил только С и местами С++) в обязательном порядке необходимо знать Перл и Питон лишь по причине наличия для обоих огромного количества стабильных библиотек (CPAN, pypi), PHP же почти не обладает адекватной кодовой базой для "всех задач" (да, PEAR есть, но мало и уныло) и обычно ограничен Вебом, что сильно сужает его применение и выбивает из группы "необходимых для изучения". Руби же также обладает довольно слабой стандартной библиотекой, а либы от пользователей на РубиФордже часто настолько багавы, что хочется выть. Также на РубиФордже очень много проектов созданы в пик популярности Руби/Рельсов и потом почти сразу же брошены. Эти факторы выбрасывают Руби из списка.

Критика и холивары приветствуются :)

Неизвестный Apache

The TimeOut directive defines the length of time Apache will wait for I/O in various circumstances:

1. When reading data from the client, the length of time to wait for a TCP packet to arrive if the read buffer is empty.
2. When writing data to the client, the length of time to wait for an acknowledgement of a packet if the send buffer is full.
3. In mod_cgi, the length of time to wait for output from a CGI script.
4. In mod_ext_filter, the length of time to wait for output from a filtering process.
5. In mod_proxy, the default timeout value if ProxyTimeout is not configured.

Вот так вота...

воскресенье, 26 июля 2009 г.

RPyC

Хм... конечно. не мануал, но показать "как это работает" хочется-прехочется. Имеем два узла с запущенным classic_server.py: локальный и удаленный, вот так легко выполнять на них команды:

python2.5
Python 2.5.4 (r254:67916, Apr 4 2009, 17:55:16)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import rpyc
>>> local = rpyc.classic.connect('localhost')
>>> local.modules.os.uname()
('Linux', 'nrg-desktop', '2.6.24-22-generic', '#1 SMP Mon Nov 24 18:32:42 UTC 2008', 'i686')
>>> remote = rpyc.classic.connect('ultrasam.ru')
>>> remote.modules.os.uname()
('Linux', 'panel.nrg.name', '2.6.18-6-xen-686', '#1 SMP Sun Feb 10 22:43:13 UTC 2008', 'i686')


Исполнение кода на удаленной машине:

>>> hello_txt = """
... import os
... print "Hello from", os.getcwd()
... """
>>> import os
>>> exec hello_txt
Hello from /home/nrg/rpyc-3.0.6
>>> remote.execute(hello_txt)


И на удаленной машинке выплыло:
Hello from /usr


А вот это меня убило, заживо :)

>>> remote.execute('import urllib')
>>> remote.execute('print urllib.urlopen("http://ya.ru").read()')
>>> local.execute('import urllib')
>>> local.execute('print urllib.urlopen("http://ya.ru").read()')


Потрясающе, у меня нету слов, честно! :)

Установка RPyC

Python

Смотрим версию Питона:
python -V
Python 2.4.4


Если она 2.4, то сносим 2.4й sudo apt-get remove python2.4 (разумеется, если у вас никакого софта от него не зависит) и ставим 2.5й: sudo apt-get install python2.5 python2.5-dev (для Дебияна)

RPyC

Стягиваем файл: rpyc-3.0.6.tar.gz с http://sourceforge.net/projects/rpyc/files/
wget http://downloads.sourceforge.net/project/rpyc/main/3.0.6/rpyc-3.0.6.tar.gz?use_mirror=sunet
tar -xf rpyc-3.0.6.tar.gz
cd rpyc-3.0.6
sudo python2.5 setup.py install (или просто python, если в это время 2.4 версия будет удалена)



Где почитать?
http://www.ibm.com/developerworks/ru/library/l-rpyc/index.html?ca=drs-ru-0707
http://rpyc.wikidot.com/

Установка easy_install на Debian

Все легко и просто:
apt-get install python-setuptools

пятница, 3 июля 2009 г.

could not bind to address 0.0.0.0:80

Как бороться с такой траблой без ребута:

Starting httpd: (98)Address already in use: make_sock: could not bind to address [::]:80
(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down


Заранее известно, что процессы апача все убиты, а других приложений, юзающих 80й порт нету. Просто апача упала, но не освободила сокет :/