
Сигурен съм, че заглавието е предизвикало здравословна реакция - "сега пак започна..." Но позволявайте ми да завладая вниманието ви за 5-10 минути и ще се опитам да не разочаровам очакванията.
Структурата на статията ще бъде следната: взема се стереотипно твърдение и се разкрива "природата" на възникването на този стереотип. Надявам се това да позволи нов поглед върху избора на парадигмата за обмен на данни във вашите проекти.
За да има ясност относно това какво е RPC, предлагам да разгледаме стандарта . С REST няма яснота. И не трябва да бъде. Всичко, което трябва да знаете за REST, е, че той не се различава от .
RPC заявките са по-бързи и ефективни, защото позволяват изпълнение на пакетни заявки.
Става въпрос за това, че в RPC можете с една заявка да извикате няколко процедури наведнъж. Например, да създадете потребител, да добавите аватар и в същата заявка да го абонирате за някои теми. Само една заявка, а колко полза!
Наистина, ако имате само една нода на backend, това може да изглежда по-бързо при пакетна заявка. Защото три REST заявки изискват три пъти повече ресурси от една нода за установяване на връзки.

Обърнете внимание, че първата заявка при REST трябва да върне идентификатора на потребителя, за да се извършат последващите заявки. Това също така негативно влияе на общия резултат.
Но такива инфраструктури можете да срещнете единствено в ин-хаус решения и в Enterprise. Най-много, в малки WEB проекти. Но пълноценни WEB решения, наричани HighLoad, не трябва да се изграждат по този начин. Инфраструктурата им трябва да отговаря на критериите за висока достъпност и натовареност. И картината се променя.

Зелените са обозначени каналите на активност на инфраструктурата при същия сценарий. Обърнете внимание как се държи RPC сега. Заявката използва инфраструктурата само по едно рамо от балансировщика до backend. Докато REST все още губи при първата заявка, но наваксва губеното, използвайки цялата инфраструктура.
Достатъчно е в сценариите да вкарате не две заявки за обогатяване, а примерно пет или десет... и отговорът на въпроса "кой печели сега?" става неясен.
Предлагам да погледнем по-широко на проблема. На схемата се вижда как се използват каналите на инфраструктурата, но инфраструктурата не се ограничава само до каналите. Важна част от високо натоварената инфраструктура са кешовете. Нека сега да получим някакъв артефакт от потребителя. Няколко пъти. Да предположим 32 пъти.

Вижте как забележимо се е "поправила" инфраструктурата на RPC, за да отговори на изискванията на високо натоварване. Целият въпрос е, че REST използва цялата мощ на HTTP протокола в отличие от RPC. На приведената схема тази мощност се реализира чрез метода на заявката — GET.
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 атаки. Получаваме:

Тук за RPC всичко става наистина тъпо. RPC просто не е в състояние да делегира работата с натоварването на CDN. Остава само да се надяваме на системи за противодействие на атаки.
Може ли това да приключи тук? И отново, не. HTTP методите, както вече бе споменато, имат своята "магия". И не е случайно, че методът GET е най-широко използваният в Интернет. Обърнете внимание, че този метод може да се свързва с част от съдържанието, може да поставя условия, които инфраструктурните елементи могат да интерпретират преди да предадат управлението на вашия код и т.н. Всичко това позволява създаването на гъвкави, управлявани инфраструктури, способни да обработват наистина големи потоци заявки. А в RPC този метод... се игнорира.
Но защо митът, че batch заявките (RPC) са по-бързи, е толкова устойчив? Лично на мен ми се струва, че повечето проекти просто не достигат такова ниво на развитие, когато REST може да покаже своята сила. Освен това, в малки проекти, той охотно показва своята слабост.
Изборът между REST и RPC не е волевият избор на отделен човек в проекта. Този избор трябва да отговаря на изискванията на проекта. Ако проектът може да извлече всичко, което REST наистина предлага, и това действително е необходимо, то REST ще бъде отличен избор.
Но ако, за да получите всички предимства на REST, ще трябва да наемете девопс специалисти за бързо мащабиране на инфраструктурата, администратори за управление на инфраструктурата, архитект за проектиране на всички слоеве на WEB услугата... а проектът в същото време продава три опаковки маргарин на ден... бих се спрял на RPC, тъй като този протокол е по-утилитарен. Той няма да изисква дълбоки познания за работата на кешовете и инфраструктурата и ще насочи разработчика към простите и разбираеми извиквания на необходимите функции. Бизнесът ще бъде доволен.
RPC заявките са надеждни, тъй като могат да изпълняват batch заявки в рамките на една транзакция.
Тази характеристика на RPC е несъмнен плюс, тъй като е лесно да се поддържа базата данни в консистентно състояние. А с REST нещата стават по-сложни. Заявките могат да идват несъ последователно на различни нодове на бекенда.
Този "недостатък" на REST е обратната страна на неговото предимство, описано по-горе — способността ефективно да използва всички ресурси на инфраструктурата. Ако инфраструктурата е проектирана лошо, а още повече, ако архитектурата на проекта и базата данни, в частност, са проектирани лошо, то това наистина е голяма болка.
Но дали batch-заявките са толкова надеждни, колкото изглеждат? Нека разгледаме случая: създаваме потребител, обогатяваме профила му с описание и му изпращаме SMS с код за завършване на регистрацията. Тоест три извиквания в една batch-заявка.

Нека разгледаме схемата. На нея е представена инфраструктура с елементи на висока наличност. Има два независими канала за връзка със SMS шлюзовете. Но… какво виждаме? При изпращане на SMS възниква грешка 503 — услугата е временно недостъпна. Тъй като изпращането на SMS е опаковано в batch-заявка, цялата заявка трябва да бъде отменена. Действията в СУБД се анулират. Клиентът получава грешка.
Следващият опит е лотария. Или заявката отново попада на същия възел и отново връща грешка, или, със късмет, ще се изпълни. Но основното е, че поне веднъж нашата инфраструктура вече е работила напразно. Имаше натоварване, но няма печалба.
Добре, нека си представим, че се постарахме (!) и обмислихме вариант, при който заявката може успешно да бъде изпълнена частично. А остатъкът, ще опитаме да изпълним отново след известно време (Какво? Определя фронтът?). Но лотарията остана същата. Заявката за изпращане на SMS с вероятност 50/50 отново ще се провали.
Съгласете се, от гледна точка на клиента, услугата не изглежда толкова надеждна, колкото би желал… а какво ще кажете за REST?

REST отново използва “магията” на HTTP, но сега с кодове за отговор. При появата на грешка 503 на SMS шлюза, бекендът предава тази грешка на балансировчика. Балансировчикът, получавайки тази грешка, и без да прекъсва връзката с клиента, насочва заявката към друг възел, който успешно изпълнява заявката. Тоест, клиентът получава очаквания резултат, а инфраструктурата потвърджава високото си звание на “високо налична”. Потребителят е щастлив.
И отново, това не е всичко. Балансировчикът не просто получи код за отговор 503. Този код при отговора, по стандарт, е желателно да бъде придружен с заглавие “Retry-After”. Заглавието дава да се разбере на балансировчика, че не трябва да притеснява този възел по този маршрут за определено време. Следващите заявки за изпращане на SMS ще бъдат насочвани веднага към възел, който няма проблеми с SMS шлюза.
Както виждаме, надеждността на JSON-RPC е надценена. Наистина, по-лесно е да се организира консистентност в БД. Но жертвата в такъв случай ще бъде надеждността на системата като цяло.
Изводът е много подобен на предишния. Когато инфраструктурата е проста, явността на JSON-RPC несъмнено е нейно предимство. Ако проектът изисква висока наличност с висока натовареност, REST изглежда по-подходящо решение, макар и по-сложно.
Прагът за навлизане в REST е по-нисък.
Смятам, че по-горе представеният анализ, който развенчава установените стереотипи за RPC, ясно показа, че прагът за навлизане в REST несъмнено е по-висок в сравнение с RPC. Това е свързано с необходимостта от дълбоко разбиране на работата на HTTP, както и с необходимостта от достатъчни познания относно съществуващите инфраструктурни елементи, които могат и трябва да се приложат в уеб проекти.
Така че защо много хора смятат, че REST е по-просто? Личното ми мнение е, че тази привидна простота идва от самите манифести на REST. Тоест, REST не е протокол, а концепция… REST няма стандарт, а има препоръки… REST не е по-сложен от HTTP. Привидната свобода и анархия привличат "свободни художници".
Несъмнено, REST не е по-сложен от HTTP. Но самият HTTP е добре обмислен протокол, който е доказал своята стойност през десетилетия. Ако няма дълбоко разбиране за самия HTTP, то не може да се съди и за REST.
А за RPC – може. Достатъчно е да вземете неговата спецификация. Необходимо ли е да имате ? Или все же хитрый REST? Решать вам.
Искрено се надявам, че не съм загубил времето ви напразно.
Източник: habr.com
