Галоўная / Артыкулы

12 прыткіх правіл для надзеяных API на Node.js

Практычныя правілы надзержання над адрысамі API Node.js: таймауты, ідэмпатэнтнасць, транзакціі, анвалідаванне кэша, логаванне і затрымкі у залежнасцях — прытаму до старонкі за 3 гадзіны ночы.

Выдавец: REACTAPP.TOP4 хв чытання906 слоў

Крыніцы: 12 Rules of Thumb for Building Node.js APIs That Don’t Wake You Up at 3 AM

Дзеяныя наследства з абыякласнасцю частаўляюцца толькі пасля перыву службы. Дванаццаць пунктав, прыведзеных ніжэй, з’яўляюцца дастатнь часта ў разных службах на базе Node.js, таму яснае ўказванне іх дэшэўша, чым прабава зноў іх аднаходзіць пад тым пяснем, калі трэба негайна дзеяць. Спрыймайце іх як стандартныя правілы пад час праектавання працоўнікаў апрацоўкі запытав, а не як дапаможныя элементы пасля запуску.

1. Запытавы, якія можна перадаць знову, будуць пераданы зноў.

Не «можа буць». Кліенты выкананяюць тайма-аут, з’язні рываюцца ў момант адпаведзі, а люды натыкаюць на кнопку выканання. Балансірывачы навантажэння і мобайльныя сеткі ствараюць дадатковыя копіі дадзеных. Кожны працоўнік, які стварае або мяняе стан дадзеных, патрэбуе чыстаю адпаведзь на запыт «што, як такі ж пакет дадзеных прыйдзе зноў», таму што за дастатнь адлеглы час гэта не будзе экстрэмальны случай — гэта немінучае. Праектаваўцы патрэбуе разам праектаваць як шлях успеху, так і шлях дублікацыі.

2. Кожнам выходзячым запытаву паказваць тайма-аут.

Запыты даўеджніка, HTTP-звязі з трэцімі сторонамі, платэжныя прыемнікі — калі вы не вказаеце канечную дату, праця якога-небудзь компонента можа застацца з ачытым сокетам на неакранічаны час. Простае выкліканне fetch(url) не ўможлівляе «тэрпячка на певны час»; гэта неакранічана адліквідацыя, і такая адліквідацыя можа змусіць сповольнюючы компонент заморозіць усё, што знаходзіцца вышэй у ланцугу. Лепей выбіраць стандартныя настройкі бібліятак, якіе встановляюць ліміт, і пры невыпанні задачы спрацоўваць з явнымі паведамленнямі пра адпрацоўку зноў чы ў форме паведамленняў для корыстніка, а не працаваць без жадных сігналоў.

3. Перакананні браузера — гэта частка UX, а не захоўні мур.

Корыстнікі можу праігнораваць ваш SPA і звяжыцца з API за дапамогою будзь-каго JSON, выкарыстоўваючы curl, Postman чы компрометаваны скрыпт. Правіла, якія маюць значэнне — правільна сформаваны электронны паштовы адрэс, ненегатыўная цэна, обав’язковыя поля — павінны зноў быць перакананы на серверэ з той жа строгосцю, якую вы бы застосавалі да ворагоўскага трафіку. Перакананні на боку кліента дапамагаюць толькі савершэнна супрацоўным корыстнікам, якія і так не нарушылі б умовы.

4. Кэш без процедуры анулювання — гэта затрыманный баг.

Кэшаванне стварае другую копію дадзейнаў, і гэтыя копіі пачынаюць разлікваваць. Калі вы вводзіце кэш, неабходна адначасова выбраць, які запіс, вебхук чыя TTL-падзея яго анулюе, і задокументаваць гэты выбор пры самай ключ-значэння кэша. Палежнасць ад ідэі, што “яны выгораюць калі-небудзь”, часта означае “дольшы тымчас, чым кліянты зможуць вытрымаць некарэктныя балансы”, особаўска калі TTL-вырахоўванні ведаецца за гадзіны пад прэтэкстом “парадку”.

5. Запісы, якія выкананы адночасна, патрабуюць транзакцыі, а не оптымізма.

await update1(); await update2(); выглядае як атамічны запіс, але такім не ёсць. У перыяд между await-амі крах, паталогія чы працоўная памятка можу заставіць выканацца толькі адні запіс, і самэ гэта прыводзіць да розніцы между інвентаром і счытанням. Толькі рэальная транзакцыя базы дадзеных — або явна сага з компенсуючымі дзеяннямі — можа закрыць гэты перыяд з гарантыямі, пра якія можна рассуждаваць.

6. Апарат для інцыдэту, які вы ўсё ўтолькі не бачылі.

