- PVSM.RU - https://www.pvsm.ru -
У нас есть Workflow сервис, выполняющий некоторый процесс и сейчас нет средства Real-Time мониторинга этого сервиса.
Расширение AppFabric к IIS показывает кумулятивную информацию о количестве инстансов за период, но чтобы видеть последнюю информацию, нужно постоянно жать руками на обновление. Так же нельзя сравнить количество инстансов в периоде.
Можно снять данные с Monitoring Database — это решение опять же завязано на AppFabric, также получение последних изменений в real-time сложно (нужно делать регулярные запросы и т.д. и т.п.)
Нужно придумать способ узнавать информацию о некотором наборе метрик в виде диаграмм на chart с постоянным обновлением текущего состояния.

Все кто предварительно читать статью, задавали один и тот же вопрос- для кого все это сделано.
Ответ- в случаи просадки производительности, которая началась и еще не закончилась- этот инструмент как раз и показывает состояние части системы. Зная нормальные значения, можно увидеть что они не в порядке, или происходят какие-либо всплески. Фактически- это инструмент мониторинга работающего сервера ведь.
Выбор был по большом счету предопределен: когда есть решение рекомендованное вендором платформы (SignalR от Microsoft), то все остальные почти всегда идут лесом. Для очистки совести (и самообразования) было проведено изучение еще одной библиотеки, которую смогли нагуглить — Xsocket.
На сайте Xsocket [1] есть сравнение [2]. Там достаточно много параметров. Каждый вендор свое болото хвалит, как известно. Я выбрал несколько ключевых параметров по которым отвалился xsocket.
Я не готов брать проект не вендора и при этом не видно, чем он принципиально лучше. SignalR более популярна и решает поставленную задачу.
Библиотека для отображения графиков была выбрана canvasjs [3]. Причина выбора проста: Google выдал ее по запросу «rea ltime chart js library». В течение часа разбора по этому вопросу было принято решение: не тратить время на изучение альтернатив, если уже это нам подходит. Библиотека работает и с Chrome и с IE9+. Значит, подходит.
StreamInsight — рекомендованная Microsoft платформа для реализации системы мониторинга.
Цитата [5]:
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.
Изучение:
Приступаем к разработке…


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




Теперь у нас есть Workflow Service, и генератор запросов к нему.
Внутри себя обработчик запросов к AppFabric — это Windows Workflow.
Работающий Workflow Instance генерирует и выстреливает события. По умолчанию есть 1 слушатель ETW (Event Tracing for Windows) [12]). Он их обрабатывает и складывает в базу данных мониторинга appfabric.
Мы тоже хотим получать часть событий, отстреливаемых workflow.
Их можно получать 2 путями:
Вариант хождения в базу данных мониторинга хорош, но у него есть изъян: запросы создают нагрузку на базу, а чтобы получать информацию за некоторый короткий промежуток времени, нужно постоянно в эту базу посылать запросы. В итоге, мы будем генерировать паразитную нагрузку, которая может оказаться достаточно существенной.
Вариант Tracking Participant лучше в том смысле, что ему не нужна никакая база данных, чтобы эти события получать. Мы дальше можем их любым интересующим нас способом перенаправить туда, куда нужно.
Для этого нужно написать Tracking Participant [13], который будет приемником выстреливаемых событий.
Для реализации в коде tracking participant нужно реализовать 3 части:



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

По умолчанию tracerecord генерируется достаточно много. Фильтровать данные в коде — это плохая идея, т.к. надо писать код проверок, да и это очистка от ненужных записей, всегда что-то можно пропустить. Лучше выбрать только интересующие нас записи. Это делается через TrackingProfile [14]
В нем мы определяем query, в которых выбираем какие именно события мы хотим получать в tracking participant. Можно собирать события изменения состояния инстансов workflow, можно собирать на более низком уровне состояние активностей входящих в инстансе, можно фильтровать по именам активностей.

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

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

В целом, в коде ничего страшного: мы объявили wcf сервис для получения данных, signalr обертку для отправки данных в приложения для отображения.
Одна из основных фишек StreamInsight — это брать поток данных и нарезать этот поток на window. В нашем примере мы из потока данных сделали PointEvent. Т.к. каждое пришедшее из внешнего мира событие превращается в точку (есть время прихода, и входящий объект.). Приходящие сообщения формируют поток, и streaminsight нарезает этот поток на window, в нашем случаи используя Tumbling Window по 1 секунде. Все события пришедшие за секунду попадают в это окно.
Когда мы описали источник данных и потребителя, мы просто связываем это все в synk.
Есть еще 2 типа Event, и еще 3 типа окон. Нам для нашей задачи они оказались не нужны. Желающим понять глубже рекомендую прочесть >глоссарий [10] из него все станет понятно.
Из нетривиального, стоит отметить CepOperator. Для того, чтобы создать окно событий из сложного объекта (не clr type), нам пришлось написать этот CepOperator [15].


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


