JSON-RPC? Вазьміце хітры REST

JSON-RPC? Вазьміце хітры REST

Упэўнены, што загаловак выклікаў здаровую рэакцыю — "ну зноў пачалося…" Але дазвольце завалодаць вашай увагай на 5-10 хвілін, і я пастараюся не падмануць чаканні.

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

Для таго, каб была яснасць у тым, што такое RPC, прапаную разглядаць стандарт. JSON-RPC 2.0. C REST яснасці няма. І не павінна быць. Усё, што трэба ведаць аб REST - ён неадрозны ад HTTP.

RPC запыты хутчэй і больш эфектыўна, таму што дазваляюць рабіць batch-запыты.

Гаворка ідзе аб тым, што ў RPC можна ў адным запыце выканаць выклік адразу некалькіх працэдур. Напрыклад, стварыць карыстальніка, дадаць яму аватар і ў тым жа запыце падпісаць яго на нейкія топікі. Усяго адзін запыт, а колькі карысці!

Сапраўды, калі ў вас будзе ўсяго адна нода backend, гэта будзе здавацца хутчэй пры batch-запыце. Таму што тры REST запыту запатрабуюць у тры разы больш рэсурсаў ад адной ноды на ўстаноўку злучэнняў.

JSON-RPC? Вазьміце хітры REST

Звярніце ўвагу, што першы запыт у выпадку з REST павінен вярнуць ідэнтыфікатар карыстальніка для выканання наступных запытаў. Што таксама негатыўна ўплывае на агульны вынік.

Але такія інфраструктуры можна сустрэць, няўжо што, у in-house рашэннях і Enterprise. У скрайнім выпадку, у невялікіх WEB праектах. А вось паўнавартасныя WEB рашэнні, ды яшчэ і названыя HighLoad так будаваць не варта. Іх інфраструктура павінна адпавядаць крытэрам высокай даступнасці і нагружанасці. І карціна мяняецца.

JSON-RPC? Вазьміце хітры REST

Зялёным адзначаны каналы актыўнасці інфраструктуры пры тым жа сцэнары. Звярніце ўвагу, як паводзіць сябе RPC зараз. Запыт выкарыстоўвае інфраструктуру толькі па адным плячы ад балансавальніка да backend. У той час, як REST ўсё таксама прайграе ў першым запыце, але наганяе выпушчанае выкарыстоўваючы ўсю інфраструктуру.

Досыць у сцэнар увесці не два запыты на ўзбагачэнне, а, скажам, пяць ці дзесяць… і адказ на пытанне "хто выйграе зараз?" становіцца невідавочны.

Прапаную зірнуць яшчэ шырэй на праблему. На схеме бачна, як выкарыстоўваюцца каналы інфраструктуры, але інфраструктура не абмяжоўваецца каналамі. Важным складнікам высоканагружанай інфраструктуры з'яўляюцца кэшы. Давайце зараз атрымаем нейкі артэфакт карыстальніка. Некалькі разоў. Скажам 32 разы.

JSON-RPC? Вазьміце хітры REST

Паглядзіце, як прыкметна "паправілася" інфраструктура на RPC для таго, каб адказваць патрабаванням высокай нагрузкі. Уся справа ў тым, што REST выкарыстоўвае ўсю моц HTTP пратаколу ў адрозненне ад RPC. На прыведзенай схеме гэтая моц рэалізуецца праз метад запыту - GET.