Калі ўсё зламваецца, вельмі пазнела дадаць рэкорд, які мог бы ўсё гэта поясніць. Структураваныя логі, ідэнтыфікаторы корэляцыі, якія пераходзяць межаў разных служб, і достатні кантэкст для рэканструкцыі запіту, які надаўся прычынай адказу, перамагаюць нават самыя хітрыя сеансы дэбаггіну пасля аналізу прычын. Лог-даны, якія можна без апасцерагаў заставіць, рэзультаты дзеянняў і зволікання ў выкарыстоўванні рэсурсаў, калі сістэма працуе нормальна.

7. Памяць процэса — гэта кеш, а не сістэма зберагчыка даных.

Значэнне, якое існуе толькі ў процэсе Node, знікае пасля перзапуску, ёсць невідальным для іншых экземпляраў таго ж процэса і ніколі не ёсць стойкім. Флагі функцый, якія зберагваюцца ў RAM, лічыльнікі чы “тэмпаратарныя” кашы, усе яны маюць такую ж долю. Калі ўжо трэба, каб даны перазсталі пасля аплыву, збою чы балансавання навантажэння без стойкіх сесый, то іх трэба зберагваць у базе дадзеных чы іншам стойкім сховішчы, а не ў віпадковай ячэйцы RAM.

8. Планавайце так, каб кожны сяброўскі вызов з часам не выканаўся.

Корыстны вопыт — не «чы гэта зазвычай работае?», а «што будзе ў рэдкім случаю неудачы?» Таймауты, частковыя адпаведзі і спады кода 5xx таксама маюць значэнне. Якшто чыстая адпаведзь — «незрозумела», запыніце гэтыя проблемы за дапамою безпечных пракатанняў, прыемнікаў на выключэнне цяга або сценарыёў з паслабленым функціянаванням, прычаму ўжо па-ранейшаму не з’яўіцца проблемы.

9. Чарга перапланавае работу; яна яе не вычыраюць.

Даўленне элемента ў чаргу створвае вражанне, што работа завершылася. Рабочы элемент працюе ўсё той самы час, з тымі ж можлівымі неудачамі, проста ў іншы момант. Якшо рабочыя элементы запазджаюць, кількасць незавершаных задач расце, хоця API застаецца адпаведным — гэта лепшая, чым блакуванне запытоў, але не значыць, што работа будзе танней. Размір спожывачаў і шляхоў для некорэктных паведамленняў трэба нарабатываць так жа рэтэльна, як і размір HTTP-слоя.

10. Давайце назвы для чытачаў, якія будуць актуальныя шасць месцаў, а не для трымкі сённяшняга спрытку.

data, temp і handleStuff застаюцься точнымі толькі пакуль тры ўсё іншыя панявы таксама не будуць атрыбутаваны як “data”. Назвы, зв’язаныя з бізнес-ідэяй, застаюцься разумнымі для чытачаў без жаднага кантэксту — укладзецца ў тое, каб будучыя версіі вас на незнайомай службе таксама моглі іх зрозумець. Лепш выбіраць іменнікі, які апісваюць сутнасць, чым механічныя дзеяння, які опісваюць першыя дэталі рэалізацыі.

11. Стваральнікі будуць вызываны два разы.

Нестабільныя сеткі, агрэсыўныя кліенты для павторных спроб, нетэрплівыя дзве клікі — гэта можа быць што-небудзь з гэтага. Запыты POST для стварэння трэба обрабоцваць так, каб усунуцца рызык дуплікацыі, зазвычай за дапамою ключа ідэмпатэнтнасці, які зберагаецца разам з рэзультатным рэсурсам; інакш могуць выйсці подвойныя платэжы і дуплікаты замовленняў, якія будуць вызваны разніцай у часе. Калі ўсё ужо створана, трэба вярнуць первісны рэзультат, а не які-небудзь новы пасляэфект.

12. Затрымка на канцы ўзьязку залежыць ад найпамедлівейшай залежнасці.

Ўтылкі, які адпрацоўваюць запыткі, якія не ў індэксе, або удаленыя API без тайма-ауту, все равно працуюць медленна. Аналіз своіх власных кодавых ліній, ігнаруючы параметры, якія надаюцься ззовні, дае некарэктныя рэшты. Памеры па параметрамі p95 і p99 трэба атрымваць для всіх элементаў карто гэтаў, а пасля — выправіць проблемы з індэксамі, групаванням задач і тайма-аутамі там, дзе насправды вітрачаецца час.

Ніякі з эых саветаў не ёсць выказной, і самэ гэта і ёсць сутніцэю: сторанкі, якія працуюць у трох адночы, рэдка калі бываюць выказнымі. Яны зазвычай належаюць да адных з гэтых дванаццаці катэгорый і застаюць без увагі, пакуль не перэстануць казацца справай нявыбаглівай. Ствараюце простыя захоўнікі ў момент, калі сервіс яшчэ достатна маленькі, ўбачлівы для змян.