Описание на проектa

Преди години работих по интеграцията на Microsoft Dynamics CRM Online в голяма международна компания в сферата на retail бизнеса. CRM-a трябваше да бъде интегриран с Resco Mobile CRM, тъй като клиентът целеше да обучи търговците си да използват мобилни системи за продажби, а в последствие тези две системи бяха интегрирани и с облака на Microsoft, под формата на интеграция с ASP WebAPI услуга качена в Azure WebApps. Допълнително проектът включваше показване на справки на базата на над един милион записи.

С други думи проектът включваше интеграция на три от четирите движещи иновативни сили на Nexus of Forces.

Интеграцията с Azure WebApps бе съществена в реализирането на проекта, тъй като реши ключов проблем с един от бизнес процесите на клиента, който ще опиша по долу.

Дефиниция на проблема – от софтуерна гледна точка

Или защо избрахме да използваме Microsoft Azure WebApps?

Тук искам да вметна няколко неща за добрите практики, преди да се впусна да обяснявам техническите предизвикателства с които се сблъскахме.

Според Microsoft, най-добрата методология за внедряване на Microsoft Dynamics CRM проекти е Microsoft Sure Step методологията.

Тази методология включва редица етапи, които могат да се видят на по-горната картинка, като оцветени стъпки на процеса на внедряване на Dynamics CRM.

Процесът анализ е един от най-важните стъпки при внедряване на Dynamics CRM проект, а и при разработване на софтуерен продукт като цяло, като този процес включва анализ както на бизнес изисквания, така и специфичен анализ наречен Fit-Gap анализ. Или с други по-прости думи, какво може да бъде реализирано с Dynamics CRM системата (Fit) и какво не може поради различни видове ограничения (Gap).

И докато редица консултантски фирми в България пропускат този процес или извършват единствено бизнес анализ, подценявайки или понякога пропускайки техническия анализ, този анализ е ключов за големи и сложни проекти и пропускането му може да доведе до сериозни забавяния на внедряването на проекта, причинени от непредвидени технически изисквания.

Или както може да се види на картинката по-долу позната на редица проектови мениджъри, увеличаването на scope-a (изискванията на проекта), неминуемо води до увеличаване на цената на този проект и до увеличаване на времето за което проектът бива реализиран.

С други думи – не подценявайте нуждата от технически анализ. В конкретния проект поради опити да спестим време и пари, бе решено да прескочим този анализ, което в последствие увеличи същото време и пари необходими за внедряване на проекта.

И ето отговорът на въпроса „Защо избрахме да използваме Microsoft Azure WebApps?“:

Защото Dynamics CRM Online не можеше да реализира една от автоматизациите изисквани от клиента.

На една от първите срещи по проекта, клиентът ни поиска да реализираме автоматично генериране на график за всичките му търговци за един месец напред. На базата на ексел файлове, които клиентът ни предостави, разбрахме че става дума за между няколко стотин хиляди до над един милион записа за посещения и задачи, които търговците изпълняват, когато отидат на посещение в тъговски обект.

Тази автоматизация трябваше да се изпълни като еднократен продължителен процес на генериране на график и можеше да се стартира в произволен ден от месеца от CRM администратора от страна на клиента.

Нека сега да погледнем възможностите за доработки, които Dynamics CRM предлага, за да разберем защо тази автоматизация, не бе възможна за реализация с този продукт.

На картинката са показани различните видове методи за доработка и API-та използвани от Dynamics CRM. Ще разгледаме тези, които касаят проекта:

  • Plugin-и – .NET асемблита, които могат да бъдат разработени със C# и да изпълняват определена логика, на базата на дефинирани в CRM събития (създаване на запис, промяна на запис и т.н.).
  • Workflow-ли – автоматизирани процеси, които могат или да бъдат разработени със C# или създадени ръчно използвайки потребителския интерфейс на CRM, от хора без опит в програмирането, като бизнес консултанти. Също се изпълняват при определени събития и промени по записи.
  • JavaScript библиотеки – изпълняват се при определени събития, при промяна на CRM формите (страниците видими за потребителя).
  • REST API – API за достъп до Dynamics CRM. Използва се предимно за извършване на CRUD операции (създаване, четене, промяна и изтриване на записи).

За всеки, който проявява интерес, към Dynamics CRM разработката, нека да си свали Dynamics CRM SDK-то или както много CRM архитекти с които съм говорил, го наричат – „Библията на CRM”, тъй като там има примери за почти всички видове доработка, които могат да се направят с Dynamics CRM.

Примерен код на plug-in създаващ задача в Dynamics CRM:

До тук добре. Имаме различни методи по-които на теория бихме могли да реализираме автоматизацията на генериране на график в Dynamics CRM Online:

  • Да я реализираме като JavaScript логика. Това може да доведе до особенно неприятен user experience, понеже говорим за създаване в определени случаи на над милион записа.
  • Да я реализираме, чрез plug-in, изпълняващ се при създаване на нов обект в CRM, примерно обект от тип „график“.

Обаче, както споменах, реализирането на тази автоматизация за генериране на график в Dynamics CRM Online e невъзможна и то поради следните причини:

Dynamics CRM Online e силно орязана и ограничена версия на предишния продукт на Microsoft – Dynamics CRM On-premise, който се инсталира на клиентски сървър. Ограниченията които касаеха този проект и бяхме пропуснали да анализираме в началото са следните:

  • Всеки plug-in разполага с 2 минути за да приключи изпълнението на логиката, която стои зад него, след което от съобръжения за сигурност, CRM Online приключва изпълнението му принудително. Т.е. не можем да реализираме тази автоматизация с plug-in-и.
  • CRM Online забранява достъпа до базата на CRM. Единственото което потребителят може да направи е да се свърже с администраторите, които може да му направят копие на текущата версия на базата, но няма директен достъп за да прави промени по базата. Единствените промени, които са възможни, са чрез потребителския интерфейс на CRM, с който могат да се добавят нови обекти и полета в тях.
  • SQL репортите в CRM Online са забранени поради опасност от SQL Injection и единствените позволени репорти са тези написани на fetchXML. Допълнително CRM Online приключва изпълнението на всеки репорт, който се изпълнява за повече от 5 минути принудително. С други думи – CRM Online не се препоръчва за репортинг цели.

Пример за fetchXML справка, за клиенти управлявани от потребител с фамилия Канон:

На базата на тези ограничения, с екипа решихме, че добър вариант за реализиране на тази автоматизация е написване на външна услуга. Поради ограничения на ресурсите с които разполагахме по този проект се реши, че услугата няма да бъде качена на фирмения сървър, а ще се качи в Microsoft Azure WebApps, а и така беше по-добре от гледна точка на консистентност – облaчен CRM с облачна услуга. Съответно нямаше да има и downtime, ако имаше проблеми с фирмения сървър.

Услугата щеше да се извиква от JavaScript при натискане на бутон „Прегенериране на график“ в обекта „график“, който ние щяхме да създадем в CRM.

Нека сега погледнем каква беше бизнес логиката стояща зад тази автоматизация и да разгледаме останалата част от нея, която реализирахме в Dynamics CRM Online.

Дефиниция на проблема – от бизнес гледна точка

Както споменах, по горе, клиентът ни бе голяма международна компания в сферата на retail бизнеса. Той разполагаше с няколко офиса в различни страни най-големи от които бяха българският и американският. В българския офис, за него работеха над сто търговеца, които всеки месец трябваше да посещават над сто различни обекта и да изпълняват определени задачи като презентации, демонстрации на продукти, раздаване на маркетингови материали и разбира се и мобилни продажби.

От нас като внедрител на CRM се искаше да им автоматизираме процеса на генериране на месечен график.

С насмешка бих казал, че методът им на генериране на график бе меко казано „интересен“, тъй като напомняше на някои от онези задачи от математическия фолклор.

Според графика им, за даден търговец обектите се деляха на четири вида:

  • Обекти, които посещава веднъж седмично
  • Обекти, които посещава веднъж на две седмици
  • Обекти, които посещава веднъж на три седмици
  • Обекти, които посещава веднъж месечно

В зависимост от обектите имаше и динамично генериране на задачи за търговеца, които той трябва да изпълни при посещение на обект, тъй като някои от обектите бяха нови клиенти за клиента ни и съответно първите им задачи бяха презентации и демонстрации преди да се стигне до продажби.

Както може да се види ориентировачно на горната снимка, бизнесът на клиента бе реализиран в Dynamics CRM Online под формата на различни обекти:

  • Акаунти – това са обектите, които търговците им посещават.
  • Мобилни потребители – това са тъговците, които посещават обектите.
  • Appointment-и или посещения – посещенията на търговците в определени обекти.
  • Tasks или задачи – задачите, които трябва да се изпълнят при определено посещение.
  • Users или Dynamics CRM потребители – 1 потребител за мобилни цели и няколко потребители занимаващи се с административни цели, сред които бях и аз, като консултант разработващ и интегриращ CRM проекта.

