Architettura delle app mobili per migliorare la velocità e ridurre il trasferimento dei dati

5

Contesto aziendale del problema

La nostra app per iphone consente agli utenti di pagare i commercianti e guadagnare premi.

Gli utenti possono anche fare cose come:

  1. Visualizza cronologia transazioni
  2. Visualizza i loro punti e i premi disponibili o richiedi i premi.
  3. Guadagna denaro facendo riferimento agli amici, visualizza una cronologia dei referral convertiti e non convertiti.
  4. Visualizza le offerte in corso presso alcuni commercianti (offerte speciali per l'happy hour, ecc.)
  5. Visualizza informazioni sui commercianti (posizione, ore, ecc.)

Poiché cose come offerte o premi disponibili, cronologia transazioni e referral possono cambiare in qualsiasi momento, abbiamo un classico problema di invalidazione della cache sul dispositivo dell'utente.

Soluzione corrente, insoddisfacente

La nostra attuale architettura è abbastanza standard e consiste di endpoint API come "/ commercianti", "/ ricompense", "/ transazioni", "/ offerte" e così via.

Al momento risolviamo il problema della cache stantia di:

  1. Polling sul server frequentemente mentre l'app è aperta (spesso ogni minuto per alcune chiamate API), nonché ogni volta che l'app riprende l'attenzione.
  2. Indicazione di dati potenzialmente obsoleti con testo come Ultimo aggiornamento di 3 minuti fa

Usiamo gli etags per evitare di inviare nuovamente i dati invariati intere (ad esempio, l'intero elenco dei commercianti), ma il nostro approccio attuale lascia ancora molta banda sprecata. Ad esempio, se un singolo commerciante cambia, tutti i commercianti vengono reindirizzati. Se viene aggiunta una singola nuova transazione, tutte le transazioni vengono reinviate.

In pratica, dal punto di vista dell'utente, questo di solito non è un grosso problema, visto che stiamo parlando di dimensioni di 1-200K al massimo, e in genere meno. Tuttavia, può essere un problema in aree con scarsa ricezione delle celle, una situazione che emerge abbastanza spesso da sentire lamentele.

E sul lato server, tutto questo polling crea un sacco di carico non necessario, soprattutto perché l'elaborazione e le query del database si verificano anche quando gli etags sono invariati,

Soluzioni migliori?

Stiamo riprogettando l'app e il codice del server e pensando a strategie alternative. Poiché questo è un problema abbastanza comune, mi piacerebbe sapere come gli altri lo risolvono.

Alcune idee che ho finora:

  1. Per ridurre al minimo il trasferimento di dati : tieni traccia, sul server, dei dati che ogni utente ha effettivamente. Invia patch JSON solo ai dati modificati, anziché alle nuove copie di tutti i dati. Le copie dei dati di ciascun utente possono essere memorizzate in redis e scadono dopo alcuni giorni o una settimana. Ciò manterrebbe la "sessione attiva" veloce, mentre l'utente senza una cache del server memorizzata potrebbe semplicemente inviare una nuova copia di tutti i dati al momento del login dopo un periodo di sospensione (come ora). Mentre in teoria questo potrebbe funzionare, mantenendo sincronizzate le copie server e client, applicando entrambe le patch, sembra una ricca fonte di potenziali bug, anche se sto usando librerie di patch JSON controllate.

  2. Per ridurre al minimo il carico del server : Stabilisci connessioni socket web con ciascun client, anziché il polling. Consentire agli eventi che modificano lo stato del cliente (ad esempio, un acquisto, una conversione di referral, un deal deal, ecc.) Spingere verso il basso i messaggi websocket, che a loro volta attivano il refresh del client. Questo potrebbe essere usato insieme all'idea 1 o al metodo attuale di invio di nuove copie di tutti i dati modificati. Anche con il metodo attuale, questo sarebbe comunque un enorme miglioramento, poiché i dati sarebbero richiesti e inviati solo quando necessario.

In questo momento, mi sto appoggiando verso 2 senza 1, poiché 1 sembra troppo potenzialmente irto di problemi. Ho alcune preoccupazioni nel fare affidamento su websocket su dispositivi mobili, ma dopo aver fatto ricerche qui, su SO e in altri luoghi, sembra che questa preoccupazione non sia valida.

Mi piacerebbe sentire altri, forse radicalmente diversi, suggerimenti per risolvere questi problemi.

    
posta Jonah 29.12.2015 - 07:18
fonte

1 risposta

2

Poiché si tratta di un'app nativa, puoi disabilitare interamente HTTP se vuoi.

Potresti usare HTTP / 2.0 che consente i flussi. Gli stream sono una soluzione parziale al blocco della linea di testa (HOL) che consente a più richieste di condividere una singola connessione TCP e di essere consegnati in modo incrementale e simultaneo. Permette anche alcune comunicazioni avviate dal server. È ancora TCP quindi non è una soluzione completa per il blocco HOL.

È possibile utilizzare WebRTC che utilizza DTLS per evitare completamente il blocco HOL e abilita gli eventi server o peer to peer in modo efficiente.

Sono propenso a evitare l'HTTP per questo tipo di caso d'uso perché pone vincoli artificiali e non simpatici sui flussi delle richieste di dati dell'applicazione. È una necessità nel browser, ma non in un'app. HTTP ha il vantaggio di fornire un'unica interfaccia di servizio per tutti i client di app basati su broswer, desktop e mobili, quindi prendi questo con un pizzico di sale.

Potresti usare AMQP su TLS (con qualcosa come RabbitMQ) sulla porta 443 e fare comunicazioni basate su eventi tramite le sue code di messaggi. I servizi di backend spingono gli aggiornamenti nelle code o un servizio di aggiornamento intermedio chiama i servizi REST e li aggiorna. Questo risentirebbe ancora del blocco HOL a livello TCP.

Un'altra opzione è ZeroMQ con CurveZMQ. È anche una soluzione orientata ai messaggi, ma in cui non è necessario un broker centrale separato come AMQP. La tua app potrebbe comunicare direttamente al tuo server tramite messaggistica. Il tuo server potrebbe eseguire il polling e la gestione dello stato di REST e inviare aggiornamenti al client con la frequenza desiderata o non frequente. Ciò consente un degrado aggraziato in situazioni di errore. Questa è l'opzione più flessibile e discutibilmente più snella, ma è anche su TCP, quindi non evita completamente il blocco HOL.

Per quello che vale il blocco HOL è improbabile in qualsiasi punto del tuo problema immediato e risolverlo richiede compromessi significativi.

    
risposta data 30.12.2015 - 21:58
fonte

Leggi altre domande sui tag