Повесть про микросервисы, масштабирование и энтерпрайз в сфере управления зарядками (много текста)

Давайте знакомиться!

Меня зовут Михаил, я сооснователь, архитектор и бэкенд разработчик в ev2go

Повесть про микросервисы, масштабирование и энтерпрайз в сфере управления зарядками (много текста)

Немного о проекте ev2Go

Мы предоставляем линейку решений для управления зарядной инфраструктурой:

  • решение для менеджмента и монетизации зарядных станций (поставляется как в виде облачного сервиса, так и в виде on-premise решения на мощностях заказчика);
  • white-label мобильное приложение;
  • решение для роуминга;
  • решение для анализа и таргетирования тарифов.

Несколько лет назад мы начинали как пет-проект в свободное от работы время. На момент написания статьи у нас 4 крупных и несколько небольших клиентов в России, СНГ, Восточной Европе, Индии и США. К системе подключено более 150 быстрых станций наших клиентов и еще около 350 обслуживается в режиме роуминга. Текущая нагрузка на систему составляет 200-400 рпс в зависимости от времени суток и активности клиентов.

Повесть про микросервисы, масштабирование и энтерпрайз в сфере управления зарядками (много текста)

Мы предоставляем полный цикл поддержки, в том числе помогаем решать наиболее сложные проблемы, связанные с особенностями использования оборудования от различных вендоров. Уделяем большое внимание мониторингу состояния сети, анализиурем и предсказываем проблемы с оборудованием, изучаем возможности применения AI для проактивного выявления нештатных ситуации.

🤡🤡🤡 После небольшой саморекламы 🤡🤡🤡

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

Далее пошли по пути классического неправильного стартапа. Нарушили все принципы, о которых пишут стартап-руководства и говорят инвесторы. Разрабатывали систему, не имея инвестирования и клиентов, делали тщательно "на века" вместо быстрой проверки гипотез, сосредоточились на разработке фич, а не на бизнесе, продажах и поиске инвесторов.

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

С выбором стэка долго не мучились, т к решили использовать богатые наработки на golang из предыдущих проектов. Это позволило нам запустить первое работоспособное и при том вполне надежное решение в течение нескольких месяцев.

Начали с реализации стандартного протокола обмена между зарядной станцией и бэкендом (OCPP 1.6). В качестве базы использовали форк одной из существующих опенсорсных библиотек на golang. В процессе работы над проектом мы неодноратно вносили изменения и исправляли баги внутри реализации протокола, но в конечном итоге это нам сэкономило значительное время по сравнению с разработкои протокола с нуля. Кроме того, из коробки мы получили сразу реализацию наиболее популярных версии OCPP 1.6 и 2.0.1. Стоит упомянуть, что реализация протокола - это лишь малая часть функционала системы. Наибольшие сложности вызвала тарификационная модель и обработка многообразия различных сценариев, связанных с особенностями поведения оборудования от разных вендоров.

Очевидно, для разработки системы, основой которой является взаимодействие с оборудованием, просто необходим полнофункциональный эмулятор (виртуальная зарядная станция). Эта задача оказалась непростой и потребовала некоторого времени в момент старта проекта, но в результате позволила построить развитую инфраструктуру для разработки и запуска интеграционных тестов. В данный момент стабильность системы гарантируется непрерывным запуском порядка 300 интеграционных тестов, имитирующих различные варианты процессов и поведения оборудования от различных вендоров. Могу смело утверждать, что именно ставка на интеграционные тесты и эмуляцию зарядных станции с большим количеством автоматизируемых сценариев и особенностей вендоров позволили нам спокойно спать после запуска. У нас появилась возможность развивать функционал системы, а не устранять бесконечный поток багов.

Важным решением было взять за основу тарифного движка правила и модель OCPI- протокола роуминга.

Повесть про микросервисы, масштабирование и энтерпрайз в сфере управления зарядками (много текста)

Об особенностях роуминга и OCPI протокола читайте в наших предыдущих статьях: техническая и менеджерская.

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

Следует отметить, что большинство игроков на рынке пошли противоположным путем, реализовав сначала самую простую модель (рассчет тарифа от стоимости кВт*ч, кстати так и работают по сей день). Мы же приняли мужественное решение потратить время, но поддержать всю сложность тарификации, чтобы потом к этому не возвращаться. В результате мы получили тарифный калькулятор, полностью соответствующий протоколу OCPI:

  • тарификация энергии, времени и фиксированных платежеи;

  • минимальные и максимальные значения тарифов;

  • тарификация каждого meter-value отдельно и возможность применения различных правил в рамках однои транзакции;

  • историчность тарифов;

  • полный набор метрик;

  • расчет налогов по различным правилам;

  • возможность производить рассчет тарифа на основе внешних данных.
