Головна / Статті

Понад P95: вимірювання затримки, яку насправді переживають ваші користувачі

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

Видавець: REACTAPP.TOP17 хв читання3974 слів

Джерела: Your P95 Latency Is Lying to You.

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

У наступних розділах пояснюється, чому прийнятне значення P95 та повільна робота продукту можуть існувати одночасно. Ви дізнаєтесь, де затримки приховуються від показників рівня обслуговування (черги, повторні спроби, розподіл завдань, блокуючі рішення), чому „хвіст“ даних має більше значення, ніж може здатися за його розміром, та як проста звичка вимірювати час виконання кожного кроку запиту допомагає перетворювати нечіткі скарги на конкретні докази. До кінця ви зможете конструктивно ставитися до тверджень на кшталт „P95 у порядку“, замість того щоб або приймати їх, або ігнорувати.

Що повідомляє та чого не повідомляє P95

Варто бути точним, перш ніж критикувати цей показник. P95 — це значення, на рівні або нижче якого виконується 95 відсотків виміряних запитів. Це справді корисна цифра, яка значно краща за середню затримку. Середнє значення — це те, де зникають проблеми в продакшені: якщо дев’яносто дев’ять запитів виконуються за 50 мс, а один — за п’ять секунд, середнє буде приблизно 100 мс, що ніхто не буде використовувати для оцінки. Перцентиль принаймні спрямовує вашу увагу на крайні значення розподілу.

Отже, сам відсоток не є проблемою. Проблема полягає у тому, яку роль команди йому надають після його прочитання. Фраза «P95 — усе гаразд» часто виступає своєрідним сертифікатом невинуватості, який завершує дискусію. Такий підхід мовчки ігнорує щось основне: ніхто з користувачів вашого продукту не сприймає відсотки. Люди стикаються з процесом очікування. Вони натискають кнопку та замислюються, чи було це натискання зафіксовано. Вони бачать сторінку, яка, здається, відображається, але не реагує. Вони спостерігають за індикатором завантаження, поки кілька сервісів за його фоном повідомляють абсолютно нормальні показники.

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

Під час кожного запиту працюють три «годинники»

Більшість обговорень щодо затримок припускають наявність одного «годинника». Насправді їх принаймні три, і вони вимірюють різні речі.

  • Годинник сервера. Надходить запит до вашого сервісу, виходить відповідь — таймер зупиняється. Саме це відображають більшість панелей керування backend.
  • Годинник залежностей. Під час обробки запиту та навколо неї витрачається час на автентифікацію, очікування підключення до бази даних, внутрішні HTTP-запити, невдачі у кешуванні, повторні спроби, роботу з чергами, перевірку флагів функцій, використання API сторонніх постачальників та всі компоненти, які „зазвичай працюють швидко“.
  • Годинник користувача. Користувач натиснув, потім чекав, поки екран стане придатним для використання. Це єдиний проміжок часу, який має значення для користувача.

Команди зазвичай оптимізують час виконання на початковому етапі, а потім описують продукт як швидкий. На малюнку нижче ці три показники показані поруч: сервіс повідомляє про час виконання 180 мс, тоді як ланцюг залежностей включає спробу повторного запуску, яка займає 600 мс, і людина за клавіатурою все ще запитує, чому сторінка завантажується.

SERVER CLOCK

request in  ------------------------------> response out
              "API P95: 180ms"

DEPENDENCY CLOCK
request in  ---> auth ---> db ---> service A ---> retry ---> service B ---> response out
                 40ms    70ms      120ms        600ms       90ms

HUMAN CLOCK
click  ----------------------------------------------------------------> usable screen
       "Why is this still loading?"

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

Кінцева точка — це двері, а процес використання продукту — це будівля

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

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

User Clicks "Open Dashboard"
        |
        v
+----------------------+
| Frontend Shell       |
+----------------------+
        |
        +------> GET /profile
        |
        +------> GET /permissions
        |
        +------> GET /accounts
        |
        +------> GET /offers
        |
        +------> GET /notifications
        |
        +------> GET /limits
        |
        v
Screen Finally Becomes Useful

Кожен з цих шести кінцевих пунктів може здаватися працездатним окремо, тоді як весь процес в цілому виглядає несправним. Сервіс може дотримуватися своїх умов SLA та водночас сприяти повільній роботі продукту. Команда може досягти власних цілей, але все одно погіршувати якість користувацького досвіду. Коли виклики здійснюються послідовно, їхні затримки накопичуються; коли вони виконуються паралельно, найповільніший виклик визначає темп, а обмеження на кількість з’єднань браузера або залежності між викликами можуть призвести до серіалізації роботи, яку ви вважали паралельною.

