Real-Time мониторинг сервиса на Windows Workflow Foundation с помощью StreamInsight, SignalR

от автора

У нас есть Workflow сервис, выполняющий некоторый процесс и сейчас нет средства Real-Time мониторинга этого сервиса.

Расширение AppFabric к IIS показывает кумулятивную информацию о количестве инстансов за период, но чтобы видеть последнюю информацию, нужно постоянно жать руками на обновление. Так же нельзя сравнить количество инстансов в периоде.
Можно снять данные с Monitoring Database — это решение опять же завязано на AppFabric, также получение последних изменений в real-time сложно (нужно делать регулярные запросы и т.д. и т.п.)

Нужно придумать способ узнавать информацию о некотором наборе метрик в виде диаграмм на chart с постоянным обновлением текущего состояния.

Мы нарисовали что-то похожее. Оригинал к сожалению не сохранился.

Кому это нужно

Все кто предварительно читать статью, задавали один и тот же вопрос- для кого все это сделано.
Ответ- в случаи просадки производительности, которая началась и еще не закончилась- этот инструмент как раз и показывает состояние части системы. Зная нормальные значения, можно увидеть что они не в порядке, или происходят какие-либо всплески. Фактически- это инструмент мониторинга работающего сервера ведь.

Выбор библиотек

Выбор библиотеки для реализации Real Time Server

Выбор был по большом счету предопределен: когда есть решение рекомендованное вендором платформы (SignalR от Microsoft), то все остальные почти всегда идут лесом. Для очистки совести (и самообразования) было проведено изучение еще одной библиотеки, которую смогли нагуглить — Xsocket.
На сайте Xsocket есть сравнение. Там достаточно много параметров. Каждый вендор свое болото хвалит, как известно. Я выбрал несколько ключевых параметров по которым отвалился xsocket.

  • Только websockets, webrtc. Т.к. ни каких ServerSiteEvents, ForeverFrame, longpooling. В IE не поддерживает webrtc. В итоге IE9 не поддерживается, а в компании много народу сидит на win7 без sp1 даже… А следовательно, вообще с IE8. Уже этого достаточно, чтобы не смотреть на эту библиотеку;
  • Платная поддержка;
  • Количество скачивания с nuget на порядок меньше чем у signalr.

Я не готов брать проект не вендора и при этом не видно, чем он принципиально лучше. SignalR более популярна и решает поставленную задачу.

Выбор клиентской библиотеки отображения графиков

Библиотека для отображения графиков была выбрана canvasjs . Причина выбора проста: Google выдал ее по запросу «rea ltime chart js library». В течение часа разбора по этому вопросу было принято решение: не тратить время на изучение альтернатив, если уже это нам подходит. Библиотека работает и с Chrome и с IE9+. Значит, подходит.

Пример работы с библиотекой

Выбор библиотеки хранения данных:

StreamInsight — рекомендованная Microsoft платформа для реализации системы мониторинга.
Цитата:
Microsoft Stream Insight provides a powerful platform for developing and deploying complex event processing (CEP) applications. CEP is a technology for high-throughput, low-latency processing of event streams. Typical event stream sources include data from manufacturing applications, financial trading applications, Web analytics, or operational analytics.

Забегая вперед

сильно позже мы поняли, что в ней есть фундаментальная подстава, о которой не пишут в hello word примерах блогеры, использующие таймер в качестве источника данных. Подстава в том, что средства коммуникации между источником и клиентом придется писать самим, а streamInsight предлагает фактически framework для создания срезов и агрегации данных. Тут человек спрашивает как данные-то скормить, и ему отвечают: напишите сами.

Изучение:

Приступаем к разработке…

Устройство сервера с SignalR Hub

Система коммуникации от IIS к клиентам в браузерe.

Веб интерфейс

UI у нас в целом готов, можно приступать к разработке на сервере.

Тестовый пример Workflow

Перейдем от того, что видет клиент, к тому что в backend работает- workflow service. Создадим простейший пример workflow(ну не production же копировать).

Пусть он будет получать сообщения, и отправлять ответ.

Наружу он виден так-же как wcf сервис.


Создадим к нему serviceProxy

будем вызывать его из тестового приложение, которое будет генерировать запросы к workflow.

