Architettura del backend mobile

1

Vorrei qualche input su alcuni refactoring che devo fare su un back-end mobile (API).

Mi è stata lanciata un'API mobile che ho bisogno di rifattorizzare e migliorare, specialmente nell'area delle prestazioni.

Uno (dei molti) posto in cui posso migliorare le prestazioni e migliorare l'architettura è il modo in cui il back-end si occupa attualmente delle notifiche push.

Lasciatemi descrivere brevemente come funziona attualmente, e quindi come intendo ristrutturarlo.

Ecco come funziona ora. L'esempio riguarda l'utente che invia un commento a un post del feed:

  1. L'utente fa clic su Invia nell'app mobile. L'app mostra uno spinner e nel frattempo invia una richiesta al back-end.
  2. Il backend riceve la richiesta e inizia a gestirla. Inserisce una riga nella tabella dei commenti, esegue altre operazioni di contabilità e, per i dispositivi mobili interessati, invia una richiesta al server Apple Push Notification o Google Firebase Service (o entrambi se il ricevitore ha sia un Android che un iPhone).
  3. In caso di successo il backend restituisce un 200 all'app mobile.
  4. Dopo aver ricevuto il codice di stato 200 dal back-end, l'app mobile rimuove lo spinner e aggiorna l'interfaccia utente con il commento inviato.

È semplice ma il problema con quanto sopra è che lo vedo

a) Attualmente questo endpoint campione ha troppe responsabilità. Si occupa del salvataggio di un commento e anche dell'invio di notifiche push ai dispositivi. b) Le prestazioni non sono le migliori poiché l'app mobile attende il back-end per salvare un commento (che è piuttosto veloce) e inviare una notifica che richiede una richiesta HTTP (che può essere qualsiasi cosa, da rapida a lenta).

Quindi la mia idea è di rimuovere tutto ciò che riguarda le notifiche dal back-end e di ospitarlo in un'app di back-end separata (potresti chiamarlo microservizio).

Quindi quello che sto pensando è farlo in questo modo:

  1. L'utente fa clic su "Invia" nell'app mobile. L'app mostra uno spinner e nel frattempo invia una richiesta al backend API principale.
  2. L'app mobile invia anche un'altra richiesta HTTP, questa volta a un servizio di notifica separato dal backend API principale. Questa è una specie di incendio e dimentica la richiesta. Quindi l'app non lo aspetta in alcun modo e può essere inviato in background (in iOS utilizzando, ad esempio, GCD).
  3. Il backend principale riceve la richiesta sul commento e inizia a gestirlo. Inserisce una riga nella tabella dei commenti, forse esegue altre operazioni di contabilità e quindi restituisce la risposta all'app mobile.
  4. Il servizio di notifica riceve la richiesta sul commento e inserisce una riga in una tabella di notifica (questo è per motivi storici, ad esempio per creare una vista Attività o qualcosa del genere), quindi inserisce un messaggio in qualche coda (o su Redis). Un lavoro separato prende ciò che è in coda / Redis e lo gestisce (è qui che inviamo effettivamente una richiesta a Apple Push Notification Server e al servizio di Google Firebase). Non avendo il servizio di notifica HTTP si parla con questi servizi esterni, sarà più semplice scalare le risorse HTTP.
  5. Dopo aver ricevuto il 200 dal back-end principale, l'app mobile rimuove lo spinner e aggiorna l'interfaccia utente con il commento inviato. Ancora una volta notate che l'app mobile non attende la seconda richiesta che invia (non è come se potesse fare qualcosa se fallisce comunque).

Quindi è molto più complesso. Ma il principale backend API ora riguarda solo il salvataggio del commento. L'app mobile deve anche inviare due richieste invece di una sola, ma non è necessario attendere la seconda richiesta. Quindi nel complesso dovrebbe dare prestazioni migliori, penso.

Per quanto riguarda il servizio di notifica, potrebbe essere più semplice non utilizzando una coda / Redis ma semplicemente fare in modo che il servizio di notifica richiami Apple e Google con le notifiche push. Ma sto pensando che separandolo in un semplice servizio HTTP che fa solo alcune cose di base per la contabilità e mettendo roba in coda / Redis può essere veloce e semplice, e il lavoro separato farebbe quindi il lavoro effettivo di chiamare Apple e Google.

Ha senso? O ho cose troppo complicate? Tutti i commenti sono apprezzati.

    
posta Jacob Rohde 07.07.2017 - 21:56
fonte

2 risposte

3

Un'API è abbastanza avanzata da aspettarsi che faccia più cose con una singola azione. Se ho un endpoint che fa un "Acquista prodotto", mi aspetto che gestisca tutte le operazioni di gestione, registrazione e aggiornamento dei saldi anziché suddividerli in servizi che il cliente deve contattare individualmente.

Hai l'idea giusta di far esplodere la notifica push e dimenticare l'operazione, ma può essere eseguita con un singolo endpoint sulla tua API. Se si utilizza una coda di lavoro, è sufficiente creare due processi separati ed eseguire entrambi: attendere uno e dimenticare l'altro.

    
risposta data 07.07.2017 - 22:12
fonte
1

Ci sono diverse cose che potrebbero andare storte e confondere le richieste.

Ad esempio problemi di rete, sovraccarico della CPU, esaurimento della memoria, traffico Internet, server db esaurito, istruzioni SQL inefficienti, mappature inefficienti del db, tabelle dei dati troppo grandi e scarsamente indicizzate, colli di bottiglia da qualche parte, esaurimento dei lavoratori, ecc ...

Sviluppa prima un piano. Devi identificare la fonte e agire di conseguenza con il problema.

BACIO !!! Inizia con la soluzione e il test più semplici. Esegui i test di carico per una misura rappresentativa della prestazione. Ottieni metriche. Successivamente, questi test misureranno anche la qualità della soluzione.

Per quanto riguarda la soluzione che suggerisci. Diavolo, no! Perché non provi prima con le esecuzioni parallele? Esegui le notifiche su un altro thread. Non aspettare che sia finito. Come dici tu, spara e dimentica.

Tuttavia, avrai bisogno di un modo per dimostrare che la soluzione ha risolto il problema e il suo ordine di grandezza.

    
risposta data 07.07.2017 - 22:43
fonte

Leggi altre domande sui tag