Перейти до

kvant-v

Маглы
  • Всього повідомлень

    12
  • Приєднався

  • Останній візит

Все, що було написано kvant-v

  1. Я увидел один серьёзный недостаток собственного решения, Патч с текущими цифрами не позволит в полной мере использовать возможности "ExecutersNum" с большими значениями. Хотя всё будет работать маленькая очередь станет слабым местом системы Ну а с большими цифрами снова создастся опасность переполнения очереди. вопрос снят.
  2. Да. А с текущими цифрами возможны какие-то грабли ? Мне казалось я всё предусмотрел. Из моих соображений как недостаток можно рассматривать большое число опросов состояния очереди на медленно выполняемых скриптах, мне не известно насколько ресурсо-ёмкая эта операция т.е. возможна доп. нагрузка на систему заметная на слабых машинах хотя у себя я пока такого не заметил.
  3. Интересная особенность патча, не смотря на значение параметра равного 1 while (data.msg_qnum > 1) //цикл ожидания освобождения очереди до заданного значения заполненности последовательность пуска скриптов выглядит так: 3 скрипта OnConnect соответствующие 3-ём OnConnect скрипты OnChange 3 следующих OnConnect соответствующие 3-ём следующим OnConnect скрипты OnChange ..... ..... На самом деле так и должно быть, первый скрипт OnConnect сразу забирается из очереди на выполнение, второй заполняет очередь до 1 и только третий заполняет очередь до 2 что по условию активирует приостановку заполнения очереди из плагина "ао". После чего в очередь встают и выполняются скрипты OnChange. Когда в очереди стоит последний не выполнненый OnChange, приостановка заполнения очереди из плагина "ао" деактивируется и в очередь снова попадают скрипты OnConnect.
  4. Мне всё-таки удалось , благодаря помощи Madf, создать патч применение которго позволяет использовать в пусковых скриптах sgconf get и set при кол-ве юзеров always online более 60. Может кому-то пригодится, а может когда-нибудь и в релиз попадёт . Патч добавляет новую функцию в плагин "always online autorizator", которая не даёт очереди скриптов переполниться или опустеть. функция представляет собой управляемую, паузу которая активируется и деактивируется в зависимости от состояния очереди. Функция содержит два важных параметра о значениях которых, хотелось-бы "услышать" мнение специалистов. А так-же какие недостатки в целом есть у данного решения ? Мне почему-то не удалось загрузить файл на форум, потому публикую патч так. Для применения перед компиляцией поместить в каталог с исходниками и набрать в этой директории команду: patch -p1 < имя_файла_патча Для отката patch -p1 -R < имя_файла_патча Патч пока для версии 2.407-p1: diff -u -r stg-2.407-p1/include/stg/settings.h stg-2.407-p1--/include/stg/settings.h --- stg-2.407-p1/include/stg/settings.h 2011-05-19 19:03:26.000000000 +0400 +++ stg-2.407-p1--/include/stg/settings.h 2012-01-28 22:09:46.000000000 +0400 @@ -39,6 +39,7 @@ virtual unsigned GetMessageTimeout() const = 0; virtual const std::string & GetMonitorDir() const = 0; virtual bool GetMonitoring() const = 0; + virtual int GetExecMsgKey() const = 0; }; //----------------------------------------------------------------------------- diff -u -r stg-2.407-p1/projects/stargazer/plugins/authorization/ao/ao.cpp stg-2.407-p1--/projects/stargazer/plugins/authorization/ao/ao.cpp --- stg-2.407-p1/projects/stargazer/plugins/authorization/ao/ao.cpp 2011-05-19 19:03:27.000000000 +0400 +++ stg-2.407-p1--/projects/stargazer/plugins/authorization/ao/ao.cpp 2012-01-29 00:41:56.000000000 +0400 @@ -30,6 +30,8 @@ #include <algorithm> // for_each #include <functional> // mem_fun_ref +#include <sys/msg.h> +#include "stg/settings.h" #include "stg/user.h" #include "stg/users.h" #include "stg/user_property.h" @@ -126,6 +128,7 @@ Unauthorize(*users_iter); UnSetUserNotifiers(*users_iter); ++users_iter; + SleepWhileNotFreeQueue(); } isRunning = false; return 0; @@ -246,6 +249,7 @@ USER_IPS ips = u->GetProperty().ips; if (ips.OnlyOneIP()) { + SleepWhileNotFreeQueue(); if (u->Authorize(ips[0].ip, 0xFFffFFff, this) == 0) { } @@ -287,3 +291,19 @@ auth.UpdateUserAuthorization(user); } //----------------------------------------------------------------------------- +void AUTH_AO::SleepWhileNotFreeQueue() const +{ +//STG_LOGGER & WriteServLog = GetStgLogger(); // для отладки +int msgID = msgget(stgSettings->GetExecMsgKey(), 0); //получаем идентификатор очереди +struct msqid_ds data; +struct timespec ts = {0, 4000000};//0.004 сек //значение паузы между запросами состояния очереди во время ожидания её освобождения +msgctl(msgID, IPC_STAT, &data); //запрос состояния очереди для определения необходимости ожидания её освобождения +//WriteServLog("Msg in queue: %d", data.msg_qnum); // для отладки, позволяет увидеть в логе процесс заполнения очереди + +while (data.msg_qnum > 1) //цикл ожидания освобождения очереди до заданного значения заполненности + { + nanosleep(&ts, NULL); //пауза между запросами состояния очереди + msgctl(msgID, IPC_STAT, &data); //запрос состояния очереди + } +} +//----------------------------------------------------------------------------- diff -u -r stg-2.407-p1/projects/stargazer/plugins/authorization/ao/ao.h stg-2.407-p1--/projects/stargazer/plugins/authorization/ao/ao.h --- stg-2.407-p1/projects/stargazer/plugins/authorization/ao/ao.h 2011-05-19 19:03:27.000000000 +0400 +++ stg-2.407-p1--/projects/stargazer/plugins/authorization/ao/ao.h 2012-01-28 22:07:59.000000000 +0400 @@ -77,7 +77,7 @@ void SetAdmins(ADMINS *) {} void SetTraffcounter(TRAFFCOUNTER *) {} void SetStore(STORE *) {} - void SetStgSettings(const SETTINGS *) {} + void SetStgSettings(const SETTINGS * s) { stgSettings = s; } int Start(); int Stop(); @@ -105,6 +105,8 @@ mutable std::string errorStr; USERS * users; + const SETTINGS * stgSettings; + void SleepWhileNotFreeQueue() const; std::list<USER_PTR> usersList; bool isRunning; MODULE_SETTINGS settings; diff -u -r stg-2.407-p1/projects/stargazer/plugins/configuration/sgconfig/stgconfig.cpp stg-2.407-p1--/projects/stargazer/plugins/configuration/sgconfig/stgconfig.cpp --- stg-2.407-p1/projects/stargazer/plugins/configuration/sgconfig/stgconfig.cpp 2011-05-19 19:03:27.000000000 +0400 +++ stg-2.407-p1--/projects/stargazer/plugins/configuration/sgconfig/stgconfig.cpp 2012-01-28 21:26:57.000000000 +0400 @@ -240,12 +240,12 @@ //----------------------------------------------------------------------------- uint16_t STG_CONFIG::GetStartPosition() const { -return 220; +return 10; } //----------------------------------------------------------------------------- uint16_t STG_CONFIG::GetStopPosition() const { -return 220; +return 10; } //-----------------------------------------------------------------------------
  5. Ну это хороший конечно способ завалить старгейзер, но уж очень примитивный. Любой админ сразу поймёт почему скрипт виснет, ещё на стадии тестирования. Вот этот способ (из документации) гораздо интереснее. sgconf get -s <server> -p <port> -a <admin> -w <admin_password> -u <user> <options> sgconf set -s <server> -p <port> -a <admin> -w <admin_password> -u <user> <options>
  6. Основная проблема текущей дефолтной очерёдности помоему как раз в сюрпризах. Изначально кажется что всё хорошо работает. Ну никак я не мог подумать что если на тестовом сервере 3 юзера работали то уже с 7 будут проблемы. И когда я решился на установку старгейзера на реальный сервер с реальным числом юзеров и уже проверенными на том тестовом сервере скриптами, вот это был сюрприз на всю ночь я долго вообще не мог понять в чём дело. Думаю многие кто шёл по моему пути на этом месте отказались от старгейзера. Но вы безусловно правы, аналогичный сюрприз для провайдера с нескольками тысячами юзеров уже работающих на старгейзере будет несравнимо более катастрофическим, чем для тех кто только ставит. Я кажется начинаю понимать Вашу религию
  7. Nightfly, помоему это ваши слова: и затем: Нее ну против религии я конечно ничего не имею. Извините не знал. Я просто хотел сделать свой посильный вклад в развитие старгейзера, не только для себя лично. У людей ведь фантазия богатая, мало ли какой контекст у них будет. А для себя благодаря Madf и Вам я все проблемы уже решил. За что ещё раз огромное спасибо.
  8. А помоему на этом форуме оч. много сообщений о граблях, ноги у которых на самом деле как раз из модуля "always online" растут. Например сообщения о том, что старгейзер глючит от больших скриптов. И мой опыт показал, что добиться нормального выполнения "больших скриптов" вполне реально. Конечно код там присутствует и он делает "тонны" полезной для меня работы. И если код скриптов без ошибок то какие причины для отказа его выполнения ? Помоему максимум плохого что должно быть от больших скриптов это снижение быстродействия. Вопрос к Madf: приемущества от смены порядка запуска модулей помоему очевидны - мы получаем возможность использовать gconf get Раз вы не видите смысла значит есть и минусы - какие ?
  9. Не успел вчера дописать самое интересное. После того как удалось изменить порядок запуска старт прошёл быстро и без единого сбоя, тогда я для краш теста скопировал запрос sgconf get 10 раз и снова пуск без единого сбоя, Мой костыль впервые оказался не задействованным при запуске. Такое кол-во запросов было эквивалентно запуску 600 юзеров моей системы. Тогда я решил проверить как будут обстоять дела с записью параметров sgconf set Добавил один запрос sgconf set с двумя ключами - и получил зависание уже на втором юзере ! Убрал 9 лишних запросов sgconf get оставив 1, снова зависение на втором юзере. Стал изучать висящие процессы всё стопорилось как раз на sgconf set И тут я вспомнил что sgconf set отличается от gconf get тем, что при его отработке должен отрабатывать скрипт OnChange и возможно так-же через общую очередь выполнения скриптов но в висящих процессах его небыло, тогда я воткнул в скрипт OnChange команду echo записывающую в лог старгейзера момент отработки, и к удивлению не обнаружил в логе ни одного запуска этого скрипта, только два пуска OnConnect на втором из которых всё зависло. дальше была серия бесполезных экспериментов в ходе которых я случайно удалил скрипт OnChange и вдруг всё стартовало без единого сбоя !!! Правда в логе запуска по каждому юзеру сообщалось что не обнаружен исполняемый файл OnChange. Я подумал что где то в скрипте ошибка, вернул его на место и полностью опусташил. И снова висяк на втором юзере ,тут я был в тупике . Как может вешать программу почти сразу на старте совершенно пустой скрипт, который к тому-же вообще ни разу не запускался ?!!! Через час до меня дошло ! OnChange ни разу не отработал, но возможно встал в конец очереди на выполние, и sgconf set висит возможно потому что безуспешно пытается поставить в переполненную очередь очередной скрипт OnChange , а в случае когда скрипт OnChange вобще отсутствовал то и в очередь его никто ставить не пытался и всё работало. Длинну очереди как собстно и её реализацию в исходниках пока не нашёл но экспериментально знаю что она около 60 скриптов. и в данном случае заполнить её под завязку мог только модуль "Always Online autorizator v.1.0" и заполнил он её скорее всего из за того, что скорость заполнения значительно превышает скорость выполнения скриптов с включёнными в них sgconf запросами. Решения тут два похоже. Первое простое и не эффективное: я вставил паузу в 0,4 секунды в цикл включения юзеров и в цикл их отключения в модуль "Always Online autorizatorv.1.0" Всё работает на ура ! и на запись и на чтение, что подтверждает что я на верном пути. Но оптимальное значение этой паузы для разных конфигураций систем и скриптов будет сильно отличаться. вот код двух функций ao.cpp со вставленной паузой вставка выделена так: ////////////// //----------------------------------------------------------------------------- void AUTH_AO::UpdateUserAuthorization(USER_PTR u) const { if (u->GetProperty().alwaysOnline) { USER_IPS ips = u->GetProperty().ips; if (ips.OnlyOneIP()) { if (u->Authorize(ips[0].ip, 0xFFffFFff, this) == 0) { ////////////////////////////////////////////////////// struct timespec ts = {0, 400000000}; nanosleep(&ts, NULL); ////////////////////////////////////////////////////// } } } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int AUTH_AO::Stop() { printfd(__FILE__, "AUTH_AO::Stop()n"); if (!isRunning) return 0; users->DelNotifierUserAdd(&onAddUserNotifier); users->DelNotifierUserDel(&onDelUserNotifier); list<USER_PTR>::iterator users_iter; users_iter = usersList.begin(); while (users_iter != usersList.end()) { Unauthorize(*users_iter); UnSetUserNotifiers(*users_iter); ++users_iter; ////////////////////////////////////////////////////// struct timespec ts = {0, 400000000}; nanosleep(&ts, NULL); ////////////////////////////////////////////////////// } isRunning = false; return 0; } //----------------------------------------------------------------------------- Второе решение сложное и эффективное: "научить" "Always Online autorizator v.1.0" отслеживать состояние очереди выполнения скриптов, и приостанавливать включение юзеров Always Online когда в очереди уже есть 5-6 скриптов, в этом случае для скриптов OnChange всегда будет место в очереди и на быстродействие "легких" скриптов читающих данные напрямую из базы это не должно повлиять. Но только второе решение я наверно не осилю хотя попытаюсь конечно если поможете. И у меня по этому поводу вопросы: Ткните меня пожалуйста где реализована очередь, в упор не вижу но знаю что где-то есть. Ну и может быть к ней уже есть доступ из выше описанных функций, хотя наверно нет. предполагаю, что нужно сделать функцию в том модуле где эта очередь находится функция должна возвращать значение int заполненности очереди Паузу уменьшить раз в 50 и поместить внутрь цикла с вызовом этой функции цикл должен повторяться пока очередь не освободится до 5 скриптов. Жду вашего мнения по поводу выше описанного алгоритма. Думаю если допилим работу sgconf до стабильного состояния всё это будет лишним Ну, а это, надеюсь, в будущих версиях будет идти по умолчанию ? Старгейзеру действительно никакой, и ему помоему нет дела до большинства параметров хранимых в его базе данных и отображаемых на экране его конфигуратора, они отображаются старгейзером для пользователя в данном случае для меня. Именно этой универсальностью мне он и нравится, он может отображать фильтровать оперативно обновлять и сортировать на экране любые параметры какие я ему поручу, даже те до которых ему нет дела но я хочу их видеть. И помоему ничего лишнего я от него не требую когда пытаюсь заставить sgconf работать в скриптах, а иначе зачем sgconf тогда вобще был создан и задокументирован. Ну а для чего мне видеть в данном случае текущие параметры шейпера то вот пример, звонит мне Вася Пупкин и предьявляет почему у него скорость интернета периодически падает я одним взглядом на экран сразу знаю что ему ответить, и если Вася грубанул с трафиком и шейпер снизил ему приоритет то я ему так и скажу, а если шейпер его не обижал, значит пора мне искать причину у себя. (забыл пояснить, старгейзером я раздаю интернет в офисе) Ну можно конечно всё в лог валить, а потом через трёх конвеерный grep всё там искать, но я как-то не очень дружу с консолью, вобщем у всех свои методы. Если в моём офисе будет сотня юзеров то первым погибну я
  10. Это то-что надо ! Madf, спасибо огромное ! Я бы месяц это искал, даже не думал, что последовательность пуска модулей внутри их самих. У меня вчера мозгов хватило только на то, чтобы поменять местами в main.cpp строки modules.sort(StartModCmp) и modules.sort(StopModCmp) что привело к полной обратной последовательности пуска-останова доп. модулей и могло иметь плохие последствия. Но мой кривой способ всё-же позволил мне вчера провести эксперимент который я повторил сегодня уже в нормальном варианте: И так напомню, проблемы с получением данных через gconf в OnConnect начинались с увеличением числа юзеров always online до 7. и решались костылём в виде повторных запросов в случае не удачи с записью в лог, и записи эти были при каждом пуске, с числом юзеров 60 костыль уже не помогал система стабильно уходила в бесконечный цикл запросов. В скрипте использовался один запрос sgconf get с шестнадцатью ключами параметров. И один запрос sgconf set который по условию пчти никогда не вызывался.
  11. Удобно видеть параметры динамического шейпера в GUI конфигураторе напротив каждого юзера ну вобщем как раз в старгейзере. Эти параметры могут меняться каждую минуту в зависимости от активности юзера. Благодаря Вам я теперь знаю, что другого способа, кроме как через "прослойки" их там отобразить нет, а городить только ради этого отделный веб интерфейс как-то не охота. Да и ошибки установки шейпера пока скрипты не отладил бывало появлялись, очень оперативно было видеть их в таблице, Так-же напротив отображается реальная скорость прокачки юзера (вычисленная средствами модифицированного конфигуратора за интервал между обновлениями) и можно оценить работу шейпера. Этот метод я видел думаю он действительно хорош и не зависит от типа базы, но он годится только для чтения данных, а для записи нет. Вобщем уже попользовавшись sgconf, мне никак не хочется расставаться с его универсальностью и простотой использования. К тому-же sgconf отлично по русски задокументирован. Помоему с этим нужно что-то делать и я решил попробовать. Раз я хоть что-то правильно понял, шанс на успех думаю есть. Мой опыт c++ под linux == 0 ,так что не судите строго Целый день и почти всю ночь я вёл не равный бой с исходниками с переменным успехом Пишу к Вам, товрищи, из последних сил глаза уже в кучу. Есть первые результаты завтра просплюсь убедюсь что это не миражи и поделюсь.
  12. Каждая домохозяйка должна научиться ковырять исходники.

  13. Мой OnConnect используeт для получения данных sgconf На 5 юзеров всё было ОК. После увеличения числа юзеров always online до семи первые два при запуске не могли получить данные грешил на модуль mysql поставил костыль в виде циклического перезапроса данных в случае не удачи, временно проблема решилась. Сейчас при достижении кол-ва юзеров always online 60 проблема появилась снова и выглядит так : при бесконечном цикле перезапроса данных в случае не удачи - сервер зависает судя по логам на старте модуля "Always Online autorizator v.1.0" точнее зависает наверно скрипт OnConnect, а сервер очевидно ждёт завершения его работы. Если ограничиваю цикл перезапроса данных в случае не удачи пятью попытками - сервер задерживается на старте модуля "Always Online autorizator v.1.0", в это время скрипт OnConnect отрабатывает не удачно (так и не получив данных) для 6 первых юзеров делая по 5 попыток + sleep 2 на каждого, затем старт всех модулей старгейзера судя по логам завершается и все остальные "юзеры" стартуют нормально. Затем я обратил внимание на то что модуль "Stg configurator v.0.08" вообще всегда стартует последним ! Т.е. запуск юзеров always online всегда начинается в момент когда модуль "Stg configurator v.0.08" ещё не запущен !!! И в этот момент действительно никак нельзя получить данные через sgconf По моей логике это вобще не могло работать, но ведь работало на пять юзеров вообще проблем не замечал ! Как ?! Предполагаю что в варианте на 5 юзеров они не запускались при старте модуля "Always Online autorizator v.1.0", а только добавлялись в очередь, а запускались все уже после старта всех модулей. Ну а в варианте на 60 юзеров очередь наверно переполняется. Подскажите пожалуйста правильно ли я тут всё понимаю ? И если правильно то можно ли как-то заставить модуль "Stg configurator v.0.08" запускаться раньше чем модуль "Always Online autorizator v.1.0" Или без переделки скриптов на прямое обращение к базе мне не обойтись ? И ещё я добавил в windows конфигуратор возможность отображения в таблице полей userdata и при старте скрипт OnConnect заносит туда опять-же через sgconf информацию о текущем режиме работы динамического шейпера и об ошибках установки правил для юзера если таковые были. Если я сделаю прямую запись в базу в поля userdata, увижу ли я эти данные в конфигураторе сразу и вобще можно ли так делать ? Ос: OpenSuse 11.4 stg v. 2.407-p1 mysql пробовал вместо mysql firebird не помогло , даже показалось что было хуже.
×
×
  • Створити нове...