Теперь у нас есть Workflow Service, и генератор запросов к нему.

Сбор данных

Внутри себя обработчик запросов к AppFabric — это Windows Workflow.
Работающий Workflow Instance генерирует и выстреливает события. По умолчанию есть 1 слушатель ETW (Event Tracing for Windows)). Он их обрабатывает и складывает в базу данных мониторинга appfabric.
Мы тоже хотим получать часть событий, отстреливаемых workflow.

Их можно получать 2 путями:

  • ходить руками в базу данных мониторинга
  • использовать Tracking Participant.

Вариант хождения в базу данных мониторинга хорош, но у него есть изъян: запросы создают нагрузку на базу, а чтобы получать информацию за некоторый короткий промежуток времени, нужно постоянно в эту базу посылать запросы. В итоге, мы будем генерировать паразитную нагрузку, которая может оказаться достаточно существенной.
Вариант Tracking Participant лучше в том смысле, что ему не нужна никакая база данных, чтобы эти события получать. Мы дальше можем их любым интересующим нас способом перенаправить туда, куда нужно.

Реализация Tracking Participant

Для этого нужно написать Tracking Participant, который будет приемником выстреливаемых событий.
Для реализации в коде tracking participant нужно реализовать 3 части:

  • BehaviorExtensionElement

  • IServiceBehavior

  • TrackingParticipan

После написания этого кода, необходимо

зарегистрировать это расширение в конфиге.

TrackingProfile

По умолчанию tracerecord генерируется достаточно много. Фильтровать данные в коде — это плохая идея, т.к. надо писать код проверок, да и это очистка от ненужных записей, всегда что-то можно пропустить. Лучше выбрать только интересующие нас записи. Это делается через TrackingProfile

В нем мы определяем query, в которых выбираем какие именно события мы хотим получать в tracking participant. Можно собирать события изменения состояния инстансов workflow, можно собирать на более низком уровне состояние активностей входящих в инстансе, можно фильтровать по именам активностей.

В этом примере мы создаем новый профиль, добавляем к нему query для получения событий workflow instance в состоянии started.

Таких запросов можно написать много. Данные мы собираем, теперь их нужно отстреливать в некоторое хранилище для обработки.

Вот пример получения активности по имени(в частности получение сообщения)

Как выбрать собираемые данные мы знаем. Пора уже связать интерфейс с источником данных через streamInsight

StreamInsight Server

Сам по себе StreamInsight сервер внутри несложен, тонкости начинаются при подключении входных потоков и создания из них выходных.

Вот пример консольного сервиса, который через себя связывает источник и приемник данных.

В целом, в коде ничего страшного: мы объявили wcf сервис для получения данных, signalr обертку для отправки данных в приложения для отображения.

Одна из основных фишек StreamInsight — это брать поток данных и нарезать этот поток на window. В нашем примере мы из потока данных сделали PointEvent. Т.к. каждое пришедшее из внешнего мира событие превращается в точку (есть время прихода, и входящий объект.). Приходящие сообщения формируют поток, и streaminsight нарезает этот поток на window, в нашем случаи используя Tumbling Window по 1 секунде. Все события пришедшие за секунду попадают в это окно.
Когда мы описали источник данных и потребителя, мы просто связываем это все в synk.

Есть еще 2 типа Event, и еще 3 типа окон. Нам для нашей задачи они оказались не нужны. Желающим понять глубже рекомендую прочесть >глоссарий из него все станет понятно.

Из нетривиального, стоит отметить CepOperator. Для того, чтобы создать окно событий из сложного объекта (не clr type), нам пришлось написать этот CepOperator.

Как это сделать


Как и написано в комментариях, у StreamInsight один костыль. Он не поддерживает вложенные в объект массивы.Из-за этого пришлось написать костыль и конвертировать массив в json строку, и затем из него десериализовать.
Теперь у нас ест все 3 части. Источник данных, сервер, UI.Осталось их связать между собой.

Общение между StremInsight Server и источником данных Workflow

В принципе, просто реализуется интерфейс IObservable.

Я взял пример по StreamInsight и сделал из него generic.

В итоге, на основе его далее строится wcf сервис.