Повесть про микросервисы, масштабирование и энтерпрайз в сфере управления зарядками (много текста)

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

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

  • поведение оборудования;
  • особенности визуального отображения станции;

  • параметры биллинга;

  • выполнять тонкий тьюнинг бэкграунд процессов.

Любои облачный сервис должен заботиться о сохранности персональных данных конечных пользователеи (в нашем случае владельцев EV). Здесь мы столкнулись с новыми вводными, о которых ранее не задумывались. Кому принадлежит клиент, если он заряжается на станциях нескольких наших партнеров? А что если партнер хочет видеть в своем приложении только своих клиентов? А что если партнер хочет видеть в своем приложении определенных клиентов? А что делать с роумингом?

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

  • для каждого владельца зарядной сети мы настраиваем режим видимости: вижу только своих клиентов, вижу всех клиентов, вижу клиентов указанных партнеров;

  • принадлежность клиента к владельцу сети определяется либо по наличию зарядных сессии, либо по привязанным RFID картам;

  • допустимость операций в рамках роуминга также конфигурируется для каждого партнера.

Имея богатыи опыт в автоматизации финансовой сферы мы заложили гибкую модель биллинга на основе счетов и платежных поручений. Реализовали наиболее популярные в России платежные методы и предусмотрели возможность подключения дополнительных методов в короткие сроки. Также мы заложили возможность конфиграции методов оплаты для каждого партнера и допустимость агентской схемы при приеме платежеи. В текущий момент работаем над реализацией мотивационных программ.

Не обошлось и без досадных проблем, о которых тоже хочется рассказать. Вот одна из них... В основе нашей бизнес-модели заложена возможность собирать деньги за оказание услуги зарядки с владельцев электрокаров через мобильное приложение. Мы не могли и представить, насколько окажутся изобретательны люди, дабы избежать оплаты по своим счетам. Например, один смышленный владелец "электрички" пытался заглушить сигналы GPRS с целью блокировать передачу данных от станции к серверу. Другие - постоянно регистрировались с новых телефонных номеров после появления минуса на балансе (тут написано про то, как мы заблуждались в должниках).

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

Помню довольно тревожный момент, когда на станции под управлением нашей системы, сгорели первые Porsсhe и VW ID4.

Повесть про микросервисы, масштабирование и энтерпрайз в сфере управления зарядками (много текста)

"Может вместо этого нам стоило разработать мобильное приложение с рецептами Высоцкой?" - на секунду задумались мы и продолжили наше непростое, но интересное дело.

Реализация роуминга оказалась для нас долгой и сложной задачей, несмотря на то, что мы готовились к ней с момента старта проекта. Поняв всю сложность и неоднозначность протокола, мы решили развивать роуминг как отдельный продукт, в результате чего разработка отняла полных 6 месяцев. Правильное ли было решение пойти этим путем? Мы пока не знаем. Но на нашей витрине появился еще один самостоятельный продукт Ocpi-Box и мы этому рады. Мы искренне надеемся что в рамках этого продукта нам удалось инкапсулировать сложность и противоречивость протокола внутри сервиса. Мы хотели предоставить клиенту более понятный механизм взаимодействия, что должно позволить экономить ресурсы на интеграции, избежать граблей, по которым прошлись мы. В данный момент мы активно развиваем нашу роуминговую сеть за счет интеграции с российскими партнерами и пробуем выйти на рынок роуминга в качестве поставщика коробочного решения.

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

  • мы начали проект, обладая значительным опытом и экспертизой в построении отказоустоичивых систем уровня предприятия;

  • мы начали разработку с нуля, не имели легаси кода;

  • мы обладали проверенными временем наработками, которые смогли эффективно использовать в другой предметной области;

  • мы имели возможность привлечь к проекту опытных разработчиков и девопс-инженеров.

Архитектура

Повесть про микросервисы, масштабирование и энтерпрайз в сфере управления зарядками (много текста)

Итак, наши принципы при проектировании архитектуры решения:

Микросервисная архитектура. Система представляет собой набор независимых легковесных сервисов, каждый из которых развивается и обновляется отдельно. Эффективное взаимодействие между сервисами достигается за счет использования высокоэффективных бинарных протоколов с высоким уровнем компрессии (GRPC, Kafka), что особенно важно при увеличении нагрузки на систему;

Поддержка горизонтального масштабирования. Каждый сервис нашей системы разворачивается как независимый контейнер внутри оркестратора, что позволяет применять правила автоматического масштабирования (увеличения количества инстансов сервиса при возрастании нагрузки);

Стэк на основе масштабируемых компонентов с открытым исходным кодом. Мы тщательно выбираем и предварительно тестируем компоненты, которые включаем в наш стэк. Отдаем предпочтения тем, которые являются одобренными для использования в Россиискои Федерации. Среди них исключительно компоненты с открытым исходным кодом и поддерживающие горизонтальное масштабирование. Мы уверены, что целевое использование зрелых продуктов в основе стэка позволит нам в дальнейшем многократно масштабировать систему. Наш основной стэк включает: Kafka, Aerospike, Clickhouse, PostgreSQL, ElasticSearch, Prometheus, Zabix, Kubernetes;

Зрелая архитектура сервисов. Внутренний дизайн сервисов мы разработали на основе нашего богатого опыта в предыдущих проектах. В результате мы не тратили время на поиск подходящих подходов, не накапливали технический долг и не занимались бесконечным рефакторингом. Существующая архитектура позволила нам реализовывать надежные фичи в короткие сроки и покрывать их тестами. Получился простой, понятный и повторяемый дизаин, с которым приятно работать, и который позволит быстро нарастить команду в случае необходимости;

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

Далее я затрону принципы разработки исходного кода, принятые в нашей компании.

Принципы разработки

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

Зрелая сформировавшаяся команда. Думаю, команда - это основное, что позволило нам построить эффективный процесс разработки. Наш опыт совместной работы и понимание сильных и слабых сторон друг друга позволили не тратить время на притирку, а сразу эффективно включиться в работу над проектом;

Культивация автотестов. Так как мы изначально понимали, что в рамках стартапа мы не сможем позволить себе ни постоянной QA команды, ни выделения большого ресурса на поддержку, наиболее эффективным подходом показалась ставка на автотесты, которая в конечном итоге дала нам необходимый уровень надежности и уверенности в системе. Кроме того, развитая инфраструктура тестов позволяет внедрять даже довольно крупные доработки без потери стабильности. Мы можем пересматривать наши предыдущие решения, переделывать целые модули, не беспокоясь о потере стабильности;

Тщательное и ответственное ревью кода внутри команды. Мы верим в необходимость придерживаться практик разработки даже в небольших проектах. Именно поэтому мы тщательно под микроскопом рассматриваем код друг друга и добиваемся его совершенства;

Энтузиазм, вера и любовь к своему делу. Как говорится "last but not least". Этот пункт стоило бы поставить на первое место, т к именно безумная вовлеченность всей команды и желание создать нечто крутое помогло нам не терять мотивации и уверенности в работе над проектом. Поверьте, в любом стартапе иногда возникает период уныния и депрессии. В этот момент важно обернуться и посмотреть на то, что уже сделано. Если результат тебе нравится, на следующий день ты проснешься с желанием как-то еще улучшить свой продукт.

В качестве заключения

Хотя рынок поставщиков программного обеспечения для управления зарядной инфраструктурой в России уже довольно зрелый и конкурентный, мы в компании ev2Go уверены в светлом будущем нашего решения, в наших подходах и технологиях. Мы хотим создать продукт нового уровня, сравнимый по качеству и возможностям с лидерами зарубежных рынков, но более современный, дешевый и простой в обслуживании.

Несмотря на то, что мы верим и культивируем технологии, постоянно совершенствуем и пересматриваем наши подходы, истинная ценность компании - это наша команда.

Именно команда позволяют нам строить амбициозные планы и привлекать новых клиентов.

Наши планы на ближаишее будущее включают:

  1. построение роуминг-хаба;

  2. повышение удобства и функциональности облачного решения (мы хотим быть AWS в мире зарядной инфраструктуры);
  3. повышение уровня сервиса за счет реализации CRM функции;
  4. создание решения для бригад обслуживания станций;
  5. развитие платежных средств;
  6. развитие решения для таксо-парков и транспортных предприятий;

Хочется верить, что эта статься позволит вам использовать наш опыт в вашем проекте, не совершать ошибок и быть лучшим решением на рынке.

Давайте строить счастливый мир электротранспорта вместе с ev2Go!!!

33
Начать дискуссию