Come dovremmo avvicinarci a architetture a strati che necessitano di grandi quantità di comunicazione continua, in tempo reale?

1

Sfondo

In gran parte della letteratura che ho letto online per quanto riguarda le architetture multi-livello, molte persone descrivono come creare la semplice applicazione dove:

  • L'interfaccia utente presenta oggetti modello statici sullo schermo.
  • Gli utenti possono effettuare richieste una tantum (ad esempio, inviare e-mail, effettuare il pagamento)
  • Viene in genere eseguita una transazione di database per restituire nuove informazioni da mostrare sullo schermo.

Spesso, gli articoli descrivono questi concetti aderendo al Design basato sul dominio

Problema

Nonostante le buone risorse online, non ci sono molte indicazioni su come organizzare le responsabilità del software per le applicazioni che devono essere in comunicazione continua con dispositivi esterni . Considera quanto segue:

  • Un client di posta elettronica dovrebbe continuamente interrogare un server POP per sapere quando è arrivata una nuova e-mail.
  • Un monitor dispositivo dovrebbe interrogare continuamente le variabili di stato del dispositivo per visualizzare sempre i valori live (ad esempio, l'HMI di un aeromobile può dipendere dalla visibilità di centinaia di variabili in ogni momento).

In entrambi i casi, l'interfaccia utente deve essere aggiornata in tempo reale mentre i cambiamenti avvengono nel mondo esterno. La mia domanda riguarda chi dovrebbe essere responsabile dell'avvio delle richieste. Ho individuato due potenziali soluzioni, la prima che implica una richiesta diretta dall'interfaccia utente e la seconda che utilizza l'inversione di controllo in modo che l'interfaccia utente possa essere notificata:

  1. Il livello dell'interfaccia utente può utilizzare i thread in background (ad esempio .NET BackgroundWorker ) per effettuare continue interrogazioni dirette ai servizi applicativi che restituiscono SOLO i dati richiesti dalla vista in questione.
  2. Un thread in background in un servizio di infrastruttura può interrogare continuamente TUTTE le informazioni rilevanti da un dispositivo esterno (magari facendo affidamento su qualche configurazione) e inviare eventi / notifiche (o richiamare un callback) ad altri livelli in modo che l'IU possa reagire. Pur non essendo personalmente un fan, un aggregatore di eventi può essere utile a tal fine.

Pensochelasoluzionen.1siameglioallineatacongliesempichehotrovato,malamiapreoccupazioneèchequestaNONsiaunasoluzionescalabile.Conl'aumentodellaquantitàdiI/Ocontinui,larotazionedimoltithreadinbackground(perciascunavista)nonsolocicausadiviolare DRY , ma peggiora le prestazioni a causa di molte, piccole richieste di I / O invece di poche, grandi richieste di I / O.

Come dovremmo affrontare architetture a più livelli che richiedono grandi quantità di comunicazione continua, in tempo reale?

L'interfaccia utente dovrebbe eseguire query dirette sui propri thread in background, oppure utilizzare un singolo thread in background e l'inversione di controllo?

    
posta Nick Miller 14.09.2018 - 17:16
fonte

1 risposta

1

L'opzione 1 utilizza il BackgroundWorker e mantiene il ViewModel reattivo. Ciò funziona in generale, ma può causare problemi nel caso in cui il lavoratore soffra di un elevato consumo di CPU in condizioni di stress . Inoltre, interrogare ripetutamente il servizio dell'infrastruttura non sembra uno scenario scalabile ed efficiente sotto il profilo delle risorse.

L'opzione 2 d'altra parte utilizza un'architettura molto comune. L'uso dei thread per l'ascolto di un socket / dispositivo sfrutta il tempo di attesa che l'I / O implica in genere senza utilizzare realmente la CPU. Il callback dell'osservatore garantisce che l'applicazione utilizzi la CPU solo quando necessario. Quindi dal punto di vista del consumo della CPU, questa architettura dovrebbe portare a risultati migliori.

Inoltre con l'opzione 2, è possibile gestire i problemi di scalabilità nei livelli inferiori. Se ci sono troppi dispositivi o un traffico troppo alto, è possibile introdurre alcuni streaming di eventi intermedi (kafka, pubub o altro) su altri nodi di elaborazione che potrebbero eventualmente filtrare solo i messaggi pertinenti. Distribuire l'elaborazione in questo modo mette una barra molto alta per la scalabilità. Il servizio infrastruttura quindi ascolterà lo streaming anziché ascoltare direttamente i dispositivi. Il limite successivo è quindi solo il numero di messaggi in arrivo rilevanti che il livello dell'app potrebbe elaborare.

    
risposta data 14.09.2018 - 22:17
fonte

Leggi altre domande sui tag