пятница, 10 июня 2016 г.

[prog.thoughts] Расширение run-time мониторинга SObjectizer-а: как бы организовать учет времени работы event-handler-ов...

Есть желание в версии 5.5.17 SObjectizer-а расширить объем мониторинговой информации, включив в нее сведения о том, как долго работают обработчики событий. Пригодиться это может, например, чтобы определять какие обработчики отжирают больше всего времени. И даже ловить ситуации, когда обработчик "повис".

Нижеследующий текст является попыткой зафиксировать некоторые соображения на этот счет. Тем не менее, буду признателен, если кто-нибудь из читателей найдет возможность поделиться своими мыслями или своим опытом в этом вопросе.

Итак, сейчас в SO-5.5 есть возможность получать сведения от run-time мониторинга. Диспетчеры и таймерная нить создают у себя так называемые "источники данных". Пользователь может включить режим мониторинга и тогда на определенный mbox с заданным темпом будут отсылаться сообщения с информацией из этих источников данных. Ну а дальше пользователь может подписаться на сообщения из этого mbox-а и делать с получаемой информацией то, что ему нужно (вот совсем простенький пример).

Сейчас в run-time мониторинге есть такая информация как количество рабочих нитей у диспетчеров, размеры очередей на этих нитях, количество коопераций, количество таймеров. Хочется придумать, как добавить туда же информацию и о времени, которое потребляют event-handler-ы.


Первый из связанных с этим вопросов: какая информация будет собираться и как ее представлять?

Тут, вероятно, нужно работать с несколькими вещами. Во-первых, какая-то статистика. Скажем, информация о том, сколько событий всего было обработано, сколько суммарно времени было потрачено (а так же min и max). Откуда получается средняя величина длительности работы event-handler-а. Так же, наверное, можно подсчитывать и времена "простоя", т.е. отрезки времени, когда на рабочей нити ничего не выполнялось. Считаться это должно в рамках какого-то временного окна, скажем, за последнюю минуту или за последний час (естественно, что эти параметры должны настраиваться, если не сразу, то в последующих версиях SO-5). Upd. С точки зрения простоты и эффективности лучше было бы ограничивать не временное окно, а количество измерений: т.е. хранить последние N показаний и вычислять min/max/avg по ним, не суть важно, сколько времени ушло на эти N показаний -- одна секунда или один день.

Во-вторых, текущее значение по текущему event-handler-у. Т.е. если прямо сейчас на рабочей нити работает какой-то event-handler, то можно указать, сколько именно времени он уже работает (ну или просто временную точку, когда он запустился, а уже из нее можно будет вычислить и все остальное).


Второй вопрос сложнее: как избежать лишних накладных расходов, если именно такой тип мониторинга пользователю не нужен?

Понятно, что пока нет реализации, сложно предполагать, какие именно накладные расходы будет иметь этот тип мониторинга. Плюс к тому, эти накладные расходы будут связаны с типом нагрузки: множество мелких event-handler-ов будут приводить к увеличению удельной доли расходов на мониторинг, тогда как на фоне длительных event-handler-ов (работающих от десятков миллисекунд до десятков минут) эти расходы будут иметь мизерный удельный вес.

Тем не менее, очевидно, что отсечки времени запуска и останова каждого event-handler-а будут иметь свою стоимость. И в худшем случае, расходы на мониторинг составят, скажем, от 5 до 10%. Как по мне, так это весьма приличные величины. И нужно подумать о том, чтобы такой тип мониторинга включался только тогда, когда пользователь явно об этом просит.

Вот и хочется понять, как лучше оформить это включение.

Пока видны два варианта:

  1. Включение этого мониторинга сразу для всего SObjectizer Environment. Т.е. при запуске SOEnv, в параметрах Environment-а указывается, что нужно контролировать времена работы event-handler-ов. Все диспетчеры, которые создаются внутри SOEnv, проверяют наличие этого режима и, если он включен, то ведут обработку событий соответствующим образом. Если же такой тип мониторинга отключен, то диспетчеры работают как обычно, без дополнительных накладных расходов на каждый вызов event-handler-а.

    На мой взгляд, у этого способа есть два больших преимущества:

    • во-первых, простота для самого пользователя. Включил подсчет времени один раз и все, больше никаких забот. Все диспетчеры, которые создаются или пересоздаются внутри приложения, будут автоматически подхватывать эту настройку;
    • во-вторых, этот подход ведет к самой простой и эффективной реализации диспетчеров и их рабочих нитей. Т.е. кусок кода, который отвечает за выборку event-handler-а и его вызов, прячется за неким интерфейсом. А диспетчер в начале свой работы один раз создает нужную реализацию этого интерфейса (которая либо считает время работы event-handler-ов, либо не считает).

    Недостатком, соответственно, является отсутствие гибкости. Если в большом приложении работает десяток диспетчеров с сотней рабочих потоков, то и мониторинговых уведомлений будет лететь много (счет в буквальном смысле пойдет на тысячи). И, не смотря на то, что в SO-5 эффективный механизм диспетчеризации сообщений, плюс есть фильтры доставки (которые позволяют отсекать то, что получателю не интересно), все равно может быть не очень удобно.

  2. Включение этого мониторинга на уровне каждого диспетчера. Т.е. при создании диспечера, потроха которого хочется мониторить, в disp_params_t указывается соответствующий параметр. После чего диспетчер сможет создать соответствующие источники данных и будет считать время работы каждого event-handler-а.

    Такой подход, очевидно, самый гибкий. Но и требующий внимания со стороны пользователя: забудешь выставить нужный флажок в disp_params_t и не получишь статистики.

    Это тем плохо, что в рамках одного большого SObjectizer-овского проекта могут объединяться проектики (библиотеки) поменьше. И не всегда будет возможность влезть в исходник чужой библиотеки и поиграться с disp_params_t тех диспетчеров, которые в ней создаются. А отсутствие мониторинга этих самых диспечеров затем вылезет боком: приложение вроде что-то делает, про какую-то часть приложения информация есть, а про остальные часть -- нет. Что неправильно.


Вот какие-то такие мысли по этому поводу. Пока писал этот текст, в голове чуток прояснилось и сумбур начал несколько структурироваться. Так что польза уже есть. А если кто-то еще подключится к обсуждению, то будет еще лучше :)

Отправить комментарий