От хаоса к порядку. Как мы внедряем стандарты в CDEK

От хаоса к порядку. Как мы внедряем стандарты в CDEK

От хаоса к порядку. Как мы внедряем стандарты в CDEK

Привет, Хабр! Меня зовут Олег Бондарь, я архитектор решений в CDEK. В этой статье расскажу о стандартах — сводах правил и требований, которые позволяют всем участникам процесса быть в общем контексте, действовать единообразно и совершать меньше ошибок. Кроме того делают взаимодействие между людьми и системами немного проще.

Статья будет полезна менеджерам проектов, разработчикам, тестировщикам, аналитикам и другим IT‑специалистам. Поговорим о способах выработки и применении стандартов, их влиянии на проектирование, разработку, тестирование и стабильность системы в целом. Для примера возьмем ERP CDEK, которая ежедневно обеспечивает работу десятков тысяч пользователей, нескольких сотен тысяч клиентов и позволяет нам обрабатывать до полумиллиона заказов в день.

Содержание

Атом вместо утки. Экскурс в историю стандартизации

Человечество задумывалось о стандартах с первых шагов современной цивилизации. В Древнем Египте при строительстве использовались кирпичи постоянного размера, а контролем соответствия размеров занимались специальные государственные служащие. Традиционные европейские системы измерения были унаследованы от древнеримских единиц, основанных на понятных каждому обывателю объектах: «палец» — дюйм, «ступня» — фут, «тысяча двойных римских шагов» — миля. Вес в древнем мире измерялся в волах, утках, зернах ячменя или пшеницы (например, один сикль равнялся весу 180 зерен ячменя).

Древний Египет. Взвешивание сердца умершего человека на суде Осириса. Источник

Древний Египет. Взвешивание сердца умершего человека на суде Осириса. Источник

С некоторыми единицами измерения происходили курьезные случаи. Например, английский ярд был введен королём Эдгаром и равнялся расстоянию от кончика носа Его Величества до кончика среднего пальца вытянутой в сторону руки. После смены престолодержателя величина ярда изменилась: новый король был более крупного телосложения, чем его предшественник. При следующей смене монарха ярд снова укоротился. Такие частые изменения единицы длины вносили путаницу.

В 19-м веке стандартизацией начали заниматься «в промышленных масштабах». Были предложены метрические единицы измерения сантиметр‑грамм‑секунда, появились прототипы эталонов метра и килограмма. В 20-м веке принята Международная система единиц (СИ), наиболее широко используемая в мире на сегодняшний день. В 2019 году единицы измерения СИ были полностью отвязаны от материальных эталонов и стали рассчитываться на основе физических свойств атома.

Важным этапом стало появление Международной организации по стандартизации (ISO), которая занимается выпуском стандартов. В 80-х годах прошлого века был организован Инженерный совет Интернета (IETF), оказывающий значительное влияние на современную IT‑отрасль.

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

Для организации эффективного бизнес‑процесса (в том числе и процесса разработки ПО) применяются регламенты, технические требования и практические рекомендации, которые если и не названы стандартами, по сути, ими являются.

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

История первая. «Планёр Гимли»

В 1983 году Boeing 767–233 авиакомпании Air Canada выполнял внутренний рейс по маршруту Монреаль‑Эдмонтон с посадкой в Оттаве. Вскоре после вылета из Оттавы, на высоте 12,5 километров в кабине пилотов прозвучал сигнал «Отказ всех двигателей». В самолете отключилось электричество и большая часть приборов на панели перестала функционировать. Пилоты взяли курс на Виннипег, но из‑за неработающих двигателей приняли решение совершить аварийную посадку на военной авиабазе Гимли. При посадке у самолета сложилась передняя стойка шасси и начался небольшой пожар, который удалось потушить. 10 пассажиров получили травмы, но к счастью, серьёзно никто не пострадал.

Самолёт проехал передней частью по бетону во время аварийной посадки. Фото: Роберт Пирсон

Самолёт проехал передней частью по бетону во время аварийной посадки. Фото: Роберт Пирсон

Эта авария произошла в то время, когда Канада переходила на метрическую систему. Наземная команда ошиблась при заправке самолета — неправильно рассчитала массу топлива (использовала коэффициент для британского имперского фунта вместо килограмма), из‑за чего вместо 20 тысяч литров было заправлено всего 5 тысяч.

История вторая. «Mars Climate Orbiter»

В 1998 году NASA проводило миссию по исследованию марсианского климата. Их космический аппарат Mars Climate Orbiter, запущенный в декабре, в течение года должен был выйти на орбиту Марса для исследования атмосферы и фотосъемки поверхности. 23 сентября 1999 года аппарат начал заходить на запланированную орбиту и после прохождения с обратной стороны планеты должен был выйти на связь. Однако больше никаких сигналов от спутника не поступало.

В ходе расследования первопричин аварии NASA сообщило, что субподрядчик в ПО аппарата использовал единицы измерения СИ, в то время как в центре управления на Земле использовались британские единицы. Предполагается, что аппарат прошел над поверхностью Марса на высоте 57 км вместо расчетных 110 км и распался в атмосфере. Данная ошибка привела к потере 327,6 миллионов долларов США, согласно оценкам NASA.

Эти истории наглядно показывают, что даже при наличии стандартов может возникать путаница между ними. А небольшие, в общем‑то, недочеты могут привести к серьезным последствиям. Хотя в большинстве случаев автоматизации бизнеса ошибки не приводят к падению самолётов или остановке работы компании, они могут привести к неудобствам для клиентов, пользователей сервисов и даже к финансовым потерям.

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

Стандарты? Не, не слышали

На момент моего прихода в CDEK, в 2019 году, в компании происходил отказ от морально устаревшей монолитной ERP‑системы, написанной на C++. Активно разрабатывалась новая версия с применением микросервисной архитектуры. На тот момент уже работало несколько десятков сервисов, написанных на Java (большая часть ядра системы), PHP (в основном витрины и интеграции) и JavaScript (фронт). При этом какая‑либо стандартизация хранения, обработки и обмена данными по большей части отсутствовала. Поэтому разработчики руководствовались в работе собственным опытом и интуицией, не применяя на практике унифицированный подход к данным.

Одной из самых распространенных проблем был подход к работе с датами и временем. Приведу небольшой список констант из уже вышедшей из употребления корпоративной Java‑библиотеки, которая использовалась для преобразования даты со временем в строку и обратно:

String SERVER_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
String VIEW_DATETIME_FORMAT_STRING = "d.MM.yyyy H:mm:ss";
String VIEW_DATESHORTTIME_FORMAT_STRING = "d.MM.yyyy H:mm";
String ORACLE_DATETIME_FORMAT_STRING = "dd.MM.yyyy HH:mm:ss";
String NSPCMAIL_DATETIME_FORMAT_STRING = "dd.MM.yyyy HH:mm:ss";
String ELASTIC_DATETIME_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss.SSS";
String ELASTIC_DATE_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss";
String FILE_NAME_DATE_FORMAT_STRING = "dd.MM.yyyy-HH_mm_ss";
String VIEW_DATETIME_SHORT_FORMAT_STRING = "dd.MM.yyyy HH:ss";

Принцип использования достаточно простой: при конвертации данных (например, из строки в JSON объекте) по очереди перебирались все возможные варианты представления и при некоторой доле везения, результат записывался в типизированную переменную. При этом, например, в Java использовался безнадежно устаревший тип java.util.Date.

Легко заметить, что во всех приведённых форматах даты и времени отсутствует указание временной зоны. Фактически значение могло быть указано как в локальной таймзоне, так и неявно в UTC, по Московскому или Новосибирскому времени. Иногда формат и временная зона указывалась в комментарии к полю объекта или столбцу БД. Чаще всего приходилось выяснять это проводя натурные эксперименты, разбираясь в коде проекта. Или же искать ответственного за данный объект разработчика.

Валюты идентифицировались в ERP‑системе пятью способами: внутренний числовой идентификатор системы, уникальный идентификатор (uuid), цифровой и буквенный коды ISO 4217, причем как в верхнем, так и нижнем регистрах. Глядя на строковое поле, содержащее код валюты в произвольном обменном объекте, решительно невозможно было понять: в каком именно формате будет представлена валюта на самом деле. Это мешало не только разработке, но и анализу инцидентов. Просто представьте, что просматривая логи, вы видите 1000 единиц в валюте № 14 или 500 у.е. в валюте с идентификатором 18117342-cff4–4fa4-a2cf-c3d332c27330.

Коды языков, локалей и стран могли быть представлены в произвольном, иногда выдуманном разработчиками виде. Например, Беларусь появлялась в виде кода BR, относящегося в ISO 3166 к Бразилии. А в списке языков мог появиться казахский с кодом »kz», которого вовсе не существует в стандарте ISO 639.

Номера телефонов были полностью непригодны для автоматической обработки, поскольку даже для РФ они имели любой из префиксов »7»,»+7»,»8» (или не имели его вовсе). Сервисы обрастали «костылями» для обработки номеров телефонов с подсчетом цифр и подменой префиксов. Алгоритмы выглядели монструозно и были ненадёжны.

Более того, данные форматы «просочились» даже в БД, где и хранились в виде сериализованных строк, а не в виде специализированных типов. В одном объекте или таблице БД могли использоваться разные варианты сериализации одного и того же типа.

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

Как мы пришли к стандартизации

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

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

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

Проанализировав ситуацию, я понял, что проблему можно решить, если описать и внедрить общие правила для работы с данными. Итогом стала объемная статья на основе стандарта ISO 8601 и строгой типизации с использованием классов java.time.*. В статье описал принципы и примеры работы с датой и временем, особенности применения временных зон и смещений, подходы к хранению, документированию и межсистемному обмену.

Затем были выработаны стандарты, призванные сделать и другие данные компании однозначными и единообразными:

  • Стандарт номеров телефонов — был разработан на основе ITU‑T E.164, преследует целью унификацию представления телефонных номеров (всегда указывается полностью, обязательно начинается с »+» и кода страны, не содержит разделителей);

  • Стандарт валют — основным идентификатором выбран код ISO 4217 Alpha-3, который однозначен и человекопонятен;

  • Стандарт финансовых и монетарных значений — с главной идеей сформулировать неотделимость суммы от валюты; в момент написания этой статьи мне встретился код, где складываются суммы из разных объектов без учета валюты!

  • Стандарт локалей — за основу взято представление локали в Java (страна ISO 639–1 и язык ISO 3166–1 Alpha-2, разделенные подчеркиванием);

  • Стандарт языков — согласно стандарту ISO 639–3;

  • Стандарт временных зон — на основе IANA Timezone Database.

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

Профит

Внедрение стандартов:

  • значительно снизило количество ошибок (количество массовых сбоев уменьшилось на порядок в том числе благодаря внедрению единого подхода к данным);

  • облегчило расследование инцидентов (взаимодействие между сервисами стало проще, а логи — очевиднее);

  • ускорило разработку, тестирование и внедрение задач (время на выпуск бизнес‑фич сократилось до 14 дней);

  • улучшило аналитику, BI (качественные исходные данные — качественный результат);

  • оказало заметное положительное влияние на основной бизнес компании в целом.

Вам нужны стандарты. С чего начать?

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

Если говорить об унификации данных, в первую очередь нужно проанализировать существующие общемировые и общепринятые стандарты, например: ISO, IETF RFC, ICANN, ITU‑T. Для начального ознакомления подойдут и статьи Википедии.

Для создания некоторых стандартов легче и эффективней использовать практическую документацию. Например, для корпоративной стандартизации HTTP‑заголовков вместо исходного RFC 4229 допустимо использовать документацию MDN Web Docs, которая проще для понимания и содержит практические примеры.

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

Стандарты выработаны — что дальше?

А дальше начинается самое сложное. Недостаточно просто сформулировать стандарт — нужно добиться его внедрения. Для этого существует два подхода: административный и технический.

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

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

Иногда внедрение происходит «со скрипом». В сервисах, в которых изначально использовались подходы, сильно отличающиеся от стандарта, возникает большое количество техдолга и проблем с обратной совместимостью. Обычно в таких случаях помогает разговор с командой (ура, созвон!) с аргументами, показывающими необходимость принятого решения и способы его реализации.

Конечно, стандарты применяются не только в работе с данными. Возможно стандартизировать любые бизнес‑процессы (в этом случае они к тому же проще автоматизируются), процессы разработки (взять за основу хотя бы Agile) и даже количество котиков в офисе в расчете на квадратный метр.

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

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

Если в процессе работы вы постоянно сталкиваетесь с проблемой «неоднозначности» и «неочевидности» (неважно — в данных или процессах разработки или бизнеса), то самое время подумать о стандартизации: выбрать объект и сформулировать к нему общие правила и требования. Даже если это не принесёт результата в моменте, со временем вы обязательно почувствуете накопленный эффект и положительное влияние на процессы и бизнес компании в целом.

А какие стандарты применяете вы? Как они влияют на процессы в вашем случае и приходилось ли сталкиваться с проблемами при их внедрении? Буду благодарен, если поделитесь своим опытом в комментариях.

© Habrahabr.ru