Топ архітектурних помилок з власного досвіду. Що не варто робити під час проєктування

Хочу поділитися своїм досвідом і розповісти про найпопулярніші помилки під час проєктування та розробки архітектури застосунків. В ІТ працюю майже 15 років, з них 5 — архітектором. За цей час сам встиг наробити помилок і надивився на безліч чужих. Тож маю що розповісти. Трохи більше про мене тут .

Якщо ви нетехнічний фахівець, але все-таки залучені в проєктування і розробку програмного забезпечення, не поспішайте закрити цю статтю. Спочатку поговоримо про так звані soft skills помилки, які трапляються в процесі консалтингу, а потім перейдемо до технічних.

Сподіваюся, стаття допоможе вам уникнути невдач.

Типові помилки в процесі консалтингу

Помилка 1. Робити те, що просить клієнт, а не те, що йому насправді потрібно

Прийти, послухати клієнта й одразу почати роботу згідно з його інструкціями — найпоширеніша помилка під час pre-sale фази. Ви можете заперечити, адже ми йому й потрібні для того, щоб зробити те, що він хоче. Але ні.

Найперше та найважливіше — з’ясувати реальну бізнес-проблему клієнта і зрозуміти, як її розв’язати. Це завдання бізнес-аналітика та архітектора. Зовнішніх консультантів наймають саме для цього.

Якби замовник мав глибшу експертизу і сам міг зрозуміти, що в нього не так, наша допомога йому не була б потрібна. А якщо він виділив бюджет і найняв нас, значить, уже пробував вирішити цю проблему самостійно (або наймав іншого партнера), але з цього нічого не вийшло.

Якось до нас прийшов клієнт з проблемою, що усі, до кого він звертався раніше, пропонували занадто складне і дороге рішення під його задачу. Ми почали розбиратися. Виявилося, що на той момент замовники зберігали та редагували дані в Excel і хотіли мати той самий функціонал, але щоб це був вебзастосунок у хмарі. Ми припустилися стандартної помилки — не уточнили, навіщо це, і просто прорахували два варіанти реалізації застосунку, який начебто був потрібен. Обидві суми були набагато вищі, ніж очікувалося.

Ми вже майже попрощалися із замовниками, і тут я запитав, чим їх не влаштовує робота в Excel. З’ясувалося, що їм потрібно було, щоб дані постійно копіювалися і була можливість одночасного доступу до них з різних місць, так щоб дані були однакові (consistent) для всіх користувачів. А ще клієнти дуже непогано зналися на SQL. І тут рішення прийшло само собою — зробити міграцію даних в SQL-базу, яка зберігатиметься в хмарі та копіюватиметься автоматично, а користувачі матимуть одночасний доступ з різних точок планети. Це рішення мало схоже на комерційний застосунок, але це саме те, чого потребував клієнт і саме за ту ціну, яку він міг заплатити.

Якщо ми чітко розуміємо проблему, то можемо запропонувати краще і дешевше рішення.

Помилка 2. Не готуватися до сесій з потенційним клієнтом

Здавалося б, до нас клієнти приходять за експертизою, яка у нас вже є, навіщо готуватися? Але тут мова про те, що потрібно проаналізувати контекст, заглибитися у конкретну сферу та проблематику, інакше ви не зможете побачити найкраще рішення.

Підготовка до pre-sale. Перша зустріч з клієнтом — це етап pre-sale. Від неї значною мірою залежить, чи підпишуть з вами контракт. Тому потрібно зібрати якомога більше інформації про сам проєкт, компанію, сферу її діяльності, конкурентів, аналогічні рішення на ринку. Адже без цих знань ми не зможемо бути корисними. До того ж розуміння контексту допоможе підібрати оптимальну проєктну команду.

Що буває, якщо не підготуватися? Уявімо, що до вас звернулася компанія, якій потрібно розгорнути e-learning платформу для клієнтів. Спеціалісти, які раніше з таким не стикалися і не досліджували цю сферу, пропонують з нуля розробити власний продукт, а не адаптувати готовий. Безумовно, це довго і дорого. Тут ще потрібно враховувати, що компанії зазвичай ведуть перемовини з кількома консультантами. Звісно, вони виберуть тих, хто запропонує швидший і дешевший варіант.

Інший можливий сценарій — у замовника низькі показники продуктивності (performance), він хоче, щоб виявили причину та усунули її. Найраціональніше рішення — під’єднати системи, що допомагають знайти схожі проблеми, впровадити тестування навантаження (Performance Testing) і з’ясувати їх причину. Для команди консультантів, які не є експертами в такому типі тестувань, це неочевидно, тому вони пропонують провести довгу і дорогу discovery-фазу. Навряд чи клієнт погодиться.

Тому перед pre-sale сесією ретельно вивчіть інформацію, яку можна знайти в інтернеті, напишіть листа клієнту з уточнювальними запитаннями, можна провести короткий дзвінок, щоб дізнатися більше деталей, перш ніж починати обговорювати технічні нюанси й робити конкретні пропозиції.

Підготовка до discovery-фази. Ця тема заслуговує окремої статті, але ось основні, на мій погляд, пункти:

  1. Приділіть ще більше уваги вивченню інформації про клієнта і проєкт, ніж під час підготовки до pre-sale. На цьому етапі у вас повинно бути вже більше контексту і можливостей знайти дані.
  2. Підберіть команду (про це докладніше поговоримо далі).
  3. Підготуйте адженду — це ніби очевидний етап, але його часто пропускають, особливо початківці. Були навіть ситуації, коли команда прилетіла до замовника за океан і стукала у зачинені двері офісу, оскільки заздалегідь не узгодила адженду. Щоб під час discovery не виникло непорозумінь, раджу сюди вносити таку інформацію щодо кожної зустрічі:
    • час, тривалість;
    • перелік стейкхолдерів, які будуть присутні, від вас;
    • перелік стейкхолдерів з боку клієнта;
    • питання до обговорення;
    • відповідальний експерт з вашого боку (якщо будете обговорювати архітектуру, то це має бути архітектор, якщо функціональні вимоги — бізнес-аналітик).

Попросіть, щоб менеджер з боку клієнта узгодив графік з ключовими особами для кожної зустрічі та запланував зустрічі у календарі.

Така підготовка значно підвищить шанси на успіх.

Помилка 3. Неправильно підібрана проєктна команда

На pre-sale мають бути залучені спеціалісти, які не лише мають найвищу технічну експертизу, а й можуть говорити мовою бізнесу і зрозуміти бізнес-проблеми.

Що може піти не так, якщо на першій зустрічі будуть суто технічні люди? Можливо, ви навіть пригадаєте себе в минулому. Коли такий експерт бачить архітектурну проблему, він одразу прагне переписати все з нуля. На його погляд, це єдине правильне рішення. Вартість і тривалість цієї роботи не враховується. Найімовірніше, що бізнес не підтримає таку ідею і потенційний клієнт піде від вас.

Якщо говорити про discovery, то головні дійові особи тут:

У кожного члена команди має бути чітка роль. Інакше може виникнути дві ситуації:

Помилка 4. Не визначити чіткі вимірювані значення нефункціональних вимог

Один з головних обов’язків архітектора під час консалтингу — це зібрати нефункціональні вимоги (non-functional requirements), їх ще називають атрибутами якості (quality attributes). Це тема, на яку люди пишуть цілі книжки. Але розберімось хоча б в основних помилках, які суттєво впливають на успіх проєкту.

Запитуючи у клієнта про вимоги до якості майбутнього рішення, часто у відповідь можна почути, що воно повинне бути швидким, безпечним, що код має бути якісним тощо. Приймати це як вичерпну відповідь — величезна помилка. Потрібно домовлятися про чіткі критерії, які можна виміряти. Інакше в певний момент виявиться, що поняття «швидкий застосунок» ви з клієнтом розумієте по-різному. Але вже буде пізно щось виправляти.

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

Звучить складно, тому розгляньмо знову на прикладі з мого досвіду. Було звичайне discovery. Ми з клієнтом почали обговорювати нефункціональні вимоги. На той момент уже було зрозуміло, що потрібно працювати із сервісами AWS, щоб зменшити витрати на DevOps і налаштування інфраструктури. Коли дійшли до обговорення доступності (availability) застосунку, клієнт сказав, що хоче 99,98%.

На моє питання, чому саме така цифра, він не відповів нічого суттєвого, тільки сказав, що десь чув і все. Для загального розуміння тут варто зазначити, що загалом ті сервіси Amazon, які ми збиралися використовувати, мали доступність 99,95%. Коли я почав йому пояснювати, що для забезпечення доступності 99,98% нам треба буде робити нестандартне рішення, яке значно підвищить вартість проєкту, замовник погодився на 99,95%. Якби ми це не обговорили, то або проєкт врешті обійшовся б клієнту набагато дорожче, або він би залишився незадоволеним нашою роботою.

Якщо вас цікавить, як правильно підготуватися до фаз discovery і pre-sale, що може піти не так і як уникнути типових помилок, рекомендую прочитати мою книжку Consulting Outbreak: Manager and Software Architect Could be Friends .

Типові помилки в дизайні архітектури

Помилка 1. Не думати про безпеку на етапі дизайну архітектури

Усі проєкти, з якими я стикався, мали проблеми з безпекою. Навіть світові відомі бренди їх мають, що вже казати про менші компанії.

Більшість проблем виникає через неправильний дизайн системи на початку проєкту. Як зазвичай розробляють проєкт? Приблизно так: зараз швидко напишемо функціонал, перевіримо, чи він працює, і якщо все добре, то в самому кінці прикрутимо авторизацію. Потім виявляється, що застосунок повинен підтримувати кілька тенантів (tenants), бути сумісним з GDPR і так далі. І щоб не переписувати всю аплікацію, розробники потроху додають швидкі, але не найкращі рішення у вигляді атрибута, який іде крізь декілька десятків методів, або перевірки ролей користувача, прибитої цвяхами в коді перед викликом кожного контролера. І ще багато таких речей, які ви самі бачили не раз. (До речі, маєте цікаву історію? Напишіть її в коментарях. Автору найцікавішої історії про безпеку чи її відсутність я подарую електронний примірник своєї книжки.)

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

Тому ви як архітектор або технічний лідер, проєктуючи систему, на старті зробіть так, щоб ваш функціонал безпеки не був жорстко пов’язаний з бізнес-логікою і за потреби міг розширюватися. Якщо у майбутньому ви вирішите додати функціонал SSO, декілька тенантів або багатофакторну автентифікацію, це можна буде зробити без великих зусиль.

Якщо ви вже отримали проєкт у такому стані, тут можу вам тільки побажати терпеливості. Бо, як я вже сказав, універсального рішення не існує.

Помилка 2. Труднощі з моделями даних

Ще одна велика проблема — це неправильне використання бази даних. А якщо є вибір між SQL і NoSQL, то маємо вже навіть дві проблемі.

Ми використовуємо SQL-базу даних як NoSQL-рішення. Кілька разів мені траплялися рішення, коли SQL-базу намагалися використовувати як NoSQL-рішення. Можливо, ви теж таке бачили.

Таблиці на 200–250 стовпців, та ще й називаються column1, column2 тощо. Звісно, у тих таблицях повна денормалізація без жодної узгодженості (consistency) даних. А ще можна натрапити на об’єднання двох таких таблиць.

Друга реалізація цього антипатерну має такий вигляд. Є тільки декілька стовпчиків, наприклад id, refId, тип значення і саме значення. І як ви вже зрозуміли, об’єкт збирається за refId з багатьох рядків у таблиці, а потім для кожного атрибута в цьому об’єкті отримується його значення і тип.

Звісно, як під час першої, так і під час другої реалізації виникають проблеми з продуктивністю і підтримкою коду.

У більшості ситуацій тут справи трохи ліпші, ніж з безпекою, бо такі зміни легше локалізувати та зробити потрібні виправлення. Зробіть окремий шар коду, який буде відповідати за доступ до цих даних і, якщо буде змога, використайте NoSQL-базу даних для таких випадків. Цей варіант підходить, якщо вам не потрібно багато join-операцій і генерації різного типу звітів.

Якщо це новий проєкт, то після вищеописаних прикладів і проблем всім очевидно, що краще витратити час архітектора і бізнес-аналітика на дизайн моделей даних. Бо в майбутньому такі незначні речі можуть призвести до великих проблем на проєкті.

І це відповідь на питання, чи варто залучати архітектора і бізнес-аналітика на подальші фази імплементації після discovery, чи команда розробників сама все зробить як треба.

Користуємось NoSQL-базою даних, але щось пішло не так. Звісно, що тут думати? Береш NoSQL-базу даних, і жодних проблем. Вона і добре масштабується, і дає змогу легко працювати зі структурами даних — що не покладеш туди, все буде збережено. Так думає більшість малих проєктів і стартапів. І це було б ок, якби вони з часом не перетворювались на комерційні проєкти зі складнішою бізнес-логікою.

Ось кілька прикладів, коли розробники та архітектори вчасно не зрозуміли, що треба змінити базу даних, поки ще не стало пізно. Якщо ви помічаєте таку логіку і у себе в коді, теж варто замислитися.

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

Якщо ви цього не розробляли, але повинні з цим працювати, чітко зрозумійте свої цілі. Якщо не плануєте велику трансформацію і розроблення нового функціоналу, наприклад перероблювання моноліту у мікросервіси, то є сенс терпіти й витрачати час на підтримку. Це буде швидше, дешевше та краще для бізнесу, ніж вносити значні зміни з ризиком щось зламати.

Якщо вам все ж таки треба розпиляти цей моноліт на малі сервіси, переробляйте наявний код. Але будьте обережні. Оцініть усі ризики, додайте тести, яких, найімовірніше, немає, порахуйте, скільки на це потрібно часу і грошей.

І третя опція — будуйте малі сервіси біля наявного моноліту. Вже з правильною структурою даних. Якщо це можливо у вашому проєкті.

Помилка 3. Наш малий стартап перетворився на успішний, але громіздкий моноліт

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

Можливо, ви помічали, що коли намагаєтеся переконати замовника в необхідності переробити частини проєкту, наприклад винести певну логіку в окремий сервіс, то натрапляєте на опір з боку архітектора чи CTO компанії. Вони наче й розуміють потреби в змінах, і з погляду бізнесу це раціонально, але не наважуються зробити перший крок.

Усе тому, що вони самі писали цей код три роки тому. А як же можна «вбити» власну дитинку? Вона ж така гарна і загалом працює. Все зводиться до «цього разу ще допишемо шматочок функціоналу, а наступного разу вже точно винесемо в окремий сервіс».

І це повторюється щоразу. Кожен такий шматочок коду — це плюс кілька тижнів у скарбничку технічного боргу. Кожне таке рішення робить підтримку наявного функціонала і розробку нового все складнішою та дорожчою.

Можливо, ви бачили такі проєкти, на яких тільки для підтримки та виправлення помилок можуть працювати до двадцяти людей. Розробник витрачає тиждень на налаштування середовища розробки з нуля. А щоб знайти помилку, а тим паче її виправити, потрібно ще не менше як тиждень. Ось на таких монстрів і перетворюються стартапи, в яких діють за принципом «а може, допишемо ще шматочок коду».

Що ж робити? Є принаймні дві опції.

Для малих проєктів і команд — коли настає той самий момент вносити зміни в дизайн проєкту, технічний лідер в п’ятницю ввечері каже всій команді більше не чіпати код до понеділка, бере піцу, пиво, каву і за вихідні вносить суттєві зміни в проєкт. Пам’ятаю, сам так робив.

Для великих комерційних компаній — потрібно мати список завдань з технічним боргом проєктів, який міститиме всі необхідні зміни в архітектуру і дизайн. І команда частину робочого часу (скажімо, 10–15%) буде витрачати на задачі з цього списку.