Тук трябва да вметна, че Resco Mobile CRM, като едно от най-добрите мобилни приложения за CRM позволяваше до скоро, да се използва линценз за един един единствен потребител в Dynamics CRM, чрез който над 100 мобилни потребителя получават достъп до системата и да я използват.

Да се върнем на генерирането на график. Тъй като се искаше да генерираме месечен график, веднага изкочиха няколко въпроса:

  • В края на месеца ли генерираме този график?
  • Ами какво ако краят на месеца, е средата на седмицата?
  • В този случай генерираме ли нов график от средата на седмицата?
  • Или пък генерираме график започвайки от края на последната цяла седмица в дадения месец?

След обсъждане с клиента, и тъй като клиентът нямаше конкретен ден от месеца в който да предоставя новия месечен график на търговците, решихме че график ще бъде генериран от избран динамично от тях ден, до края на текущия месец и за целия следващ месец. Т.е. в най- специфичния случай, график ще бъде генериран за близо два месеца, ако генерирането бъде осъществено в началото на текущия месец.

Но истинският проблем не беше самото генериране, а голямото количество записи, които трябваше да се създадът в Dynamics CRM при автоматично генериране на такъв график.

Както споменах по-горе при дефинирането на проблема от софтуерна гледна точка, целта беше автоматизацията да се извърши еднократно, което за голям брой записи означаваше продъжителен и времеемък процес.

Нека предположим, че имаме 100 търговеца, които посещават по 100 обекта за един месец и изпълняват по 10 задачи на обект (въпреки, че задачите са по-малко, броят обекти за месец и броят търговци са повече, което балансира дадения пример), то имаме 10 000 генерирани записа за посещения в конкретни обекти и 100 000 генерирани записа за задачи, които трябва да бъдат изпълнени в обектите.

Реално, автоматизираното генериране на график, създаваше над 400 000 записа за двата месеца, а тук говорим само за българския офис. Идеята на клиента бе в последствие да използваме предложеното от нас решение, за автоматично генериране на график и в другите им офиси в чужбина, което можеше да означава над един милион записа, които трябва да се генерират в рамките на една вечер, така че на другия ден графикът на търговците да е обновен и да не се повлиява отрицателно работата им, заради тази автоматизация.

Но това разбира се, не беше всичко. В процесът на работа, установихме че за целта на добър репортинг в Dynamics CRM Online изграден на базата на тези посещения и позволяващ рязане на тези милион записи според различни KPI-и, трябваше да създаваме или да модифицираме специален тип записи, които ние сами създадохме в CRM, включващи най-общо следните данни:

  • Търговец
  • Обект, който посещава
  • Задача, която извършва
  • Други конкретни данни необходими ни за даден репорт

Този обект играеше ролята на SQL View в CRM и бе ключов за бързото и ефективно изпълнение на репортите в Dynamics CRM Online.

Т.е. в най-специфичния случай, при едно автоматично генериране на график можеше да имаме създаване или модифициране на над 800 000 записа и то само за българския офис. 400 000 записа за посещения и задачи и още толкова за обобщени данни използвани за репортинг.

Ключови показатели за ефективност. Това е система за оценяване, която помага на организацията да определи степента на достигане на своите стратегически и тактически цели. Използването на KPI дава възможност да се контролира бизнес активността на сътрудниците и на компанията като цяло в реално време. 

Допълнително с цел улесняване на автоматизацията бяхме създали и обекти на базата на които генерирахме графика, включващи следните детайли:

  • Обект
  • Търговец
  • Честота на посещение (веднъж седмично, веднъж на две седмици и т.н.)
  • Задача

Най-общо стъпките по-които генерирахме график бяха следните:

  • Изтриваме стария график от днешна дата, нататък до края на следващия месец
  • Прочитаме всички обекти на базата на които генерираме новия график
  • Създаваме график за всички тези обекти циклично до достигане на края на следващия месец.

Избор на подходящ инструмент в Azure и подходящ ценови план

Избрах Azure WebApps, тъй като съм го използвал по малки проекти преди, а и първоначалната ни идея бе да свържем услугата с базата на облачния CRM преди да установим ограничението за достъпа до базата.

Тук може да се види документацията за качване на услуга в Azure WebApps, свързана с SQL Azure база данни.

Сега трябваше да изберем и ценовия планът, който да използваме за тази Azure услуга. Предвид, че новите непредвидени технически детайли (и непредвидени разходи) бяха в процес на обсъждане с клиента, решихме да проверим възможностите на Free ценовия план.

Избор на Free ценови план на App Service