Стартуем приложение и генерируем Proxy для нашего сервиса.

Подключаем со стороны StreamInsight Server wcf proxy как источник сообщений.

//определяем источник данных.
var observableWcfSource = app.DefineObservable(() => new WcfObservable(wcfSourceUrl, «WcfObservableService»));

Клиент работы с SignalRHub

В целом ничего сложного.
//определяем средство доставки данных клиентам.
var observableSink = app.DefineObserver(() => new SignalRObserver(signalRHubUrl));

Создаем подключение, цепляемся к Hub. Отправляем в него сообщение.

Результат

У нас есть Генератор запросов к Windows Workflow. WWF, который генерирует события, мы их ловим и передаем через WCF на StreamInsight Server. На Сервере мы агрегируем прилетающие события и пробрасываем их на SignalRHub на IIS и оттуда в browser. В браузере рисуем диаграмму.

Выглядит примерно так.

Нагрузочное тестирование

Первая попытка протестировать все была на машине разработчика: win7sp1. НЕ НАДО ТЕСТИРОВАТЬ НАГРУЗКУ НА МАШИНЕ РАЗРАБОТЧИКА. Серверная винда и клиентская сильно отличаются своими настройками. Клиентскую можно использовать как positive test, т.е. если даже на ней летает, то и на сервере должно быть хорошо. Обратное не значит вообще ничего.

Тестирование отдачи от signalr hub в browser

1000 запросов за 60 секунд с одного генератора запросов, в signalr hub, и просмотр в 1 вкладке браузера прошла успешно. Для нашего кейса 17 запросов в секунду в hub — это нормальная нагрузка.

Затем мы повторили эксперимент: 1000 запросов за 60 секунд, но при этом 10 открытых вкладок. И вот тут мы больно ударились: оказалось, что отправка сообщений начинает подтормаживать, при достижении 7 клиентских подключений просто останавливается. Мы подумали, почитали и решили перейти с win7 на winserver.
( “1.IIS/Cassini on Windows 7 has a default limit of 10 concurrent connections. Try running tests on Windows Server and see if it behaves the same. ”). После теста на winserver 2012 стало очевидно, что пора уже забить на win7 надо и тестироваться на схожей с production среде (это и раньше было очевидно, но тестишь по началу всегда на своей машине) на iis есть ограничение числа соединений, их конечно можно поднять, но лучше win server.

Результаты на windows server 2012 с 1 открытой вкладкой браузера:
150000 запросов за 576 секунд= 260 запросов в секунду, т.е. уже на порядок выше, чем на клиентской, а это тем более удовлетворяет нашим потребностям.
Затем провели эксперимент с 10 открытыми вкладками, и все работало. Единственное, что при таком потоке сообщений отображение на canvas в браузере подтормаживало, но это уже мелочи.

Вывод: используйте серверную ОС, для серверных задач. SignalRHub работает достаточно быстро, чтобы перемалывать огромную массу сообщений.

Тестирование отображения в браузере

При 260 сообщений в секунду, конечно, браузер не успевает все отрисовать нормально, но на 50 сообщений в секунду уже все хорошо. Сам браузер память отжирает медленно, так что на 150000 chrome процесс не сожрал более 110мб, с учетом, что все точки он хранил в памяти. В общем, будем считать, что даже удалять старые записи из массива не будем, ибо смысла в этом нет.

Тестирование через SoapUI

Мы написали тест планы для тестирования используя SoapUI.
На нем я смог положить WCF сервис, через который влетают данные, причем сделать это так, чтобы он сам уже не поднялся

Пример тест планов.

После разбирательства, было решено сделать метод PushEvent — OneWay. Потери событий небольшим допустимы, зато это привело к тому, что в сервис каждую секунду влетало 400событий в течении часа, и он работал на тех тестовых планах от SoapUI, которые раньше его убивали.

Дальнейшие изыскания

Я намеренно не стал описывать JS код мой, тк он требует доработки (нужно чтобы график умел работать в 2 режимах- осциллограф- когда данные ограничены промежутком времени, и сейсмограф- сколько собрал, все показать.). Если будет интерес, напишу отдельно.

ссылка на оригинал статьи http://habrahabr.ru/post/215097/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *