Из этой статьи вы узнаете, как организовать процесс построения эффективной разработки в распределенной цифровой компании, как сделать это через общение экспертов и как это происходит на примере МТС.
МТС, как и многие другие современные компании, подверглась так называемой цифровой трансформации. Говоря простым языком, нашим приоритетом стал запуск цифровых процессов и продуктов.
Для меня, как для технаря, это значит, что направление бизнеса в компании целиком зависит от качества ИТ-систем и их способности к быстрому эволюционированию.
Конечно, это неправильное определение, и маркетологи могут со мной поспорить — и даже переспорить! Но для всего, что вы прочитаете ниже, его вполне достаточно.
Меньше бюрократии — проще разработка
Что изменилось: в первую очередь, модель управления компанией. Если раньше ребята из централизованной архитектуры предприятия (enterprise architecture) верифицировали каждый проект, то теперь они издают техническую политику (большой и умный документ) и обучают ей архитекторов. А как ее применять — уже личное дело каждого продуктового архитектора из более чем сотни команд.
С одной стороны, это хорошо — меньше бюрократии, что сильно упрощает разработку. С другой — все продукты так или иначе между собой взаимодействуют, и ошибка в одном из них может повлиять на другой.
Например, в книге Software Systems Architecture: Working with Stakeholders Using Viewpoints and Perspectives Оуэн Вудс (Eoin Woods) и Ник Розански (Nick Rozanski) пишут про базовый принцип обеспечения безопасности — secure the weakest link. Он означает, что если в вашем IT-ландшафте есть хоть одна слабо защищенная IT-система, то под угрозой весь IT-ландшафт. Просто потому, что гипотетический злоумышленник может безнаказанно работать от имени этой системы.
Есть еще много примеров, когда полезно иметь гарантированное качество и согласованность в проектировании и разработке IT-систем.
Эксперты из интровертов
Что мы придумали: создать сообщество по обмену знаниями и распространению лучших практик. Идея не нова и не сильно революционна, но отвечает требованиям и специфике разработки цифровых продуктов.
- Как способ организации работы мы выбрали проведение интервью с представителями всех ролей производственных команд — от аналитика до DevOps- и support-инженеров;
- Интервью проводят такие же представители продуктовых команд, пользующиеся авторитетом в компании. Очень важно, чтобы это были именно практикующие специалисты, а не сторонние консалтеры или аудиторы;
- Мы не смотрим на соответствие работ какому-то стандарту или регламенту, наша задача — выявление рисков. Это дает ряд плюсов. Во-первых, риски можно оценить с точки зрения вероятности и влияния на конкретную команду; во-вторых, их можно отсортировать; в-третьих, по каждому риску можно придумать план борьбы;
- Интервью в формате живого общения, где обе стороны делятся опытом и обсуждают технические нюансы;
- Организация ротации в команде «аудиторов», чтобы как можно больше представителей команд имели возможность обмениваться знаниями и опытом.
Чтобы запустить процесс, мы собрали команду энтузиастов, разработали для каждой из ролей перечень тем обсуждения и провели обучение команды наших импровизированных аудиторов. К слову, обучение было самым сложным этапом, поскольку зачастую очень хорошие специалисты в нашей сфере — это еще и очень хорошие интроверты :-)
Что получилось в результате?
- Процесс исследования продуктовых команд получился довольно неспешным. В среднем на одну команду у нас уходит примерно 31 день. За это время мы успеваем пообщаться с представителями всех направлений деятельности команды, составить отчет-памятку и объяснить ее владельцу продукта, чтобы он мог ее запланировать в действие;
- Результат работы очень зависит от эксперта. Поэтому важно, чтобы их было по несколько на каждую роль: два аналитика, два архитектора и т. д.; где один уже провел ряд интервью, а другой только включается в общение;
- Необходимо также постоянно адаптировать методику интервьюирования, поскольку одни темы теряют актуальность, а на их месте возникают вопросы, о которых раньше никто не задумывался.
Для примера давайте посмотрим на результаты исследования по направлению «Архитектура».
Что мы сделали:
- Провели общение с 20 командами;
- На каждую тратили в среднем 31 день. С учетом того, что мы параллельно общались с несколькими командами, весь процесс занял полгода;
- Выявили 180 рисков, связанных с архитектурой.
Внутри наших команд риски разделились так:
Риск 1: проектирование
Важно понимать, что все исследуемые нами программные системы так или иначе проходят через достаточно строгий выходной контроль качества (например, у телеком-систем период контроля больше периода разработки), но нет границ совершенству и эффективности.
Чтобы понять, что мы считаем за риски, давайте рассмотрим ТОП-3 на примерах.
Для молодых продуктовых команд вполне нормальна ситуация, когда программная архитектура разрабатывается по остаточному принципу. Вначале кажется, что все просто, да и сроки проектов редко дают возможность всерьез задуматься об организации архитектуры. И тогда вступает в действие метод проектирования снизу вверх — когда мы разрабатываем отдельные компоненты решения, после чего собираем их в единое целое.
Например, мы решили сделать цифровой продукт для телемедицины. Что для этого нужно?
- Наверное, нам нужен компонент для видеозвонков между пациентом и врачом — делаем компонент для звонков;
- Иногда нужен обычный чат — значит, делаем компонент для чата;
- Нужно брать историю болезни из автоматизированных медицинских систем — создаем соответствующий компонент;
- Нужно вести расписание дежурства врачей — делаем компонент и для этого.
И так далее.
Все кажется просто, пока мы не начинаем собирать все вместе. И тут появляются проблемы с дублированием функций — например, чат и видеозвонок сами по себе очень близкие приложения (по крайней мере с точки зрения контекста взаимодействия врач-пациент). Т.е. риск в том, что нам придется переделывать наше приложение достаточно существенно из-за большого количества дублирующего кода.
Или проблемы с моделью данных. Каждый компонент по умолчанию предоставляет интерфейсы в той модели, которая удобна для хранения и обработки именно этому компоненту, а не приложению в целом.
Поэтому стоит помнить ряд простых правил:
- Метод проектирования снизу вверх хорош для небольших проектов с низкой технической сложностью, небольшими командами и изменчивыми требованиями;
- Для больших проектов и команд приемлем метод проектирования сверху вниз, то есть когда мы сперва проектируем картину в целом, а потом уже приступаем к кодированию.
Поэтому прежде, чем окунуться с головой в новый проект, задайте себе вопрос: к какому типу он относится?
Риск 2: безопасность
Казалось, про безопасность в наше время думают очень серьезно. Все помнят такие банальности, как необходимость:
- аутентифицировать пользователей;
- авторизовывать их на проведение действий;
- соблюдать принцип минимальных привилегий (principle of least privelege);
- поддерживать конфиденциальность данных;
- вести лог аудита действий пользователя.
Но вот неожиданность! Для команд, которые делают сервисы по внутренней автоматизации, это не так очевидно, как для всех остальных. Кажется, если приложение уже работает во внутренней корпоративной сети, то зачем его еще защищать? На самом деле надо, особенно если данные, с которыми работает приложение, относятся к категории персональных. Да, вероятность того, что во внутренюю сеть проник злоумышленник сильно мала, но защиты много не бывает.
Да и с внешними приложениями тоже могут возникнуть нюансы. Рассмотрим простой, чисто гипотетический, пример веб-приложения, которое аутентифицирует пользователя по паролю. Какие могут быть тут проблемы:
- Приложение может позволять вводить слишком простые пароли, которые потом легко подобрать;
- Приложение может быть незащищено от самих переборов паролей (нет ни капчи, ни чего подобного);
- Приложение может генерировать пароль при первой регистрации и не требовать его обязательной смены. Таким образом, пароль будет храниться где-нибудь в почте в открытом виде;
- Пароль может передаваться в URL-запросе или в теле HTTP-запроса в открытом виде;
- Приложение хранит пароли в виде хеш-функций, но использует не безопасный криптоалгоритм. Например, MD5 сравнительно легко перебирается с помощью радужных таблиц;
- Веб-приложение не предоставляет пользователям возможность изменения пароля либо не нотифицирует пользователей об изменении их паролей;
- Веб-приложение использует уязвимую функцию восстановления пароля, которую можно использовать для получения несанкционированного доступа к другим учетным записям. Например, спрашивает информацию, которую кроме вас знает пол-организации;
- Веб-приложение не требует повторной аутентификации пользователя для важных действий: смена пароля, изменения адреса доставки товаров и т.д.;
- Веб-приложение небезопасно работает с HTTP-сессиями:
- веб-приложение создает session tokens таким образом, что они могут быть подобраны или предсказаны для других пользователей;
- веб-приложение уязвимо для session fixation-атак (т. е. не заменяет session token при переходе анонимной сессии пользователя в аутентифицированную);
- веб-приложение не устанавливает флаги HttpOnly и Secure для browser cookies, содержащих session tokens;
- веб-приложение не уничтожает сессии пользователя после короткого периода неактивности либо не предоставляет функцию выхода из аутентифицированной сессии.
Таким образом, тут риск связан с тем, что кто-то получит доступ к данным, которые ему не предназначены. И это может привести к проблемам в работе приложения.
Это лишь примеры того, о чем можно поговорить в сфере безопасности. Конечно, идеальным вариантом будет внедрение процесса Secure Development Life Cycle Например, такого, как рекомендует Microsoft.
Риск 3: производительность
Одной из проблем быстро создаваемых продуктовых команд является слово из трех букв. Это MVP или minimal valuable product (минимально жизнеспособный продукт). Такие команды стремятся как можно быстрее создать приложение, которое начнет приносить доход компании, а поскольку пользователей у приложения в начале будет совсем немного, то о параметрах производительности обычно думают в последний момент. Но если созданное приложение вдруг становится популярным, то приходится задуматься, как быть дальше.
Тут рекомендации простые: производительность приложения обратно пропорциональна числу запросов к медленным ресурсам. Соответственно, все тактики направлены либо на уменьшение числа запросов, либо на ускорение самих ресурсов. При этом под ресурсами понимается процессор, память, сеть, диски; также иногда удобно рассматривать в качестве ресурса базу данных или сервер приложений.
- Сначала смотрим, можно ли в распределенном приложении сделать клиентский кэш, чтобы каждый раз не запрашивать/ вычислять нужные нам данные. Если это возможно, то мы экономим на сетевых запросах, загрузке ресурсов сервера и всего того, чем он там занимается.
- Но так везет очень редко, поэтому смотрим, не сделать ли нам серверный кэш. С ним принцип такой же что и с клиентским, но выигрыш в производительности немного меньше, поскольку все-таки будут ходить сетевые запросы;
- Тут мы вспоминаем, что сервера хорошо бы масштабировать. В наше время микросервисов тяжело представить приложение, которое не масштабировалсь бы горизонтально, то есть установкой еще одной копии сервера и организации распределения запроса, например, по принципу балансировки нагрузки (load balancer);
- Раз уж сервер у нас масштабированный, то нужен распределенный кластерный кэш. Для этого есть много полезных систем — от уже устаревающей My SQL Cluster Grid Edition до вполне хайповой Apache Ignite (Gridgain).
Ну и, конечно, надо помнить, что сам по себе кэш решает проблему с доступом к данным, но создает новую проблему с алгоритмом его инвалидации и предзагрузки. А в каких-то системах кэширование может быть и вовсе бесполезным. Например, в CRM (Customer Relationship Management) системах очень редко удается эффективно кэшировать данные о клиентах. Специалист, который работает в офисе очень быстро переходит от одного к другому клиенту и кэш просто не используется.
Таким образом, тут риск в том, что не подумав вначале о стратегии того, как мы будем «разгонять» наше приложение, мы можем попасть на очень большие затраты по переписыванию приложения в будущем.
Подводя итог
В этой статье я постарался рассказать, как можно организовать процесс построения эффективной разработки в распределенной цифровой компании через общение экспертов. В наше время удаленной разработки такие процессы становятся особенно актуальными. Они позволяют разрушить закон Конвея, ну или хотя бы его минимизировать.
Если решитесь создавать собственные чек-листы, то я бы рекомендовал не делать все с нуля, а взять что-нибудь из уже существующей литературы. Например, по архитектуре очень полезен обзорный материал Software Architect's Handbook авторства Joseph Ingeno ISBN: 9781788624060
Мой доклад можно посмотреть тут
Автор статьи: руководитель R&D Центра Дмитрий Дзюба
Автор: info_habr