Тук може да се разгледат, най-общо възможностите и някои от ограниченията на различните ценови планове за App Service (върху която стои Azure WebApps).

Хубаво е да се знае, че Free планът е предназначен предимно за тестови цели, а не за продукционни цели. Аз лично не бих го използвал дори за малки проекти.

При тестването на този план, установихме че услугата извършваща автоматизираното генериране на график, написана като ASP.NET WebAPI услуга, се изпълнява за до около 5 минути, след което спира без да даде някакви грешки, като процесът на генериране на график е недовършен.

Какво точно стана?

След четене на не малък брой статии и използвайки monitoring инструментът на App Service, достъпен в портала на Azure, за който прочетох в една от статиите, установих, че един от ресурсите на App Service e изтекъл. В зависимост от ценовият план на App Service тези ресурси може да варират. Тук може да се разгледа monitoring инструментът на Azure и детайли по ресурсите, които може да се очетат с него.

Ресурсът, който беше изтекъл бе CPU time (short) – който се ресетва на всеки 5 минути.

Подобно на тази картинка, при мен CPU time (Short) бе изцяло сив – т.е. изчерпан.

Избор на Shared ценови план на App Service

Предвид, че генерирането на между няколко стотин хиляди до над 1 милион записа бе времеемко, изключихме възможността с Free планът. Насочихме се към следващия, този път платен ценови план – Shared.

На един Azure Bootcamp с приятели взехме няколко ваучера за тестване на Microsoft Azure в рамките на 100$ ценови разходи. Реших да споделя един от тези ваучери с екипа, предвид, че все още не се бяхме договорили с клиента за конкретен план.

Използвайки този ваучер, започнахме да тестваме как работи услугата с Shared плана.

Този път услугата се изпълняваше между 40 минути и час, но отново спираше без да даде грешка и без да генерира всички записи от графика. Този път Azure monitoring инструментът не даде конкретна информация за изчерпан ресурс.

Подобно на тази картинка, започнах да използвам Metric инструментът на Azure, за да следя изпълнението на услугата. След около 40 минути до час, услугата се изпълняваше успешно, след което се отчитаха Http Server Errors. Тъй като нямах достатъчно информация за на какво може да се дължи проблемът, реших да предприема следващата стъпка.

Трябваше да диагностицирам и изследвам изпълнението на услугата с помощта на Visual Studio.

Диагностициране на App Service услуга с помощта на Visual Studio и Azure Application Insights

Докато търсих информация за възможни проблеми с услуги в Azure App Service, прочетох, че Azure Application Insights е добър инструмент за диагностициране на проблеми в услуги качени в App Service и позволява real-time дебъгване и анализиране на услугите.

Тук може да се прочете детайлно, как може да се свържем с Azure App Service услуга използвайки Visual Studio и Application Insights:

https://docs.microsoft.com/en-us/azure/application-insights/app-insights-visual-studio

https://docs.microsoft.com/en-us/azure/application-insights/quick-monitor-portal

Използвайки този инструмент забелязах, че услугата ни има голям брой входящи и изходящи request-и. Предположих, че при изпълнение на услугата изтича ограничението ни за входящи и изходящи request-и.

Това беше така, тъй като когато я разработвах, с колегите бяхме решили, тя да се извиква при създаване на посещение за конкретен търговец. Plug-in изпълняващ се при създаване на обект от тип „график“ щеше да създаде посещенията за всички търговци (от 10 000 до няколко десетки хиляди записа), а услугата (част от друг plug-in) щеше да създава само задачите, за конкретно посещение.

Не разполагахме с време да пренапишем и тестваме наново услугата. Решихме да изберем следващия ценови план.

Избор на Shared ценови план на App Service

Използвайки Shared ценовия план, този път услугата разполагаше с достатъчно ресурси, за да се изпълнява между 1 и 2 часа, но графикът макар и генериран на около 80%, не бе генериран изцяло отново. А ние разбира се целяхме, 100% успешно генериран и верен график.

Този път, клиентът не беше готов на компромиси за ресурсите, въпреки сложността на услугата и трябваше да решим проблема по друг начин.

Инструментите за диагностика на Azure, макар и значително добри и детайлни, не можаха да дадат конкретен отговор, кой ресурс се изчерпва отново. Трябваше да работим с ресурсите с които разполагаме и да генерираме графика с тях.

След оптимизации по услугата, в някои случай графикът се генерираше на 100% в рамките на 2 часа, но в други не, а ние държахме на стабилен автоматизиран процес.

Трябваше ни друго решение.

