2012-03-23 16 views
6

Sono curioso di sapere come risolvere il problema di concorrenza per un'API RESTful. Più in particolare, ho una collezione di oggetti che richiedono l'esame e l'aggiornamento manuale, ad es. un numero di righe che richiedono una colonna aggiornata manualmente; tuttavia, se apro l'API a un certo numero di client, verranno tutti catturati dall'alto verso il basso, quindi molti utenti riempiranno la colonna della stessa riga nello stesso momento. Preferirei non avere collisioni e il modo semplice e statico è di scaricare gli articoli in una coda del servizio e farli scoppiare mentre le persone li richiedono.Le API RESTful devono essere apolidi, ma per quanto riguarda la concorrenza?

Qual è la versione senza stato di questo? Hash per indirizzo IP, o afferrare a caso le righe in base all'ID?

:: :: aggiornamento

"Hrm, quindi deve essere semplicemente senza stato dal punto di vista del cliente?

che rende sicuramente un sacco di senso. Stavo leggendo un articolo (ibm.com/developerworks/webservices/library/ws-restful) su API RESTful, e dopo aver incontrato il bit sul paging, ero preoccupato che la mia coda abbastanza statica fosse simile all'incremento di una pagina, ma in realtà sono abbastanza diversi come la "pagina successiva" è relativa sul lato client, mentre "pop" è sempre stateless per il client: non importa ciò che è stato scoppiato prima.

Grazie per avermi liberato la testa! " -me

+0

Non vedo davvero il problema/domanda qui. Le API RESTful possono essere - e IME sono quasi sempre - supportate da server stateful. Potresti chiarire il problema che stai cercando di risolvere? Gli e-tag –

+0

possono essere utilizzati per fornire la concorrenza –

+0

Hrm, quindi deve essere semplicemente stateless dal punto di vista del client? Questo ha sicuramente molto senso. Stavo solo leggendo un articolo (https://www.ibm.com/developerworks/webservices/library/ws-restful/) sulle API RESTful, e dopo aver incontrato il bit sul paging, ero preoccupato che la mia coda abbastanza statica fosse simile ad aumentare di una pagina, ma in realtà sono abbastanza diversi in quanto la "pagina successiva" è relativa sul lato client, mentre "pop" è sempre stateless per il client. Non importa ciò che è stato scoppiato prima. Grazie per avermi liberato la testa! –

risposta

3

Ci sono due approcci di base si può prendere:

  1. andare completamente senza stato, e adottare una strategia "ultima richiesta vince". Per quanto possa sembrare strano, è probabilmente la soluzione più pulita in termini di prevedibilità, scalabilità, complessità del codice e implementazione su entrambi i lati client e server. C'è anche un sacco di precedenza per questo: guarda come siti come Google impagina attraverso le query usando uno start=10 per pagina 2, per pagina 3, ecc.

    Potresti scoprire che il contenuto cambia all'interno delle pagine mentre navighi avanti e indietro tra di loro, ma allora? Ricevi sempre le informazioni più recenti e Google può gestire le tue richieste su uno dei loro numerosi server senza dover trovare le informazioni sulla sessione per determinare quale fosse il tuo ultimo contesto di query.

    Il più grande vantaggio di questo approccio è la semplicità dell'implementazione del server. Ogni richiesta può passare direttamente al livello dati nel back-end ed è assolutamente matura per il caching sia a livello HTTP (tramite E-Tag o intestazioni Last-Modified) che lato server (usando qualcosa come memcache, per esempio).

  2. Passare allo stato e trovare un modo per fare in modo che i server forniscano una sorta di blocco o token per client per ciascuna "sessione" dell'API. Sarà come cercare di combattere la marea dell'oceano con un bastone, perché finirai per fallire e frustrato.

    Come identificherete i clienti? Chiavi di sessione? Indirizzo IP? Il descrittore di file per il socket su cui sono entrati (buona fortuna se usi un trasporto come HTTP dove la connessione può essere chiusa tra le richieste ...)? I dettagli che scegli per questo dovranno essere persistenti sul lato server, o dovrai usare alcune brutte vecchie funzionalità di sessione appiccicose sul tuo server delle app (e se così fosse, aiutare il tuo client se il server che stanno usando scende metà sessione).

    Come gestirai i client API che scompaiono in modo disgraziato?Avrai il timeout della sessione in modo automatico bloccando il thread di un mietitore e pulendo quelli inattivi? Questo è più codice, più complessità e più posti da nascondere per i bug. Per quanto riguarda i client API che tornano da un lungo periodo di inattività e cercano di riutilizzare un blocco scaduto, come devono essere create le applicazioni client per gestire tale situazione?

Potrei andare avanti, ma spero che tu possa vedere il mio punto. Vai con l'opzione 1 e vai senza stato. Altrimenti finirai per provare a tenere traccia dello stato del client sul lato server. E l'unica cosa che dovrebbe tracciare lo stato di un cliente è il client stesso.

+0

Non credo che accettare le modifiche ai contenuti mentre si sfogliano le pagine dei risultati sia il modo di pensare unico. Potresti visualizzare voci doppie - OK (e il client potrebbe gestirlo comunque), ma potresti anche perdere le voci totalmente a causa di rimozioni nell'ambito di pagine passate/precedenti - non è bello. Per i risultati di ricerca di Google che potrebbero non avere importanza, ma in altri contesti potrebbe. –

+0

In alternativa, è possibile recuperare "tutti gli ID" sul client (OK, per i risultati di ricerca di Google non più fattibili per la maggior parte del tempo) e scorrere questo elenco pagina per pagina, caricando più contenuti quando si raggiunge la pagina del set di risultati con quell'ID sottoinsieme. Le cattive notizie sono che il problema ritorna dietro l'angolo: ci possono essere oggetti nel frattempo cancellati (che non possono essere caricati più - devono essere catturati in qualche modo), e ci possono essere nuovi elementi aggiunti nel frattempo che non si vedono da sfogliando il tuo attuale set di risultati. Quindi la domanda è: cosa è più importante per te? –

+0

Se non ti interessa la mancanza o la duplicazione degli elementi durante la navigazione del set di risultati pagina per pagina avanti e indietro, allora andrà bene inserendo il numero di pagina o l'intervallo di indice nell'URL come parametro - caricando il servizio con il caricamento e buttare via tutti gli oggetti che sarebbero stati collocati su qualsiasi pagina prima. (Come gestisce Google? Chiunque ha provato una query assurda e inizialmente ha specificato un numero di pagina elevato, ad esempio "query = millionaire & page = 59786"?) –

1

È possibile mantenere lo stato della risorsa. Il "divieto apolide" si riferisce solo allo stato della sessione.

Ecco un estratto da Roy Fielding's seminal REST derivation:

Abbiamo poi aggiungere un vincolo per l'interazione client-server: comunicazione deve essere senza stato di natura, come nello stile client-stateless-server (CSS) di Sezione 3.4.3 (Figura 5-3), tale che ogni richiesta dal client al server deve contenere tutte le informazioni necessarie per comprendere la richiesta e non può sfruttare il vantaggio di di qualsiasi contesto memorizzato sul server. Lo stato della sessione è quindi interamente conservato sul client.