Elaboriamo i messaggi attraverso una varietà di servizi (un messaggio toccherà probabilmente 9 servizi prima che sia fatto, ognuno facendo una specifica funzione relativa all'IO). Al momento abbiamo una combinazione del caso peggiore (serializzazione del contratto dati XML) e del caso migliore (MSMQ in memoria) per le prestazioni.
La natura del messaggio indica che i nostri dati serializzati terminano a circa 12-15 kilobyte e elaboriamo circa 4 milioni di messaggi a settimana. I messaggi persistenti in MSMQ erano troppo lenti per noi e, man mano che i dati crescono, sentiamo la pressione dei file mappati in memoria di MSMQ. Il server ha un consumo di memoria di 16 GB ed è in crescita, solo per l'accodamento. Anche le prestazioni si verificano quando l'utilizzo della memoria è elevato, poiché la macchina inizia lo scambio. Stiamo già eseguendo il comportamento di auto-pulizia di MSMQ.
Mi sento come se ci fosse una parte che stiamo sbagliando qui. Ho provato a utilizzare RavenDB per mantenere i messaggi e ad accodare un identificatore, ma le prestazioni erano molto lente (1000 messaggi al minuto, nel migliore dei casi). Non sono sicuro che sia il risultato dell'uso della versione di sviluppo o di cosa, ma abbiamo sicuramente bisogno di un throughput più elevato [1]. Il concetto ha funzionato molto bene in teoria, ma le prestazioni non erano all'altezza.
Il modello di utilizzo ha un servizio che funge da router, che viene letto da tutti. Gli altri servizi collegheranno le informazioni in base al loro hook di terze parti e inoltreranno di nuovo al router. La maggior parte degli oggetti viene toccata 9-12 volte, sebbene circa il 10% sia costretto ad aggirarsi in questo sistema per un po 'finché le terze parti non rispondono in modo appropriato. I servizi in questo momento spiegano questo e hanno comportamenti di sonno appropriati, poiché utilizziamo il campo prioritario del messaggio per questo motivo.
Quindi, la mia domanda, è qual è lo stack ideale per il trasferimento di messaggi tra macchine discrete-ma-LAN in un ambiente C # / Windows? Normalmente inizierei con BinaryFormatter invece della serializzazione XML , ma questa è una tana del coniglio se un modo migliore è quello di scaricare la serializzazione in un archivio di documenti. Quindi, la mia domanda.
[1]: La natura della nostra attività significa che prima elaboriamo i messaggi, più soldi guadagniamo. Abbiamo dimostrato empiricamente che elaborare un messaggio più tardi nella settimana significa che siamo meno propensi a fare quei soldi. Mentre le prestazioni di "1000 al minuto" sembrano molto veloci, abbiamo davvero bisogno di un numero che superi i 10.000 / minuto. Solo perché sto dando i numeri nei messaggi a settimana non significa che abbiamo un'intera settimana per elaborare quei messaggi.
=============== modifica:
Informazioni aggiuntive
In base ai commenti, aggiungerò qualche chiarimento:
-
Non sono sicuro che la serializzazione sia il nostro collo di bottiglia. Ho eseguito il benchmark dell'applicazione e mentre la serializzazione si presenta nel grafico del calore, è responsabile solo del 2,5-3% circa dell'utilizzo della CPU del servizio.
-
Sono principalmente preoccupato per la permanenza dei nostri messaggi e il potenziale uso improprio di MSMQ. Utilizziamo messaggi non transazionali e non persistenti, in modo che possiamo mantenere attive le code e mi piacerebbe avere almeno dei messaggi persistenti per sopravvivere al riavvio.
-
L'aggiunta di più RAM è una misura in sospeso. La macchina è già passata da 4 GB - > 16 GB di RAM e diventa sempre più difficile rimuoverlo per continuare ad aggiungerne altri.
-
A causa del pattern di instradamento a stella dell'applicazione, metà del tempo in cui un oggetto viene scoppiato e poi spinto in una coda, non cambia affatto. Questo si presta di nuovo (IMO) per archiviarlo in qualche tipo di archivio di valori-chiave altrove e semplicemente per passare gli identificatori di messaggi.
-
Il pattern di instradamento stellare è parte integrante dell'applicazione e non cambierà. Non possiamo applicarlo come metodo perché ogni pezzo lungo la strada opera in modo asincrono (in modalità sondaggio) e vogliamo centralizzare il comportamento dei tentativi in un unico punto.
-
La logica dell'applicazione è scritta in C #, gli oggetti sono POCO immutabili, l'ambiente di distribuzione di destinazione è Windows Server 2012 e siamo autorizzati a installare macchine aggiuntive se un particolare software è supportato solo in Linux.
-
I miei obiettivi sono il mantenimento del throughput corrente riducendo l'ingombro della memoria e aumentando la tolleranza ai guasti con un esborso minimo di capitale.