В итоге, на основе его далее строится wcf сервис.
Подключаем со стороны StreamInsight Server wcf proxy как источник сообщений.
//определяем источник данных.
var observableWcfSource = app.DefineObservable(() => new WcfObservable(wcfSourceUrl, «WcfObservableService»));
В целом ничего сложного.
//определяем средство доставки данных клиентам.
var observableSink = app.DefineObserver(() => new SignalRObserver(signalRHubUrl));

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

Первая попытка протестировать все была на машине разработчика: win7sp1. НЕ НАДО ТЕСТИРОВАТЬ НАГРУЗКУ НА МАШИНЕ РАЗРАБОТЧИКА. Серверная винда и клиентская сильно отличаются своими настройками. Клиентскую можно использовать как positive test, т.е. если даже на ней летает, то и на сервере должно быть хорошо. Обратное не значит вообще ничего.
1000 запросов за 60 секунд с одного генератора запросов, в signalr hub, и просмотр в 1 вкладке браузера прошла успешно. Для нашего кейса 17 запросов в секунду в hub — это нормальная нагрузка.
Затем мы повторили эксперимент: 1000 запросов за 60 секунд, но при этом 10 открытых вкладок. И вот тут мы больно ударились: оказалось, что отправка сообщений начинает подтормаживать, при достижении 7 клиентских подключений просто останавливается. Мы подумали, почитали [17]и решили перейти с 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.
На нем я смог положить WCF сервис, через который влетают данные, причем сделать это так, чтобы он сам уже не поднялся
После разбирательства, было решено сделать метод PushEvent — OneWay. Потери событий небольшим допустимы, зато это привело к тому, что в сервис каждую секунду влетало 400событий в течении часа, и он работал на тех тестовых планах от SoapUI, которые раньше его убивали.
Я намеренно не стал описывать JS код мой, тк он требует доработки (нужно чтобы график умел работать в 2 режимах- осциллограф- когда данные ограничены промежутком времени, и сейсмограф- сколько собрал, все показать.). Если будет интерес, напишу отдельно.
Автор: SychevIgor
Источник [18]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/news/56965
Ссылки в тексте:
[1] Xsocket: http://xsockets.net/
[2] сравнение: http://xsockets.net/xsockets-vs-signalr
[3] canvasjs : http://canvasjs.com/
[4] ссылка: http://canvasjs.com/editor/?id=http://canvasjs.com/example/gallery/dynamic/multiseries_line/
[5] Цитата: http://msdn.microsoft.com/en-us/library/ee391416(v=sql.111)
[6] Тут : http://social.msdn.microsoft.com/Forums/sqlserver/en-US/0bc5f213-1c54-4e92-8590-e161ce29509e/streaminsight-how-does-the-client-get-the-data-from-the-streaminsight-server?forum=streaminsight
[7] Стартовая страница на Microsoft.com : https://www.microsoft.com/en-us/sqlserver/solutions-technologies/business-intelligence/streaming-data.aspx
[8] Блог команды: http://blogs.msdn.com/b/streaminsight/
[9] Stream Insight examples: http://streaminsight.codeplex.com/releases
[10] Глоссарий : http://technet.microsoft.com/en-us/library/ee378962(v=sql.105).aspx
[11] Видеокурс: http://pluralsight.com/training/courses/TableOfContents?courseName=streaminsight
[12] ETW (Event Tracing for Windows): http://msdn.microsoft.com/en-us/library/windows/desktop/bb968803(v=vs.85).aspx
[13] Tracking Participant: http://msdn.microsoft.com/en-us/library/ee513993(v=vs.110).aspx
[14] TrackingProfile: http://msdn.microsoft.com/en-us/library/ee513989(v=vs.110).aspx
[15] CepOperator: http://technet.microsoft.com/en-us/library/ee842720.aspx
[16] Он не поддерживает вложенные в объект массивы: http://technet.microsoft.com/en-us/library/ee378905.aspx
[17] почитали : http://stackoverflow.com/questions/10426163/when-signalr-made-8-10-connections-at-a-time-live-chat-doesnt-work у win7
[18] Источник: http://habrahabr.ru/post/215097/
Нажмите здесь для печати.