JSON-RPC? Prendi l'astuto REST

JSON-RPC? Prendi l'astuto REST

Sicuro che il titolo abbia suscitato una reazione sana: "eccoci di nuovo..." Ma permettetemi di attirare la vostra attenzione per 5-10 minuti e cercherò di non deludere le aspettative.

La struttura dell'articolo sarà la seguente: viene presa un'affermazione stereotipata e si rivela la "natura" dell'emergere di questo stereotipo. Spero che questo permetta di vedere la scelta della paradigma di scambio dati nei vostri progetti sotto una nuova luce.

Per chiarire ciò che è RPC, propongo di considerare lo standard JSON-RPC 2.0. Con REST non c'è chiarezza. E non dovrebbe esserci. Tutto ciò che bisogna sapere su REST è che è indistinguibile da HTTP.

Le richieste RPC sono più veloci ed efficienti perché permettono di effettuare richieste batch.

Si tratta del fatto che in RPC è possibile eseguire in una sola richiesta la chiamata di più procedure. Ad esempio, creare un utente, aggiungere un avatar e nella stessa richiesta iscriverlo a determinati argomenti. Solo una richiesta, ma quanta utilità!

Infatti, se avete solo un nodo backend, questo sembrerà più veloce durante una richiesta batch. Perché tre richieste REST richiederanno tre volte più risorse da un nodo per stabilire connessioni.

JSON-RPC? Prendi l'astuto REST

Notate che la prima richiesta nel caso di REST deve restituire l'identificatore dell'utente, per eseguire le richieste successive. Questo influisce negativamente sul risultato complessivo.

Ma infrastrutture del genere si possono incontrare, semmai, in soluzioni in-house e Enterprise. Al massimo, in piccoli progetti WEB. Ma non si dovrebbe costruire così soluzioni WEB complete, chiamate anche HighLoad. La loro infrastruttura deve soddisfare criteri di alta disponibilità e carico. E la situazione cambia.

JSON-RPC? Prendi l'astuto REST

I canali di attività dell'infrastruttura nello stesso scenario sono evidenziati in verde. Notate come si comporta ora RPC. La richiesta utilizza l'infrastruttura solo su un lato dal bilanciatore di carico al backend. Mentre REST perde ancora nel primo richiesta, ma recupera il tempo perso utilizzando tutta l'infrastruttura.

Basta introdurre nello scenario non due richieste di arricchimento, ma, diciamo, cinque o dieci… e la risposta alla domanda "chi vince ora?" diventa poco chiara.

Propongo di esaminare la problematica da una prospettiva più ampia. Nello schema si può vedere come vengono utilizzati i canali di infrastruttura, ma l'infrastruttura non si limita ai canali. Una componente importante dell'infrastruttura ad alta capacità di carico sono le cache. Ora otteniamo un artefatto utente. Più volte. Diciamo 32 volte.

JSON-RPC? Prendi l'astuto REST

Osservate come l'infrastruttura per RPC sia notevolmente 'migliorata' per soddisfare i requisiti di alta carico. La questione è che REST utilizza tutta la potenza del protocollo HTTP, a differenza di RPC. Nello schema fornito, questa potenza si realizza attraverso il metodo di richiesta — GET.

I metodi HTTP, oltre a tutto, hanno strategie di caching. È possibile conoscerle nella documentazione su HTTP. Per RPC vengono utilizzate richieste POST, che non sono considerate idempotenti, cioè la ripetizione multipla delle stesse richieste POST può restituire risultati diversi (ad esempio, dopo ogni invio di un commento, apparirà una copia ulteriore di quel commento) (fonte).

Di conseguenza, RPC non è in grado di utilizzare in modo efficace le cache infrastrutturali. Questo porta a dover 'importare' cache software. Nello schema, Redis è presentato in questo ruolo. La cache software richiede, a sua volta, uno strato di codice aggiuntivo da parte dello sviluppatore e notevoli modifiche all'architettura.

