'

Пора ли отправлять С на свалку истории?

Понравилась презентация – покажи это...





Слайд 0

Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием расширения libevent


Слайд 1

Кто мы такие? Вадим Крючков [Long], руководитель группы разработки Андрей Голубев [440hz], ведущий разработчик Евгений Прудников, ведущий разработчик


Слайд 2

Обычная архитектура (mem)cached


Слайд 3

Наша архитектура — включаем демоны


Слайд 4

Демонизация. Что есть такое libevent? Предоставляет простой механизм для запуска callback функций, при наступлении определенного события на дескрипторе: READ WRITE TIMEOUT SIGNAL http://www.monkey.org/~provos/libevent/ http://ru.php.net/manual/en/intro.libevent.php


Слайд 5

Пишем демона


Слайд 6

Пишем демона, работающего с сокетом // Создаем сокет - event вешается на дескриптор $rSocket = stream_socket_server ( 'tcp://127.0.0.1:666', $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN ); // далем его не блокирующим, что бы позволить принимать другие коннекты stream_set_blocking ( $rSocket, 0 );


Слайд 7

Пишем демона — подключаем libevent // создаем событийную базу $rBaseEvent = event_base_new ( ); // создаем новое событие для сокета $rSocketEvent = event_new ( ); /** * ловим события "чтение" и после операции чтения возвращаем событие в базу * EV_READ - чтение * EV_PERSIST - вернуть событие в базу после выполнения */ event_set ( $rSocketEvent, $rSocket, EV_READ | EV_PERSIST, 'onAcceptEvent' ); // устанавливаем событие в базу событий event_base_set ( $rSocketEvent, $rBaseEvent ); // запускаем отслеживание event_add ( $rSocketEvent ); // запускаем цикл event_base_loop ( $rBaseEvent );


Слайд 8

Метод обработки function onAcceptEvent ( $rSocket, $rEvent, $args ) { global $rBaseEvent; // удобнее сделать через объект ;) static $iConnect = 0; // идентификатор конекта $iConnect++; // Примем коннект $rConnection = stream_socket_accept ( $rSocket ); // далем коннект не блокирующим, что бы позволить принимать еще коннекты stream_set_blocking ( $rConnection, 0 ); // создадим буфер обмена данными $buf = event_buffer_new ( $iConnect, 'onReadEvent', 'onWriteEvent', 'onFailureEvent', $iConnect); // подключаем буфер к базе событий event_buffer_base_set ( $buf, $rBaseEvent ); // включаем буфер на события и возвращаем события назад после выполнения event_buffer_enable ( $buf, EV_READ | EV_WRITE | EV_PERSIST ); }


Слайд 9

Метод чтения $iBufferReadLenght = 1024; // размер буфера чтения function onReadEvent($rStream, $args) { global $iBufferReadLenght; $tmp = ''; do { $tmp .= event_buffer_read ( $hBuffer, $this->iBufferReadLenght ); if( $iBufferReadLenght > strlen($tmp) ) { break; } } while ( true ); return $tmp; }


Слайд 10

Превращаем демона в ... или не документированные возможности


Слайд 11

Таймеры (thnx 440hz) Стандартный таймер libevent'а не работает :( Выход есть! событие можно повесить на «любой» дескриптор event_add ( resource $event, int $timeout )


Слайд 12

Таймеры - решение tmpfile() - открываем новый временный файл «вешаем» на этот дескриптор отложенное событие event_set( $rTimers, $rTtmpFile, 0, 'onTimer', );


Слайд 13

Демонстрация http://cyberdot.ru/src/socket.phps


Слайд 14

Подводные камни Очень мало информации и примеров Следить за ресурсами, не забываем их освобождать Хитрости при чтении данных, превышающих размер буфера Входных данных — много и они бывают «чужие» :) Проблемы с отслеживанием сигналов (EV_SIGNAL)


Слайд 15

Даем нагрузку


Слайд 16

Тестирование ботами Имитируем … пользователей в on-line: Воспользовались API Написали приложение, генерирующее ботов


Слайд 17

Результаты Сервер Xeon 8х2.66GHz, RAM 8Gb: Около 2.5 тысяч запросов в секунду (не Hello, World) На 1 пользователя в online расходуется около 1Мб памяти Приложение (пока) не подвергалось жесткой оптимизации


Слайд 18

Результаты Сервер Xeon 8х2.66GHz, RAM 8Gb: Около 2.5 тысяч запросов в секунду (не Hello, World) На 1 пользователя в online расходуется около 1Мб памяти Приложение (пока) не подвергалось жесткой оптимизации Память не «течет» (1 месяц публичного бета-теста не выявили)


Слайд 19

Советы Научитесь «мыслить параллельно» Процесс не завершается Чужие данные Читайте исходники — в них много полезного Если демон будет не один — напишите простенький фреймворк Документируйте код + протокол взаимодействия Напишите хороший логгер - без него отлаживать приложение будет сложно Сделайте несколько уровней логгирования


Слайд 20

Выводы Выводы пока делать рано :)


Слайд 21

Выводы (серьезно) Можно рекомендовать к использованию на продакшене Позволяет держать хорошие нагрузки (при этом оставляя LA в разумных пределах ) Реальные тесты — придется подождать :(


Слайд 22

Вопросы?


×

HTML:





Ссылка: