Integra un ambiente di riposo esterno con la mia applicazione web

1

Ho un servizio in esecuzione su AWS esposto tramite un'API di riposo. Il servizio elabora i file.

I client del servizio inviano un file all'api e viene restituito un ID lavoro.

I client possono quindi richiedere lo stato del lavoro, se è completo il risultato del lavoro viene restituito come JSON.

L'API consiste essenzialmente in un semplice servizio gateway che accetta le richieste di lavoro e le inserisce in una coda SQS. Poi ci sono un pool di dipendenti di ec2 che elaborano i lavori e aggiornano un database in RDS con i loro risultati.

Il tempo necessario per elaborare un file può essere compreso tra 20 secondi e 2 minuti a seconda delle dimensioni del file, tuttavia, a seconda della dimensione della coda e della dimensione del mio gruppo di ridimensionamento, possono essere necessari diversi minuti da quando un client invia un lavoro e quando è completo.

Ora sto creando un'applicazione Web separata che consente agli utenti di inviare lavori a questo servizio. L'utente caricherà un file nell'applicazione Web e vedrà quindi una sorta di schermata 'Elaborazione ...' e quindi quando il lavoro sarà completato vedrà i risultati.

Non sono sicuro del modo migliore per gestire il modo in cui l'applicazione Web sa quando un lavoro è completato.

Al momento questo è il mio approccio:

1) Quando un utente invia un file, la mia applicazione Web invia il file al servizio di elaborazione e viene restituito un ID lavoro. Quel Id del lavoro è memorizzato nel mio DB locale con uno stato di 'elaborazione'. Tale ID lavoro viene aggiunto a una coda "Lavori in corso" locale nella mia applicazione web

2) L'applicazione Web restituisce l'ID del lavoro al browser e i sondaggi del browser  l'applicazione web che controlla lo stato dell'ID lavoro nel database

3) Un thread separato estrae gli elementi dalla coda locale "Lavori in corso" e per ognuno esegue il polling del servizio API verificando se il lavoro è completo. Questo thread tira dire 50 elementi dalla coda e un tempo, e controlla lo stato di ogni lavoro contro l'API ogni 10 secondi. Se il lavoro è completo, il suo stato viene aggiornato nel database locale insieme ai risultati del lavoro.

So che funzionerà, ma sembra complicato e mi chiedo come verrà scalato, e se lo sto distribuendo in un ambiente con bilanciamento del carico (ad esempio su AWS), come farò fronte al potenziale fallimento di uno dei miei nodi di app Web.

Mi sembra anche che si tratti di un caso di uso comune, e forse ci sono alcuni schemi migliori.

L'applicazione web viene creata usando Spring.

    
posta user933709 22.03.2017 - 11:33
fonte

1 risposta

1

Dovresti prendere in considerazione l'utilizzo di eventi inviati dal server . Ecco alcuni posti per saperne di più:

Gli eventi inviati dal server sono supportati nativamente in Chrome, Opera, Firefox e Safari e ci sono polifili che puoi utilizzare per far funzionare gli eventi inviati dal server in Edge / IE e anche a plug-in jQuery .

Ecco un esempio molto semplice di un codice lato client:

var source = new EventSource("/server-side-app-that-gives-progress-updates")
source.onmessage = function(e) {
  console.log(e.data);
}

Sul lato server, la tua app /server-side-app-that-gives-progress-updates ti restituisce solo i dati in testo semplice formattati in questo modo:

data: some data\n
data: more data\n\n

Inizia lo streaming inviando una risposta con un'intestazione Content-Type: text/event-stream . Il codice cliente sopra lo vedrà come un singolo messaggio e.data con " some data\more data ".

Quando l'app del server ha un aggiornamento, scrive semplicemente un altro messaggio di quel modulo nella risposta.

Se si desidera inviare gli aggiornamenti come una serie di messaggi JSON, l'app del server scrive:

data: {"foo": "bar", "hoge": "moge"}\n\n

E quindi il tuo codice cliente può fare questo:

source.onmessage = function(e) {
  var jsonObject = JSON.parse(e.data);
  console.log(jsonObject.foo);
}

Naturalmente c'è dell'altro che puoi imparare nei luoghi sopra citati. Ma questo è tutto sommato.

L'uso di eventi inviati dal server eliminerebbe la necessità per il tuo codice client di eseguire qualsiasi polling. Il caso d'uso principale è la comunicazione unidirezionale degli aggiornamenti dal server al client (in contrasto con i socket Web, che sarebbe la cosa da usare se fosse necessario anche fare un sacco di aggiornamenti in tempo reale nell'altra direzione , dal client al server).

    
risposta data 22.03.2017 - 11:49
fonte

Leggi altre domande sui tag