У HTTP метадаў, апроч іншага, ёсць стратэгіі кэшавання. Пазнаёміцца ​​з імі можна ў дакументацыі на HTTP. Для RPC выкарыстоўваюцца POST запыты, якія не лічацца ідэмпатэнтнымі, гэта значыць шматразовае паўтарэнне адных і тых жа запытаў POST можа вяртаць розныя вынікі (напрыклад, пасля кожнай адпраўкі каментара будзе з'яўляцца чарговая копія гэтага каментара) (крыніца).

Такім чынам, RPC не ў стане эфектыўна выкарыстоўваць інфраструктурныя кэшы. Гэта прыводзіць да таго, што даводзіцца "завозіць" софтавыя кэшы. На схеме ў гэтай ролі прадстаўлены Redis. Софтавы кэш, у сваю чаргу, патрабуе ад распрацоўніка дадатковы кодавы пласт і прыкметныя змены ў архітэктуры.

Давайце зараз палічым, колькі ж запытаў "радзіў" REST і RPC у разгляданай інфраструктуры?

запыты
Уваходныя
да backend
да СКБД
да софт-кэша (Redis)
РАЗАМ

REST
1 / 32 *
1
1
0
3 / 35

RPC
32
32
1
31
96

[*] у лепшым выпадку (калі лакальны кэш выкарыстоўваецца) 1 запыт (адзін!), у горшым 32 якія ўваходзяць запыту.

У параўнанні з першай схемай розніца ашаламляльная. Цяпер становіцца відавочным выйгрыш REST. Але прапаную не спыняцца на дасягнутым. Развітая інфраструктура складаецца з CDN. Часта ён жа вырашае пытанне процідзеяння DDoS і DoS нападам. Атрымаем:

JSON-RPC? Вазьміце хітры REST

Тут для RPC усё становіцца зусім сумна. RPC проста не ў стане дэлегаваць працу з нагрузкай CDN. Застаецца спадзявацца толькі на сістэмы процідзеяння нападам.

Ці можна на гэтым скончыць? І зноў, не. Метады HTTP, як вышэй ужо гаварылася, маюць сваю "магію". І нездарма метад GET з'яўляецца татальна выкарыстоўваным у Internet. Звярніце ўвагу на тое, што гэты метад здольны звяртацца да часткі кантэнту, здольны ставіць умовы, якія змогуць інтэрпрэтаваць інфраструктурныя элементы яшчэ да перадачы кіравання вашаму коду і г.д. Усё гэта дазваляе ствараць гнуткія, кіраваныя інфраструктуры, здольныя пераварваць сапраўды вялікія плыні запытаў. А ў RPC гэты метад… ігнаруецца.

Дык чаму так устойлівы міф аб тым, што batch запыты (RPC) хутчэй? Асабіста мне падаецца, што большасць праектаў проста не дасягаюць такога ўзроўню развіцця, калі REST здольны паказаць сваю сілу. Больш за тое, у невялікіх праектах, ён больш ахвотна паказвае сваю слабасць.

Выбар REST ці RPC гэта не валявы выбар асобнага чалавека ў праекце. Гэты выбар павінен адпавядаць патрабаванням праекта. Калі праект здольны выціснуць з REST усё тое, што ён сапраўды можа, і гэта сапраўды трэба, тое REST будзе выдатным выбарам.

Але калі на тое, каб атрымаць усе профіты REST, трэба будзе наняць у праект дэвапсаў, для аператыўнага маштабавання інфраструктуры, адмінаў для кіравання інфраструктурай, архітэктара для праектавання ўсіх пластоў WEB сэрвісу… а праект, пры гэтым, прадае тры пачкі маргарыну ў дзень… я б спыніўся на RPC, т.я. гэты пратакол больш утылітарны. Ён не запатрабуе глыбокіх ведаў працы кэшаў і інфраструктуры, а сфакусуе распрацоўніка на простых і зразумелых выкліках патрэбных яму працэдур. Бізнэс будзе задаволены.

RPC запыты надзейней, таму што могуць выконваць batch-запыты ў рамках адной транзакцыі

Гэтая ўласцівасць RPC з'яўляецца несумнеўным плюсам, т.к. лёгка ўтрымліваць БД у кансістэнтным стане. А вось з REST выходзіць усё складаней. Запыты могуць прыходзіць непаслядоўна на розныя ноды backend.

Гэты "недахоп" REST з'яўляецца зваротным бокам яго перавагі апісанага вышэй - здольнасць эфектыўна выкарыстоўваць усе рэсурсы інфраструктуры. Калі інфраструктура спраектавана дрэнна, а тым больш, калі спраектавана дрэнна архітэктура праекта і БД у прыватнасці, то гэта сапраўды вялікі боль.

Але ці так надзейныя batch-запыты як падаюцца? Давайце разгледзім кейс: ствараем карыстальніка, узбагачаем яго профіль нейкім апісаннем і дасылаем яму SMS з сакрэтам для завяршэння рэгістрацыі. Г.зн. тры выклікі ў адным batch-запыце.

JSON-RPC? Вазьміце хітры REST

Разгледзім схему. На ёй прадстаўлена інфраструктура з элементамі высокай даступнасці. Ёсць два незалежныя каналы сувязі з SMS шлюзамі. Але... што мы бачым? Пры адпраўцы SMS узнікае памылка 503 — сэрвіс часова недаступны. Т.к. адпраўка SMS запакаваная ў batch-запыт, то ўвесь запыт павінен адкаціцца. Дзеянні ў СКБД анулююцца. Кліент атрымлівае памылку.

Наступная спроба - латарэя. Або запыт ізноў патрапіць на тую ж ноду і ізноў верне памылку, або павязе, і ён выканаецца. Але галоўнае, што як мінімум адзін раз наша інфраструктура ўжо папрацавала дарма. Нагрузка была, а профіту няма.

Добра, давайце ўявім, што мы напружыліся (!) і прадумалі варыянт, калі запыт можа паспяхова выканацца часткова. А рэшту, мы зноў паспрабуем выканаць праз нейкі інтэрвал часу (Які? Вырашае фронт?). Але латарэя так і засталася. Запыт на адпраўку SMS з верагоднасцю 50/50 ізноў праваліцца.

Пагодзіцеся, са боку кліента, сэрвіс не здаецца такім надзейным як жадалася бы… а што REST?

JSON-RPC? Вазьміце хітры REST

REST зноў выкарыстоўвае "магію" HTTP, але зараз з кодамі адказаў. Пры ўзнікненні памылкі 503 на SMS шлюзе, backend транслюе гэтую памылку балансавальніку. Балансавальнік атрымліваючы гэтую памылку, і не раздзіраючы злучэнне з кліентам накіроўвае запыт на іншую ноду, якая паспяхова адпрацоўвае запыт. Г.зн. кліент атрымлівае чаканы вынік, а інфраструктура пацвярджае сваё высокае званне "восокодоступной". Карыстальнік шчаслівы.

І зноў гэта не ўсё. Балансавальнік не проста атрымаў код адказу 503. Гэты код пры адказе, па стандарце, пажадана забяспечыць загалоўкам “Retry-After”. Загаловак дае зразумець балансавальніку, што не варта турбаваць гэтую ноду па гэтым роўце на працягу зададзенага часу. І наступныя запыты на адпраўку SMS будуць накіроўвацца адразу на ноду, у якой няма праблем са SMS шлюзам.

Як мы бачым, надзейнасць JSON-RPC пераацэнены. Сапраўды, лягчэй арганізаваць кансістэнтнасць у БД. Але ахвярай, у такім разе, стане надзейнасць сістэмы ў цэлым.

Выснова шмат у чым аналагічны папярэдняму. Калі інфраструктура простая, відавочнасць JSON-RPC несумненна яго плюс. Калі праект мяркуе высокую даступнасць з высокай нагружанасцю, REST глядзіцца дакладнейшым, хоць і больш складаным рашэннем.

Парог уваходу ў REST ніжэй

Я думаю, што вышэй праведзены аналіз, развенчвае ўстояныя стэрэатыпы аб RPC наглядна паказаў, што парог уваходу ў REST несумненна вышэй, чым у RPC. Звязана гэта з неабходнасцю глыбокага разумення працы HTTP, а таксама, з неабходнасцю валодаць дастатковымі ведамі аб існуючых інфраструктурных элементах, якія можна і трэба прымяняць у WEB праектах.

Дык чаму многія думаюць, што REST прасцей будзе? Асабіста маё меркаванне заключаецца ў тым, што гэтая ўяўная прастата зыходзіць з саміх маніфестаў REST. Г.зн. REST гэта не пратакол, а канцэпцыя… у REST няма стандарту, ёсць некаторыя рэкамендацыі… REST не складанейшы за HTTP. Уяўная свабода і анархія вабіць "вольных мастакоў".

Несумненна, REST не складанейшы за HTTP. Але сам HTTP гэта добра прадуманы пратакол, які даказаў сваю заможнасць дзесяцігоддзямі. Калі няма глыбокага разумення самога HTTP, то і аб REST судзіць нельга.

А вось аб RPC можна. Досыць узяць яго спецыфікацыю. Дык ці патрэбен вам тупы JSON-RPC? Ці ўсё ж хітры REST? Вырашаць вам.

Шчыра спадзяюся, што я не патраціў ваш час дарма.

Крыніца: habr.com

Дадаць каментар