Mi piace modificare il codice di SQL Server per migliorare le prestazioni, ma a volte ci sono scenari in cui, anche dopo l'ottimizzazione del codice, l'indicizzazione e la progettazione di un'attività utente dall'applicazione richiedono più tempo per il completamento rispetto all'esperienza dell'utente finale prevista. Quando ciò accade, l'interfaccia utente deve attendere il completamento del processo o dobbiamo trovare un modo alternativo per gestire l'attività. L'elaborazione asincrona fornita da Service Broker si adatta bene a molti di questi scenari e consente l'elaborazione in background dell'attività di lunga durata da eseguire separatamente dall'interfaccia utente, consentendo all'utente di continuare a lavorare immediatamente senza attendere che l'attività venga effettivamente eseguita . Nei miei prossimi articoli, spero di creare una serie su come sfruttare Service Broker con le spiegazioni e gli esempi di codice appropriati lungo il percorso per rendere più semplice sfruttare le capacità di Service Broker senza problemi di implementazione.
Metodi di esecuzione dell'elaborazione asincrona
Esistono diversi modi per affrontare un processo di lunga durata, ma già ottimizzato. Il codice dell'applicazione può anche essere riscritto per usare un BackgroundWorker, il ThreadPool in background o una soluzione basata su Thread scritta manualmente in .NET che esegue l'operazione in modo asincrono. Tuttavia, ciò consente l'invio da parte dell'applicazione di un numero illimitato di questi processi di lunga durata, a meno che non venga eseguito un ulteriore lavoro di codifica per tenere traccia e limitare il numero di processi attivi. Ciò significa che l'applicazione avrà un potenziale impatto sulle prestazioni, o sotto carico raggiungerà un limite e tornerà all'attesa precedente che stavamo cercando di evitare in origine.
Ho anche visto questo tipo di processi trasformati in processi di SQL Agent legati a una tabella utilizzata per archiviare le informazioni da elaborare. Quindi il processo viene pianificato per l'esecuzione periodica oppure viene avviato dall'applicazione utilizzando sp_start_job
quando una modifica viene memorizzata per l'elaborazione. Tuttavia, ciò consente solo un'esecuzione seriale dei processi a esecuzione prolungata, poiché SQL Agent non consente l'esecuzione simultanea di un processo più volte. Il lavoro dovrebbe anche essere progettato per gestire scenari in cui più righe entrano nella tabella di elaborazione in modo che si verifichi l'ordine di elaborazione corretto e gli invii successivi vengano elaborati separatamente.
L'utilizzo di Service Broker per l'elaborazione asincrona in SQL Server risolve effettivamente le limitazioni con i metodi menzionati in precedenza per la gestione dell'elaborazione asincrona. L'implementazione del broker consente di accodare nuove attività per l'elaborazione asincrona in background e consente anche l'elaborazione parallela delle attività che sono state accodate fino a un limite configurato. Tuttavia, a differenza del livello dell'applicazione che deve attendere quando viene raggiunto il limite, la soluzione broker semplicemente mette in coda il nuovo messaggio ricevuto e ne consente l'elaborazione al completamento di una delle attività di elaborazione correnti, consentendo all'applicazione di continuare senza attendere.
Configurazione del broker di servizi di database singolo
Sebbene le configurazioni di Service Broker possano diventare complesse, per una semplice elaborazione asincrona è sufficiente conoscere i concetti di base per creare una configurazione di database singolo. Una singola configurazione del database richiede solo:
- Creazione di due tipi di messaggio
- Uno per richiedere l'elaborazione asincrona
- Uno per il messaggio di ritorno al termine dell'elaborazione
- Un contratto che utilizza i tipi di messaggio
- Definisce quale tipo di messaggio viene inviato dal servizio iniziatore e quale tipo di messaggio viene restituito dal servizio di destinazione
- Una procedura di coda, servizio e attivazione per la destinazione
- La coda fornisce la memorizzazione dei messaggi inviati al servizio di destinazione dal servizio iniziatore
- La procedura di attivazione automatizza l'elaborazione dei messaggi dalla coda
- Restituisce un messaggio completato al servizio iniziatore quando completa l'elaborazione di un'attività richiesta
- Gestisce i tipi di messaggi di sistema http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog e http://schemas.microsoft.com/SQL/ServiceBroker/Error
- Una procedura di coda, servizio e attivazione per l'iniziatore
- La coda fornisce la memorizzazione dei messaggi inviati al servizio
- La procedura di attivazione è facoltativa ma automatizza l'elaborazione dei messaggi dalla coda
- Elabora il messaggio completato al servizio di destinazione e termina la conversazione
- Gestisce i tipi di messaggi di sistema http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog e http://schemas.microsoft.com/SQL/ServiceBroker/Error
Oltre a questi componenti di base, preferisco utilizzare una stored procedure wrapper per creare una conversazione e inviare messaggi tra i servizi del broker per mantenere pulito il codice e semplificare la scalabilità secondo necessità implementando il riutilizzo delle conversazioni o il trucco delle 150 conversazioni spiegato in il white paper del team SQLCAT. Per molte delle semplici configurazioni di elaborazione asincrona, potrebbe non essere necessario implementare queste tecniche di ottimizzazione delle prestazioni. Tuttavia, utilizzando una stored procedure wrapper, diventa molto più semplice modificare un singolo punto del codice, invece di modificare ogni procedura che invierà un messaggio in futuro, se necessario.
Se non hai dato un'occhiata a Service Broker, potrebbe fornire un metodo alternativo per eseguire l'elaborazione disaccoppiata in modo asincrono per risolvere una serie di possibili scenari. Nel mio prossimo post analizzeremo il codice sorgente per un'implementazione di esempio e spiegheremo dove sarebbe necessario apportare modifiche specifiche per sfruttare il codice per l'elaborazione asincrona.