Archive for category oProxy
oProxy release
Posted by John Lepikhin in oProxy, программирование on May 20th, 2009
Не прошло и полгода, как я решил разродиться на релиз прокси. Назовём его “1.1″.
Nginx против oProxy: друг другу сливаем :)
Posted by John Lepikhin in Ocaml, Performance, oProxy, программирование on February 1st, 2009
Потестировал производительность проксирования HTTP трафика. Результаты местами получились весьма неожиданными.
Повторю, тестировалось именно проксирование. Известно, что при прямой отдаче и Apache, и Nginx использует ядрёный вызов sendfile(), который отдаёт содержимое файлика в сокет без лишних копирований. Это неинтересно. А вот проксирование — это совсем другое дело. В ядре пока что ещё нет прямых путей для копирования из сокета в сокет (есть полупрямой вариант splice() + pipe(), но как выяснилось он даже не на всех современных ядрах работает).
Итак…
Пора в production? Скоро узнаем.
Posted by John Lepikhin in Ocaml, oProxy, программирование on January 29th, 2009
Готовимся к продакшен тестированию. Надеюсь, завтра запустить всё воедино на тестовых машинах.
Из нового:
- Балансировка нагрузки. Универсальный модуль для любых видов соединений. Написано кривовато, но работает. Заведует всеми узлами мастер-процесс. Это несколько замедляет процесс (рабочим приходится больше общаться с мастером), зато позволяет контролировать балансировку в одном месте.
- Файлик: список сайтов. Пока каждый сайт можно только включить/выключить и прописать алиасы. Кроме того, на будущее есть поле “домашняя директория сайта”. В ближайшее время есть планы проксёй отдавать статичные файлы. Не понятно, что делать с .htaccess. Не хочется забивать, как это нынче делается в Nginx.
- Файлик: список узлов. Представляет из себя IP, мастер-пароль, список ролей.
- Роли. Что каждая машина умеет/должна делать. От этого зависит поведение балансировщика и некоторых скриптов. Предопределённые роли: worker_http (узел умеет обрабатывать HTTP-запросы), master (узел будет точкой входа, где висит балансировщик) и другие. Всё рассказывать раньше времени не буду :)
- Мониторинг. Наконец нашёл, где заюзать функционалы. На основе этого функционала (functional) написан мониторинг файлов. Как результат, прокся умеет автоматически подгружать изменённый список сайтов или узлов.
- Новый параметр у oproxyctl: show_nodes. Показывает известные узлы. Кто в дауне, сколько у каждого активных запросов, сколько всего обработано. Может оказаться полезным для выяснения проблемных узлов.
- Поддерживаем новый протокол, который я сам выдумал :) Служит для различных сервисных запросов к узлу. Поскольку позволяет совершать совершенно небезопасные вещи, авторизация происходит без передачи открытого пароля по сети.
- Новая утилита: clusterctl. Умеет 1) запустить на узлах с указанной ролью (или на всех, или на определённом IP) определённую команду и вернуть в STDOUT/STDERR что в итоге получилось 2) рассказывать список ролей текущей ноды 3) рассказывать список узлов, поддерживающих указанную роль. Служит для сервисных скриптов.
- Прокся умеет выставлять X-Forwarded-For, чтобы в конечном итоге в логи попадал нужный IP.
- Сервисные скрипты: apachectl (рестарт Апача на всех узлах), repquota и другие.
- Оптимизация, стабильность.
Допил коньяк. Опять потянуло на философию…
Торжественно заборот(заборон?) последний крупный баг
Posted by John Lepikhin in oProxy on December 28th, 2008
… В результате которого рабочий иногда падал, валя за собой всю проксю. Как и предполагал, дело оказалось в рекурсии, которая не могла быть развёрнута в tail из-за не пойманных исключений внутри. Это можно назвать минусом смешивания чистой функциональщины с чем-то ещё. Но, увы и ах, ловить все исключения внутри нельзя.
Заменил рекурсивный вызов на цикл, и уже двое суток работаем ровно и без падений; обработано около 2000000 реальных соединений к MySQL.
Кстати…
чуть-чуть обновлений
Posted by John Lepikhin in oProxy on November 28th, 2008
1. oproxyctl — утилита управления проксёй. Пока умеет корректно останавливать, показывать/сбрасывать статистику.
2. Порт под FreeBSD. Это удивительно, но под фрюхой прокся вываливалась с исключениями о deadlock’ах в мутексах. И это правильно, там алгоритмически иначе быть не может. Почему этого не происходило под Linux — фиг знает. А ведь и там вываливалась иногда с этим, но не в этих местах кода…
3. Полная поддержка KeepAlive. Сводится к тому, что прокси теперь не жалуется в логи, если в процессе ожидания команды от клиента случился таймаут. И вообще, логи оставлены практически только для ошибок.
4. Исправлено несколько разного рода ошибок.
В общем, ничего интересного. Дальше в планах написание балансировщика для mysql_proxy и конфиг. Конфиг — это большая тема. Там должен быть элемент ЯП. И что этот язык должен уметь, ещё надо подумать.
oProxy: производительность mysql_proxy
Posted by John Lepikhin in Performance, oProxy on November 25th, 2008
Сократил оверхед до 56 МИКРОсекунд на запрос (т.е. запрос отдаётся в среднем медленнее на это время, чем если бы подсоединялись напрямую). Для сравнения, у Mysql Proxy это значение заявлено в 400 МИКРОсекунд, т.е. 7 раз больше. Но у меня практически никакого анализа пакетов не делается, только выясняю подсоединившегося пользователя и собираю статистику. Считал скриптом:
time perl -MDBI -e ‘$dsn = “DBI:mysql:database=mysql;host=127.0.0.1;port=5501″;$dbh = DBI->connect($dsn, “user”, “анунеподглядывай”);for(0..100000){$s = $dbh->selectall_arrayref(”select repeat(100000000000000000, 10)”);}’
Во время выполнения, oProxy ел около 31% CPU, MySQL 25% Perl 50%. Ещё есть куда расти.
oProxy: mysql_proxy
Posted by John Lepikhin in oProxy on November 23rd, 2008
Сел вечерком в воскресенье, и практически написал проксю для MySQL. Затраченное время: 2:56.
Что умеет: собственно, проксировать (80% готово, см. ниже). Считать трафик, затраченное время и количество запросов. Поддерживает протоколы MySQL >= 4.1 (версия протокола 10?). Теоретически поддерживает и более младшие версии, но не тестировал.
Чего пока не умеет: проксировать наборы данных в ответах клиенту. На реализацию потребуется не более полутора часов.
Чего не будет уметь: балансировать нагрузку. Изначально планировал часть select’ов направлять на реплицирующий сервер. Увы, из-за особенностей протокола MySQL и авторизации в частности, это не представляется реализуемым. Во всяком случае, идея меня пока так и не посетила. Возможно, что-то даст изучение исходников существующих балансеров, если конечно есть с открытым кодом.
oProxy: еще больше статистики, поймано последнее исключение, которое оказалось совсем и не исключением.
Posted by John Lepikhin in oProxy on November 20th, 2008
3 дня охотился за мифической ошибкой, которая намертво обрушивала рабочих. Дело осложнялось тем, что происходило это только через магические 180/210 секунд и только после серии прерванных запросов. Следы привели к Unix.write. Долго расставлял ловушки для исключений, но улова не было. Заменил Unix.write на Unix.single_write. И — о чудо! Похоже, что больше не падает.
UPDATE: Дело оказалось в другом. Когда далёкая сторона рвёт пайп, процесс ловит не исключение, а сигнал SIGPIPE. Который, соответственно, и надо было отловить. Но это уже исключительно моя глупость. Достаточно было воспользоваться gdb. Теперь уже точно всё чудесно:
2008-11-21 15:04:49 [21685] Worker: Exception: Exception got while putstring(): Failure(”Broken pipe”)
2008-11-21 15:04:49 [21685] Worker: Exception: Exception in protocol_http: End_of_file
Read the rest of this entry »
oProxy: поддержка постоянных соединений, охота на исключения и http benchmark
Posted by John Lepikhin in oProxy on November 19th, 2008
Дописал поддержку keepalive, ловлю в ключевых местах все исключения. Но этот момент можно улучшать ещё долго. Стабильность кода значительно увеличилась.
Померил более достоверными средствами производительность. Окружение: запросы на http://ya.ru, контент которого закэширован моей домашней прокси (Squid). Запросы идут через wlan. Флуд-атака 40-а конкурентными пользователями. Организовал с помощью siege. Строчка запуска: siege -t 30s -b -c 40 http://ya.ru >/dev/null