Помилка 4. Ми ще не в продакшені, але вже маємо проблеми з продуктивністю (performance)

Це типова помилка. Не повірив би, що таке буває, якби не бачив схожі кейси.

Якось нас покликали поліпшити продуктивність проєкту. Проблема була така: проєкт ще не в продакшені, але його тестували на 200 користувачах і виявили проблеми з продуктивністю, запуск відбудеться за кілька місяців, після чого ще за кілька місяців очікується 5–10 тис. користувачів.

Ми почали розбиратися. Швидко знайшли багато проблем з продуктивністю, і з коду було видно, що його ніхто сильно і не старався писати під більш-менш нормальні навантаження. Це було дивно, оскільки ті, хто за це відповідав, могли виконати роботу набагато краще. Потрібно було зрозуміти, чому так сталося.

Виявилося, що цей код писали для перевірки концепції (Proof of concept), і не передбачалося, що його будуть використовувати на комерційному проєкті. Але замовник мав доступ до коду, оскільки вся робота велася в клієнтському середовищі. І він вирішив довести його до презентабельного вигляду і виходити з ним в продакшен. Однак після тестування на невеликих навантаженнях зрозумів, що такий підхід не працює і потрібно поліпшити продуктивність.

Усі розумні книжки кажуть: якщо ви пишете якийсь POC або Spike, то повинна бути мертва гілка з кодом. Його треба викинути на смітник і ніколи не використовувати в комерційному проєкті.

Ще один приклад, показовий як для цього розділу, так і для попереднього. Якось під Новий рік ми з колегою писали якісний, гарний код, як то належить робити для комерційного проєкту. Працювали над ним удвох протягом двох тижнів. А коли почали тестувати його навіть на малих навантаженнях, побачили, що продуктивність була вдвічі нижча за очікувану. Провівши дослідження, ми знайшли рішення для продуктивності, яке підходило набагато краще. Помилка була в тому, що ми не зробили швидкий РОС і не протестували продуктивність до того, як писати код. Але мораль цієї історії інша.

Ми не посоромилися сказати замовнику, що цей підхід поганий, що ми припустилися помилки й місяць праці однієї людини треба викинути у смітник. Хоча могли це приховати, зробити якісь поліпшення і це не було б одразу помітно. Проблемою то вже стало б у продакшені на великих навантаженнях. Але яку ціну довелося б заплатити в цьому випадку?

Тому не соромтеся викинути код, який або з самого початку не був призначений для комерційного проєкту, або так вийшло, що він поганий і призведе до проблем у майбутньому. Це краще, ніж прирікати на вічні муки розробників, які будуть його підтримувати.

Помилка 5. Ми вже в продакшені, але досі не знаємо, чому в нас проблеми з продуктивністю

У таких випадках все (або майже все) написано добре, як має бути в комерційному проєкті. Але проблеми з продуктивністю все одно виникають. Коли було 500 користувачів, усе працювало нормально, а коли стало 200 тис., сповільнилося невідомо чому. Знайома картина?

Головна помилка таких проєктів у тому, що вони надто пізно починають думати про продуктивність. Ці питання треба ставити, коли ви тільки стартуєте розробку:

Можу дати кілька порад для таких кейсів. Звісно, краще це реалізовувати на етапі розробки, але для вже готового проєкту вони теж підходять.

Ще коли тільки починаєте проєктувати застосунок, подумайте, як ви будете вимірювати та контролювати метрики продуктивності на рівні бази даних, сервісів, інфраструктури тощо. Є комерційні рішення, такі як New Relic, Datadog, які без великих витрат часу допоможуть вам усе налаштувати. Якщо ви не хочете за них платити, можете розгорнути схожі системи самі, але це займе більше часу. Це можуть бути ELK (Elasticsearch, Logstash, Kibana) або EFK (Elasticsearch, Fluentd, Kibana) stack.

Налаштуйте статичні аналізатори коду, як-от Sonarqube. Вони допоможуть знайти типові помилки, пов’язані з продуктивністю коду, неоптимальні рекурсивні виклики, можливо, нескінченні цикли й так далі. Звісно, найцікавіші помилки вам доведеться шукати власноруч, але аналізатор допоможе хоча б частково зробити код чистішим і кращим.

Пам’ятайте про performance і load тестування. Робіть ці тести максимально наближеними до реальності. Якщо ваше завдання — протестувати тисячу одночасних користувачів, то не намагайтеся спростити собі життя і зробити тисячу викликів одним користувачам, це не те саме. Якщо вже зробили performance-тести, то перевірте різні сценарії, так щоб був запас. Оскільки, наприклад, до тисячі користувачів може бути все гаразд, а після — різкий спад продуктивності.

У нас на проєкті одного разу була така ситуація, коли забули вимкнути load-тести на вихідні. І в понеділок на ранковій нараді технічний лідер сказав, що має дві новини — хорошу і погану. Погана полягала в тому, що за вихідні ми витратили зайві 400$ на ресурси Amazon, а хороша — наш застосунок витримує навантаження вдесятеро більше, ніж те, що потенційно буде на продакшені.

Думайте, коли пишете код, і постійно перевіряйте код ваших колег (code review), оскільки найцікавіші помилки завжди знаходить людина. Досі можна побачити такі шедеври, як витягання всіх 100500 сутностей з таблиці, а потім на frontend-стороні розбиття на сторінки (pagination).

Помилка 6. Клієнти раніше за розробницьку команду помічають помилки й самі на них вказують

Ця остання порада може прозвучати банально, сумно і смішно одночасно, але, повірте, її актуальність складно переоцінити.

Робіть нормальне логування! Це не так складно, і його можна зробити всюди — на старому проєкті, на новому, на моноліті, на мікросервісах. Є багато комерційних рішень, які допомагають із цим.

Думаєте, що це просто? Може й так, за моїми спостереженнями 20–30% проєктів досі мають проблему з логуванням.

Розповім про цей процес на прикладі одного проєкту. Всі помилки перехоплював один-єдиний обробник, який намагався пересилати то на пошту адміністратора. Ця електронна адреса була записана у самому коді. Звісно, що більша частина середовищ розробки та тестування (dev, stage and test environments) були навіть не налаштовані. Але схоже, що і для продакшену цей підхід не дуже працював. Бо процес повідомлення про помилку і з’ясування, в чому справа, виглядав так: у клієнта виникала проблема із застосунком — він телефонував у технічну підтримку і повідомляв про це. Розробник йому пояснював, як відкрити панель розробника у браузері та зробити знімок екрана так, щоб було видно помилки, які з’явилися в графічному інтерфейсі аплікації, і помилки, які пишуться в консоль панель розробника у браузері. Клієнт надсилав цей знімок у підтримку для подальшого дослідження проблеми.

Може, простіше зробити логування?

Щоб не закінчувати на сумній ноті

Якщо хтось з моїх колег впізнав у наведених прикладах свій проєкт, то це лише збіг, бо проблеми у всіх однакові. Не беріть це близько до серця :)

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

Це все базується лише на моєму досвіді. Можливо, я щось пропустив або не надав значення іншим помилкам, які теж значно впливають на успіх проєкту. В такому разі пишіть у коментарях про свій досвід і що, на вашу думку, може заважати розвитку проєкту.

Бажаю вам вчитися тільки на чужих помилках і успішно реалізовувати проєкти!

Опубліковано: 23/03/21 @ 08:00
Розділ Різне

Рекомендуємо:

Что нужно учитывать менеджеру, чтобы не переделывать проект с нуля
Софт из 90-х VS микросервисы: что банки могут перенять у финтех-компаний
Вывод в топ 10 сайта по продаже спецтехники
Работать нельзя отдыхать. Почему трудоголизм в IT вреден и что делать, чтобы не перерабатывать
Как перейти из тестирования в разработку и дорасти до Senior. Советы из личного опыта