15 июля 2015 г.

Инструменты для проекта на .NET и JavaScript: Часть 1

Когда я говорю, что в нашей компании мы используем .NET Framework, то собеседники обычно представляют «бедный» набор из ОС Windows, TFS, C#, MSSQL и ASP.NET + немного JavaScript.

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

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

В следующих нескольких постах я опишу наш набор инструментов, какие проблемы с ними возникали и на что мы поменяли тот или иной инструмент. Для разных проектов этот набор получается разный. Причем различаются не только библиотеки, но и подходы к проектированию.

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

Проект №1

Основные характеристики

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

  • В день обрабатывается 40-50 тысяч информационных блоков, 200-250 тысяч текстов.
  • Объем реляционной БД около 750ГБ, объем индексов Sphinx 600ГБ.
  • Микросервисная архитектура
  • Балансировка через очереди, число экземпляров сервиса устанавливается числом потоков приложения
  • Около 20 серверов под Windows Server, Ubuntu, CentOS

Хостинг

Изначально вся инфраструктура была на AWS, а это не много не мало 100+ виртуальных машин. Ушили с AWS на отечественный хостинг из-за повышения курса доллара полгода назад. Обратите внимание, что Amazon EC2 Reserved Instances покупаются на определенный период, при желании можно уйти раньше окончания срока, но деньги за неиспользованный период вернуть практически невозможно.

К тому же Амазон оказался менее производительным, чем виртуальные сервера на Vmware ESX. Сервера на Amazon были не сбалансированы, там либо много процессора и мало оперативки, либо много оперативки и мало процессора. На российском хостинге мы купили меньше ресурсов, нарезали купленное между виртуалками.

Бэкапы

Бэкапы всех серверов настроены средствами VMware + Veeam Backup, снимаются снепшоты по индивидуальному расписанию. Для консистентности баз данных используется Veeam AAIP (Application Aware Image Processing) с включенной Windows Shadow Copy Service на машинах с базами. Тестовые восстановления занимают меньшее время по сравнения с восстановлением БД из бэкапа MSSQL, но позволяют восстанавливать БД только на момент снятия снепшота (для нашего проекта потеря данных за сутки само-восполняема). Кроме того, процесс настройки резервирования прост и одинаков для всех серверов, как и процесс их восстановления.

TeamCity

Практически вне конкуренции для организации Continuous delivery. Кроме того запускает интеграционные тесты по таймеру, собирает JS-скрипты, выпускает артефакты проекта, заливает артефакты на сервер (используется PowerShell Remote). Отказались от встроенной Hyper SQL, поскольку в какой-то момент TeamCity стал сильно тормозить. Вмеcто Hyper SQL настроили работу с MS SQL.

IronMq

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

Минусы в том, что обращаться в тех. поддержку приходится чаще, чем хотелось бы. Год-два назад у них были забавные проблемы, когда однажды утром видишь, что из очереди пропали 100К сообщений. Правда они быстро исправляются и возвращают их обратно. Однажды были безвозвратно утеряны почти 1,5 млн сообщений, тех. поддержка только развела руками.

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

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

Интересно, что почти на всех других проектах используется RabbitMQ. На этом проекте IronMQ остался от AWS, т.к. изначально весь проект был в AWS, а IronMQ хостится на AWS. Со временем с AWS полностью ушли на хостинг, но очереди остались в облаке.

Microsoft SQL Server

Эта реляционная СУБД используется для расчета статистики, хранения основных сущностей и т.п.

Изначально ноды кластеризовались, используя технологию Microsoft Failover Cluster, переброс с ноды на ноду приложений делается автоматически. Поэтому возможны ситуации, когда кластер думает, что его основная нода не доступна и кидает приложение на второстепенную, которая не готова принимать данные, приложение падает. Поэтому отказались от этого и используем 2 ноды с настроенной между ними репликацией. Репликация на уровне БД не обеспечивает целостность данных, при добавлении новых объектов. Для того чтобы добавить таблицу на сервер репликации необходимо несколько не тривиальных пунктов - не описанных в документации.

Индексы, заведенные на таблицах, постепенно деградируют. Сервис их не регенерирует автоматически, делаем это самостоятельно через запуск job-ов.

Sphinx

Полнотекстовый поисковый движок родом из России. Из коробки не может ничего. Совсем. Всё решает правильная настройка конфигов. Быстр, местами глючен. Хорошая поддержка русского языка, но, к сожалению, маленькая команда разработчиков и, как следствие, редкие релизы.