Саме тому фраза „наш API швидкий“ є початком розслідування, а не відповіддю. Наступні запитання є некомфортними, але необхідними: швидкий у порівнянні з чим, для кого та як вимірюється швидкість? В межах вашого сервісу чи з моменту натискання користувачем кнопки?

Решта п’ять відсотків — це не похибка округлення

Назва „P95“ створює враження, ніби проблемна частина є незначною. П’ять відсотків здається прийнятною ціною для масштабованої роботи, щось таке, що може бути перенесене за допомогою спокійного екологічного комітету.

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

Навіть таке формулювання занадто спрощене, адже повільні запити не розподіляються рівномірно між користувачами:

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

На панелі керування видно розподіл даних. Постраждалий користувач стикається з чимось особистим. З точки зору системи частина запитів виконувалася повільно; з точки зору користувача продукт конкретно марнував його час.

Саме тому скарги користувачів варто розглядати як дані. Люди не повідомляють про проблеми у вигляді відсотків; вони розповідають історії. „Кожного разу після натискання кнопки «Надіслати» програма зависає“. „Сторінка з’являється, але дані надходять з запізненням“. „Мені доводиться перезавантажувати двічі“. „Все працює, але працює повільно“. Жодна з цих скарг не є розпливчастою. Кожна з них — це звіт про продуктивність, написаний простою мовою, а спільною проблемою є перетворення цих описів на неправильні показники та висновок про відсутність проблем.

Два сервіси, один показник P95 — дуже різні ризики

SERVICE A

Most Requests        120ms - 260ms
Slow Requests        300ms - 380ms
Disaster Requests    Rare

SERVICE B

Most Requests        40ms - 80ms
Slow Requests        300ms
Disaster Requests    8s - 12s

Обидва можуть показувати приблизно однаковий показник P95. Лише у сервісу B є „підступна“ ситуація – його продуктивність знаходиться повністю за межами 95-го відсоткового інтервалу, тож цей показник її не враховує. Щоб побачити цю різницю, потрібно подивитися на показники P99, P99.9 та максимальні значення, або ще краще – на гістограму чи теплову карту затримок.

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

Практичне правило: панель керування з перцентилями має започатковувати діалог, а не закривати його. Питання полягає не лише у тому, „який у нас P95?“, а й у тому, „яка проблема стоїть за цим числом?“

Найгірша затримка існує між командами

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

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