Ora calcoliamo quanti richieste ha 'generato' REST e RPC nell'infrastruttura considerata?

Richieste
In arrivo
al backend
al DBMS
alla cache software (Redis)
TOTALE

REST
1/32*
1
1
0
3 / 35

RPC
32
32
1
31
96

[*] nel miglior caso (se la cache locale è utilizzata) 1 richiesta (una!), nel peggior caso 32 richieste in entrata.

Rispetto alla prima schema, la differenza è notevole. Ora diventa ovvio il vantaggio di REST. Ma propongo di non fermarci qui. Un'infrastruttura avanzata include un CDN. Spesso questo risolve anche il problema della controreazione agli attacchi DDoS e DoS. Otteniamo:

JSON-RPC? Prendi l'astuto REST

Qui per RPC la situazione diventa davvero triste. RPC non è in grado di delegare il lavoro con il carico del CDN. Rimane solo la speranza nei sistemi di difesa contro gli attacchi.

Possiamo fermarci qui? E di nuovo, no. I metodi HTTP, come già accennato, hanno la loro "magia". Non è un caso che il metodo GET sia ampiamente utilizzato su Internet. Va notato che questo metodo è in grado di accedere a parti del contenuto, è in grado di applicare condizioni che possono essere interpretate dagli elementi infrastrutturali ancor prima che il controllo venga passato al tuo codice, e così via. Tutto ciò consente di creare infrastrutture flessibili e gestibili, in grado di gestire flussi di richieste davvero elevati. E in RPC questo metodo... viene ignorato.

Ma perché il mito secondo cui le richieste batch (RPC) siano più veloci persiste? Personalmente credo che la maggior parte dei progetti non raggiunga mai un livello di sviluppo in cui REST possa dimostrare la sua forza. Inoltre, nei piccoli progetti, tende a mostrare più facilmente le sue debolezze.

La scelta tra REST e RPC non è una decisione arbitraria di una singola persona nel progetto. Questa scelta deve rispondere ai requisiti del progetto. Se il progetto può trarre vantaggio da REST in tutto ciò che può realmente offrire, e questo è davvero necessario, allora REST sarà un'ottima scelta.

Ma se per ottenere tutti i benefici di REST è necessario assumere devops per la scalabilità operativa dell'infrastruttura, amministratori per la gestione dell'infrastruttura, un architetto per progettare tutti i layer del servizio WEB... e il progetto, nel contempo, vende tre pacchi di margarina al giorno... io mi fermerei su RPC, dato che questo protocollo è più utilitaristico. Non richiederà conoscenze approfondite sul funzionamento della cache e dell'infrastruttura, e concentrerà lo sviluppatore su chiamate semplici e chiare delle procedure necessarie. Gli affari saranno soddisfatti.

Le richieste RPC sono più affidabili, poiché possono eseguire richieste batch all'interno di una sola transazione.

Questa caratteristica di RPC è un indiscutibile vantaggio, poiché consente di mantenere il database in uno stato consistente. Con REST, invece, le cose diventano più complicate. Le richieste possono arrivare in modo non sequenziale a diversi nodi del backend.

Questo "difetto" di REST è il rovescio della medaglia del suo vantaggio descritto sopra: la capacità di utilizzare efficacemente tutte le risorse dell'infrastruttura. Se l'infrastruttura è progettata male, e ancor di più se l'architettura del progetto e il database in particolare sono mal progettati, allora questo rappresenta davvero un grande problema.

Ma sono così affidabili i batch request come sembrano? Consideriamo un caso: creiamo un utente, arricchiamo il suo profilo con una descrizione e gli inviamo un SMS con un segreto per completare la registrazione. Cioè, tre chiamate in un unico batch request.

JSON-RPC? Prendi l'astuto REST