Реализиран автоматизиран процес на генериране на график, чрез App Service

Една вечер след латино танци и 1-2 бири ми дойде идеята. Рекурсия.

Трябваше да променим процесът по такъв начин, че дори да не се изпълни на 100%, да се стартира отново и да се изпълни за останалите обекти и търговци за които не е успял да генерира график.

Ето описание на промените на процеса, който измислих на базата на Azure App Service услугата и възможностите за доработка на CRM Online с които разполагахме.

  • При натискане на бутон „Прегенериране на график“ в обект „график“ се случват 2 неща. Извикване на App Service услугата с помощта на JavaScript. Извикване на Workflow в CRM Online с timeout от 2 часа.

Тъй като имахме и успешни опити за генериране на график с услугата и знаехме, че в рамките на 2 часа, графикът или се генерира или не, беше достатъчно да стартираме процес, който след 2 часа щеше да провери дали услугата се е изпълнила успешно и ако не щеше да я стартира наново.

  • Добавихме флагове „Изпълнил се успешно“ на обект график и на междинните обекти съдържащи информация за обектът който се посещава, честотата на посещение, търговецът който го посещава и задачата която се изпълнява, като тези междинни обекти ги споменах в началото на тази статия.
  • При стартиране на прегенерирането, тези флагове се нулират. При изпълнение на услугата те почват, лека по-лека да се маркират като „изпълнени“.
  • В моментът в който услугата спре и Workflow-ът я стартира наново се проверява, за кои търговци и обекти няма генерирани посещения и задачи на базата на тези флагове и услугата почва да се изпълнява наново единствено за тях.

Чрез този процес на изпълнение, услугата се изпълняваше 2 пъти, най-много 3 пъти и графикът бе генериран на 100% успешно и вярно.

Допълнително репортинг обектът, който споменах в началото, играещ ролята на SQL View направи репортите на базата на генерирания график изпълними, тъй като репортите написани на fetchXML не позволяваха join на таблици използвайки fetchXML, а се използваха сравнително бавни методи за join, така наречените data set-ове, обединението на които водеше до визуализиране на нужните данни.

Затова изпълнението на fetchXML репорт теглещ данни от множество таблици се изпълняваше бавно надвишавайки ограничението от 5 минути поставено от CRM Online, докато нашият SQL View обект, позволяваше теглене и визуализиране на обобщените данни в рамките на тези 5 пет минути.

Говорил съм с CRM архитекити от България и чужбина и за жалост, това е единственото познато решение на този проблем на CRM Online. Естествено Microsoft предоставят и един много добър инструмент за репортинг – Power BI, и интеграцията между CRM и Power BI би могла значително да подобри репортинг възможностите на CRM Online.

Заключение

Генерирането на автоматизиран график бе най-ключовото изискване на клиента и реализирайки го с помощта на Azure App Service, в частност WebApps успяхме да си спечелим дългогодишен клиент. В последствие решението бе имплементирано и в останалите офиси на клиента.

В наши дни Azure облакът е може би най-добрият облак от гледна точна на големия брой предлагани услуги, както може да се види от тази картинка.

Говорейки си с един от Microsoft Azure евангелистите, дошъл от Германия на събитие тук и двамата бяхме съгласни, че Microsoft са вече много по-отворени към Open Source проекти и интеграцията им с Azure също е сравнително лесна.

Microsoft Azure e особенно мощен облак и някой който умее да си разпределя ресурсите може да го използва за да реализира сравнително сложни решения.

А ако нещо не сработи, не забравяйте – оптимизирайте приложенията си и потърсете алтернативни методи за работа с Azure услугите, както ние направихме.


Автор:
Евгени Дюлгеров

>>> Работи като Senior .NET Developer – Contractor в KPMG ITS, като официалното му работно място е в ScaleFocus;
>>>>>> Завършил  е бакалавър „Компютърни системи и технологии“ в ТУ-София, и в момента завършва магистратура „Управление на ресурси в предприятията“ в английския факултет на ТУ-София.
>>> Хобитата му са плуване, латино танци, играене на футбол на маса.
>>> Интересите му също са разнообразни – писане на проекти с нови технологии, разработка на freelance проекти през свободното време.

 


Стани част от потребителските групи на DEV.BG. Абонирай се и ще ти изпращаме информация за всичко, което предстои в групата.

Прочети още:
„При .NET фокусът е върху създаване на среда, където лесно можеш да бъдеш продуктивен за кратко време” – Валентин Бонев
Мартин Гебов: „Намирам стимул най-вече в предизвикателствата“

Share This