У таких випадках система не повільна в жодному конкретному місці. Вона повільна у з’єднаннях між компонентами:

  • під час передачі даних між сервісами;
  • під час повторної спроби, яка подвоює тривалість виклику;
  • під час другого запиту, який взагалі не повинен був надсилатися;
  • під час перевірки дозволів, яка виконується після того, як вже розпочалася дорога обробка;
  • під час невдалих спроб звернення до кешу, які залишаються непоміченими, оскільки обробка запиту все одно завершується до досягнення порогового значення для сповіщень;
  • у сервісі сторонньої організації, який усі називають „зовнішньою залежністю“, що звучить менш незручно, ніж визнати, що це частина користувацького досвіду;
  • у черзі, ще до того, як почнеться виконання вашого коду;
  • під час серіалізації, після завершення обробки бізнес-логіки;
  • на фронтенді, оскільки API повертає дані, створені для бази даних, а не для екрана, і клієнту доводиться їх переформатувати.
  • P95 не вводила нікого в оману своєю хибністю. Вона вводила в оману тим, що була єдиною. Ізольований показник дозволяє кожній команді демонструвати свою невинуватість, поки користувач продовжує чекати.

    Час, проведений у черзі, все одно є затримкою

    Існує ще одна більш тонка проблема вимірювання: таймери на рівні додатку часто починають працювати занадто пізно. До того часу, як ваш обробник або контролер починає виконуватися, запит може вже деякий час чекати у балансувальнику навантаження, чекати на з’єднання, чекати на робочий процес або потік, або ж чекати після інших операцій, оскільки процес формально працював, але фактично був перевантажений. У Node.js цей самий ефект проявляється у затримці циклу подій: активний цикл означає, що функції-відповіді, включаючи ваш обробник запиту, починають виконуватися пізніше, ніж сокет отримує дані.

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

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

    Найменування кожного етапу запиту

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

    Наведений нижче фрагмент — це обробник у Spring Boot на Java, але ця схема може бути безпосередньо застосована в Express, Fastify чи NestJS. Для запиту GET /home ініціюється об’єкт LatencyTrace, який пов’язується з заголовком X-Request-Id, що надходить. Кожен значущий крок — завантаження користувача, отримання дозволів, виклик служб обліку та пропозицій, а також формування відповіді — обгортається функцією trace.time(...) із описовою міткою. У блоку finally функція trace.logIfTotalCrosses(Duration.ofMillis(700)) виводить деталі лише тоді, коли загальний час обробки запиту перевищує 700 мс; таким чином журнал залишається тихим для нормального трафіку та містить деталі для повільного. Саме впровадження менш важливе, ніж звичка, яку воно формує.

    @GetMapping("/home")
    public HomeResponse home(@RequestHeader("X-Request-Id") String requestId) {
        LatencyTrace trace = LatencyTrace.start("GET /home", requestId);
    try {
            User user = trace.time("db.user", () ->
                userRepository.findActiveUser()
            );
            Permissions permissions = trace.time("auth.permissions", () ->
                permissionClient.fetch(user.id())
            );
            List<Account> accounts = trace.time("accounts.http", () ->
                accountClient.fetchAccounts(user.id())
            );
            List<Offer> offers = trace.time("offers.http", () ->
                offerClient.fetchEligibleOffers(user.id())
            );
            return trace.time("response.mapping", () ->
                HomeResponse.from(user, permissions, accounts, offers)
            );
        } finally {
            trace.logIfTotalCrosses(Duration.ofMillis(700));
        }
    }
    

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

    Порівняйте те, що дає звичайний журнал затримок, з тим, що дає цей інструмент. У звичайній версії є лише один рядок із загальним значенням:

    GET /home took 1180ms
    

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

    GET /home took 1180ms
    
    db.user              42ms
    auth.permissions     81ms
    accounts.http        156ms
    offers.http          823ms
    response.mapping     28ms
    

    Коли такий результат показують перед групою, тон дискусії змінюється. Нікому не потрібно здогадуватися чи захищати власний сервіс, а фраза „у мене все працює“ більше не є корисним внеском. Пропозиції щодо облікових записів становлять приблизно 70 відсотків запитів, тож розмова переходить від думок до доказів. Ось справжня перевага хорошого інструментарію: не більше графіків, а менше суперечок.

    У кодбазі Node.js ви можете досягти такого ж ефекту, розмістивши performance.now() біля кожного виклику, який очікує на результат, та використовуючи структурований логгер, або більш систематично — за допомогою OpenTelemetry spans, які зберігають однакові назви кроків між межами сервісів, щоб аналіз залишався корисним навіть тоді, коли повільний крок знаходиться у чужому сервісі. Для більш детального ознайомлення з поєднанням журналів подій, метрик та трекінгу дивіться створення спостережуваних API Node.js.

    Чому чисті тестування продуктивності можуть виправити хаотичну систему

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

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

    • Бенчмарк тестує один кінцевий пункт; справжня дія користувача активує багато з них.
    • Бенчмарк виконується з попередньо завантаженими кешами; користувачі з’являються після розгортання, видалення даних та через проблеми з холодними шляхами виконання коду.
    • Бенчмарк вимірює успішні відповіді; користувачі стикаються з частковими помилками, повторними спробами, таймаутами та недійсними екранами.
    • Бенчмарк передбачає стабільні залежності; у продакшені залежності залишаються стабільними аж до моменту, коли це вже не так.
    • Бенчмарк ізолює одну службу; те, з чим стикається користувач, складається з багатьох служб разом із браузерами, мережами, чергами, контрактами API та рішеннями команд, які можуть більше не спілкуватися між собою.

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

    Швидкий код не гарантує швидкого продукту

    Багато інженерів, які працюють з бекендом, вважають локальну оптимізацію дуже задовільною. Ви скорочуєте час виконання функції з 20 мс до 8 мс, усуваєте непотрібні виділення пам’яті, переструктуруєте цикли, налаштовуєте запити – і результат здається ідеальним. Проте продукт все ще чекає на віддалений сервіс, який на кожен десятий запит виконується протягом 900 мс. Екран все ще довго залишається недоступним, кнопки все ще замерзають, а заявки на підтримку продовжують містити коментарі про „повільну“ роботу.

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

    Коли найповільнішою залежністю є рішення

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

    • Фронтенд викликає шість API, хоча було б достатньо однієї агрегованої відповіді.
  • Кожен екран знову запитує сервіс дозволів, замість того щоб використовувати попередній результат.
  • Повторні спроби виконуються синхронно всередині шляху запиту, призначеного для користувача.
  • Віджет пропозицій блокує відображення всього головного екрана.
  • Події аналітики мають бути виконані перед тим, як користувачеві дозволять продовжити.
  • API повертає об’єкти у форматі бази даних, залишаючи фронтенду завдання з формування значень.
  • Сервіс на наступному етапі обробки позначений як „критичний“, тому що ніхто не хотів стверджувати, що його функції можна завантажити пізніше.
  • Найповільнішою частиною системи часто є вибір продукту, який ніколи не оцінювався, проблема з власністю на ресурси або зустріч, що відбулася давно, а результати якої призвели до постійної затримки. Для багатьох з цих проблем існують відомі рішення, такі як використання backend-сервісу для фронтенду, який об’єднує запити, відкладене завантаження неважливих елементів інтерфейсу, відкладення спроб повторного запуску та аналітики з критичного шляху виконання, а також форматування відповідей з урахуванням розміру екрана. Однак кожне з цих рішень вимагає, щоб у хтось були повноваження змінити прийняте рішення.

    Саме тому робота над продуктивністю стає політизованою, коли прості рішення вже застосовані. Решта затримок перетворюється на питання відповідальності. Хто має право оголосити певну залежність обов’язковою? Хто несе відповідальність за весь процес? Хто може скасувати певний запит? Хто несе відповідальність, коли всі сервіси працюють нормально, а якість користування все одно погана? P95 не може відповісти на жодне з цих питань, і ніколи не призначався для цього.

    Зелені панелі керування можуть зменшити цікавість команд

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

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

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

    Почніть з того, що намагався зробити користувач

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

    • Для відкриття панелі керування вимірюйте час до моменту, коли панель справді готова до використання.
    • Для надсилання форми вимірюйте час від натискання кнопки до з’явлення підтвердження.
    • Для завантаження звіту вимірюйте час від кліку до того моменту, коли файл стає доступним.
  • Для оплати вимірюйте від початку до кінцевого стану з завершеною оплатою.
  • Це здається очевидним, проте багато систем не оптимізовані саме так. Їх вимірювання здійснюється в межах команд, оскільки це просто та дозволяє створювати чіткі панелі керування. Шляхи виконання завдань складніше вимірювати, і результати бувають менш задовільними, а саме ці менш задовільні результати є основою для покращень продукту. З боку клієнта API браузера, такі як інтерфейси Performance та User Timing, дозволяють чітко позначити моменти «клік користувача» та «доступність екрана», а поєднання цих позначок із ID запиту дозволяє пов’язати людський час із записами сервера. Якщо повільність виникає під час відображення контенту, а не через мережу, стаття про діагностику продуктивності React поза межами часу відповіді API розглядає саме цю сторону проблеми.

    Ставіться до показників із обережною настороженістю

    Усе це не є аргументом для видалення P95 з ваших панелей керування. Він належить туди та має значення. Проте його не варто довіряти ізольовано. Хороший відсотковий показник має пробудити у вас більше цікавості, спрямувавши увагу на запити, які знаходяться за межею цього порогу:

    • Хто саме належить до цих п’яти відсотків повільних запитів, і чи це завжди одні й ті самі особи?
    • До яких сценаріїв використання користувачами належать ці запити?
    • Чи якась одна залежність є причиною більшості проблем у цій групі?
    • Чи певний регіон має проблеми, хоча загальна ситуація виглядає нормальною?
    • Чи певний користувач постійно стикається з найгіршими умовами?
    • Чи перезапуски запитів тихо перетворюють невдачі на тривале очікування?
    • Скільки часу запити проводять у черзі, перш ніж навіть почнеться таймер додатку?
  • Чи є якийсь стан фронтенду, який утримує екран у заблокованому стані після того, як бекенд вже надав відповідь?
  • Чи є сервіс теоретично справним, але на практиці шкодить продукту?
  • Правильний підхід до метрики — це не її обожнювання та не відкидання. Це уважна настороженість. Метрика — це свідок, а свідки можуть пропустити важливі речі.

    Ключові висновки

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

    • P95 перевищує середні значення, але приховує форму розподілу, ступінь вираженості „хвоста“ та тих, хто постраждав; поєднуйте його з вищими перцентильними значеннями, гістограмами та розбивкою даних за користувачем чи регіоном.
    • Розрізняйте часи, які використовують сервер, залежності та люди, і переконуйтеся, що кожен з них має відповідального.
    • Шлях користувача зазвичай складається з багатьох кроків; вимірюйте весь цей шлях, а не лише кінцеві точки.
    • Таймери додатків часто не враховують очікування у черзі, час підключення та затримки в циклі подій; вимірюйте ці показники окремо.
    • Вимірювання кожного окремого кроку запиту та запис у журнал подій при перевищенні певного порогу замінює звинувачення на докази.
    • Частина затримок є наслідком рішень щодо продукту та визначення відповідальних осіб, а їх усунення вимагає наявності особи з повноваженнями їх змінити.
    • Розглядайте скарги користувачів як звіти про продуктивність, а панелі керування — як одного з багатьох джерел інформації.