Esaminiamo lo schema. Su di esso è rappresentata un'infrastruttura con elementi di alta disponibilità. Ci sono due canali di comunicazione indipendenti con i gateway SMS. Ma… cosa vediamo? Durante l'invio dell'SMS si verifica un errore 503 — il servizio è temporaneamente non disponibile. Poiché l'invio di SMS è racchiuso in un batch request, l'intero request deve essere annullato. Le azioni nel DB vengono annullate. Il cliente riceve un errore.

Il tentativo successivo è una lotteria. O il request andrà di nuovo sulla stessa nod e restituirà nuovamente un errore, oppure avrà fortuna e verrà eseguito. Ma la cosa principale è che almeno una volta la nostra infrastruttura ha già lavorato invano. C'era carico, ma nessun profitto.

Bene, immaginiamo che ci siamo impegnati (!) e abbiamo pensato a un'opzione in cui il request può essere eseguito con successo parzialmente. E il resto, tenteremo di eseguirlo nuovamente dopo un certo intervallo di tempo (Quale? Decide il front-end?). Ma la lotteria è rimasta. Il request per l'invio dell'SMS ha il 50/50 di probabilità di fallire di nuovo.

Ammetti che dal punto di vista del cliente, il servizio non sembra così affidabile come vorremmo… e per quanto riguarda il REST?

JSON-RPC? Prendi l'astuto REST

Il REST utilizza nuovamente la “magia” dell'HTTP, ma ora con i codici di risposta. Quando si verifica un errore 503 sul gateway SMS, il backend trasmette questo errore al bilanciatore di carico. Il bilanciatore, ricevendo questo errore e senza interrompere la connessione con il cliente, invia il request a un'altra nod che elabora con successo la richiesta. Cioè, il cliente riceve il risultato atteso e l'infrastruttura conferma la sua alta reputazione di “alta disponibilità”. L'utente è felice.

E ancora non è tutto. Il bilanciatore non ha semplicemente ricevuto il codice di risposta 503. Questo codice, nella risposta, secondo standard, è preferibile fornire con l'intestazione “Retry-After”. L'intestazione fa capire al bilanciatore che non dovrebbe disturbare questa nod su questo percorso per un certo tempo. E le successive richieste per l'invio di SMS saranno indirizzate immediatamente a quella nod che non ha problemi con il gateway SMS.

Come vediamo, l'affidabilità del JSON-RPC è sovrastimata. Davvero, è più facile organizzare la coerenza nel DB. Ma la vittima, in questo caso, sarà l'affidabilità del sistema nel suo complesso.

L'output è in gran parte simile al precedente. Quando l'infrastruttura è semplice, l'evidenza di JSON-RPC è indubbiamente un suo punto a favore. Se il progetto prevede alta disponibilità con un carico elevato, REST appare una soluzione più appropriata, sebbene più complessa.

La barriera d'ingresso a REST è più bassa

Credo che l'analisi sopra, che sfata gli stereotipi consolidati su RPC, abbia chiaramente dimostrato che la barriera d'ingresso a REST è senza dubbio più alta rispetto a RPC. Questo è dovuto alla necessità di una profonda comprensione del funzionamento di HTTP, oltre alla necessità di avere conoscenze sufficienti sugli elementi infrastrutturali esistenti che si possono e si devono applicare nei progetti WEB.

Quindi perché molti pensano che REST sia più semplice? La mia personale opinione è che questa apparente semplicità derivi dai manifesti stessi di REST. Cioè, REST non è un protocollo, ma un concetto… REST non ha uno standard, ci sono alcune raccomandazioni… REST non è più complesso di HTTP. La apparente libertà e anarchia attirano i "free spirits".

Senza dubbio, REST non è più complesso di HTTP. Ma lo stesso HTTP è un protocollo ben strutturato, che ha dimostrato la sua validità per decenni. Se non si ha una comprensione profonda di HTTP, non si può giudicare su REST.

Ma su RPC — si può. Basta prendere la sua specifica. Quindi vi serve un semplice JSON-RPC? Или все же хитрый REST? Решать вам.

Spero sinceramente di non aver sprecato il vostro tempo.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster