Qual è il modo migliore per scalare orizzontalmente le applicazioni di back-end .Net?

3

Dato un carico di lavoro con molte operazioni intensive CPU / IO di lunga durata (ad es. produzione di file di testo multi-GB da letture di database e regole aziendali), qual è il modo migliore per bilanciare il carico delle applicazioni .net su un gruppo di Windows Server 2012 R2 VM?

Idealmente, l'approccio consentirebbe l'aggiunta / rimozione / patch dei nodi, se necessario. È praticamente un'operazione 24 ore su 24, 7 giorni su 7, con poche opportunità per le finestre di manutenzione.

Sfondo

Siamo in procinto di migrare milioni di righe di codice COBOL da un mainframe IBM a C #. Il carico di lavoro corrente è centrato su lotti e ci sono molti lavori che si attivano a un'ora programmata per eseguire unità di lavoro di varie dimensioni.

Ovunque possibile, cercheremo di rendere i processi convertiti più in tempo reale, guidati dagli eventi, ecc ... Tuttavia, a causa della dipendenza dagli input / output esistenti da / per molti partner upstream e downstream e dal desiderio di passare da una piattaforma all'altra nel minor tempo possibile con interruzioni minime, avremo vincoli che ci impediranno di procedere con un approccio completamente greenfield.

A causa dei grandi volumi di dati in costante cambiamento coinvolti e dell'interconnessione di tali dati con altri sistemi legacy, il passaggio a un'infrastruttura basata su cloud non è probabilmente fattibile.

Approcci che stiamo considerando

Code JMS: disponiamo di un ESB conforme a JMS di classe enterprise e potremmo fare la coda del lavoro, avendo utenti su ogni VM in grado di eseguire il lavoro in base alla disponibilità delle risorse.

Coordinatore delle attività: abbiamo preso in considerazione la creazione di un gestore del carico di lavoro personalizzato in grado di monitorare i server e decidere dove inviare il lavoro. Qualcosa lungo queste linee .

    
posta Paul G 16.10.2015 - 15:34
fonte

1 risposta

1

Ecco un estratto da una domanda correlata , in particolare su scalatura.

Scaling across machines can be done in various ways. Likely what you will want is partitioning. The easiest way is by hashing on some request value to decide which server to send to. For instance, if your customer ID is an integer (or can be consistently reduced to one... e.g. with GetHashCode) and you have 3 machines processing tasks, you can use a simple modulus to decide which customer should go to which machine. machineNumber = customerId % 3. CustomerId 1,4,7, etc will always go to machine 1. However, if Machine 1 goes down, 1/3 of the customer requests will not get processed until it comes back up. Since these are long running imports anyway, that's likely not a big deal. The load will also not be distributed evenly, since there are usually some customers who are heavier users. Again, probably not a huge deal. Measure to make sure.

Another way that is resilient to failure is to use a distributed directory. It keeps track of which node currently owns which customer. Project Orleans uses a mechanism like this. It allows for nodes to fail and customers to be transitioned to another node. Before allocating a new customer on a node, you can also query the node to see which is the least loaded. However, I'm not aware of a pre-built component for this purpose, and building it yourself is perilous to your time.

Poiché hai menzionato le code, potresti visualizzare una funzionalità chiamata Concorrenti consumatori disponibile in vari sistemi di code. In tal caso, si installano più macchine o VM (nodi) per servire la coda. Ogni volta che arriva un nuovo messaggio, il primo nodo da rispondere riceve il messaggio e ci si aspetta che lo elabori.

La sezione Problemi e considerazioni del link dei consumatori in competizione ha alcuni punti eccellenti riguardo a tale sistema di coda / carico di lavoro.

    
risposta data 16.10.2015 - 18:39
fonte

Leggi altre domande sui tag