Со Sphinx очень просто общаться с ним коннекторы MySql (пакет MySql.Data).

Несколько багов обнаружено нами (в основном из-за большого объема данных), часть из них до сих пор не решена. Поддержка отвечает на вопросы, но баги исправлять не спешит. Возможно, если бы сейчас стоял выбор, то мы взяли бы Elasticsearch для решения задач полнотекстового поиска.

Redis

Хорош для кэширования информации в памяти и её персистирования на диск. Подходит, если важна скорость запроса и не хочется при этом ничего потерять. Помимо этого умеет много интересного: работа со структурами данных, защищенные очереди, pub/sub и другое.

Если объем памяти меньше объема данных, будет происходить вытеснение. Важно правильно настроить политику вытеснения и последующее восстановление данных. У нас были с этим шероховатости.

Мониторинг Redis настроен через zabbix (установлен Python и специальный Python-скрипт получает и передает на сервер zabbix показатели). Наиболее важным параметром является Evicted Expired Keys, который говорит о том, что объем памяти не достаточен и происходят вытеснения из Redis.

NCron

Планировщик задач, умеет запускать таски по таймеру. Даже если экземпляр таска не отработал, не колеблясь запускает следующий. Это нужно учитывать в своем приложении. Однажды у нас это привело к массовой рассылке дубликатов писем.

Dapper

Удобен, безотказен. Особенно хороши MultiQuery, можно запрашивать несколько сущностей одним запросом. Также есть DynamicParameters, это позволяет динамически формировать запросы и их параметры. Минусы в том, что запросы на Update, Insert и Select каждый раз пишутся полностью заново, из-за чего можно в них ошибиться. С этой сложность можно бороться с помощью QueryObject.

PetaPoco

Микро ORM, есть атрибутный маппинг сущностей (только простые типы, вложенные объекты не понимает). Плюсы в том, что по маппингу автоматически генерируются запросы на Update, Select, Insert. Есть проблемы при чтении Enum и собственными переменными внутри скриптов, пришлось патчить. Минус в том, что с 2013 года пакет не обновлялся.

SevenZipSharp

.NET обертка к архиватору 7z. Позволяет очень эффективно сжимать текстовые данные. Однако сама обертка написана на статических классах, что создает проблемы многопоточным приложениям. В проекте применяется для сжатия данных, которые передаются в очереди (выше было написано про ограничения IronMQ).

YouTrack

Путь к нему был довольно долог. Сначала сидели в AgileZen, не хватало возможностей поиска, возможности назначать нескольких разработчиков и QA на одну задачу, слабая система отчетов по итерациям, нет интерактивности.

Потом перешли на AgileZen + Gooogle Docs, решили проблему отчетности и получили массу электронно-бумажной работы. И наконец перешли к YouTrack. В принципе, устраивает почти всем. Не хватает полной итеративности и возможности отдельного оценивания разработчиком и QA своих частей задачи.

Zabbix

Zabbix — это наши глаза и бесценный инструмент для нахождения проблем. Без мониторинга всей нашей инфраструктуры система будет неуправляема.

Изначально мы постарались определить узкие места системы, в дальнейшем список постоянно расширялся и расширяется до сих пор:

  • показатели серверов (процессор, память, диски)
  • состояние служб и запущенных приложений
  • определять кол-во обработанных задач
  • определять полноту обработки
  • видеть очередь сообщений
  • состояние кластеров БД
  • доступность внешних систем и пр.

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

Front-end

Пользователи работают с системой через браузер, интерфейс очень интерактивный, много взаимосвязанных элементов. Из арсенала front-end разработчиков можно выделить:

Другие инструменты

Всё подробно перечислять не будем, дальше списком:

  • ASP.NET MVC, WebAPI, Windows-сервисы и другие стандартные инстурменты для .NET Framework
  • Git
  • CompareNETObjects
  • Microsoft.Owin.Security.OAuth
  • log4net
  • IIS
  • Яндекс Метрика, Yandex mail + Yandex DNS
  • Google Analytics
  • Google maps
  • Sendgrid
  • MailChimp

Продолжение следует...

В следующем посте будет рассказ про разработку проекта, которые делался почти полностью через TDD, на российском облаке и PosgtreSQL.

1 комментарий:

  1. То, что Саша описал, разрабатывалось, когда Typescript был еще в зачатке. Сейчас мы в продакшене используем ES2015 и babel. TS в своей текущей версии не дает нам ничего, кроме статической типизации на уровне транспайлера.

    ОтветитьУдалить