Service Broker e gruppi di disponibilità AlwaysOn: Comportamento dispari di trasmissione della coda
-
22-10-2019 - |
Domanda
ho anche postato questa domanda sul mio blog: http://www.sqldiablo.com/2012/04/15/service-broker-alwayson-availability-groups-odd-transmission-queue-behavior/ .
Ho lavorato su un progetto nel corso degli ultimi mesi che utilizzeranno Service Broker e Gruppi di disponibilità AlwaysOn per incontrare alcuni degli obiettivi HA e DR del lavoro azienda per cui per (maggiori info: http://www.sqldiablo.com/service-broker-replication/
). Proprio di recente, sono stato in grado di implementare la soluzione completa nel mio laboratorio di sviluppo e segnalare un'istanza del nostro sito a questo. Mentre stavamo lavorando fuori alcuni nodi nel nostro database e sito web per ottenere i due lavorare bene con il mio progetto di Service Broker di replica, ho cominciato a notare un comportamento strano nel Service Broker quando è utilizzato con gruppi di disponibilità AlwaysOn, e volevo blog su di esso in un tentativo per vedere se qualcun altro ha visto questo problema e potrebbe avere un idea di come affrontarlo.
Il Setup:
Ho un host Hyper-V in esecuzione 6 di Windows Server 2008 R2 VM (BTDevSQLVM1-BTDevSQLVM6). La VM sono raggruppati in WSFCs 2 nodi con nodo e condivisione di file quorum. Ho installato standalone SQL 2012 casi Developer Edition su ciascuna delle macchine virtuali, e ha creato un gruppo di disponibilità con un ascoltatore in ogni cluster (SBReplDistrib, SBRepl1, e SBRepl2).
Ai fini di questo post del blog, mi concentrerò sulla comunicazione tra SBRepl1 e SBReplDistrib. L'illustrazione seguente mostra il Service Broker oggetti per ogni lato della conversazione:
(io sono nuovo e può pubblicare le immagini non ancora, quindi si prega di vedere il mio blog all'indirizzo di cui sopra per l'immagine)
Gli endpoint di Service Broker e percorsi sono impostati per questo articolo MSDN .Il percorso SBRepl_Receive in MSDB è per il servizio del server locale (// SBReplDistrib / SBRepl su SBReplDistrib, e // SBRepl1 / SBRepl su SBRepl1), e punti per l'istanza locale. Il percorso SBRepl_Send su SBRepl1 mappe servizio // SBReplDistrib / SBRepl a TCP: // SBReplDistrib:. 4022, e il percorso SBRepl_Send_SBRepl1 su SBReplDistrib è una mappatura simile per il servizio sul SBRepl1
Il comportamento previsto:
La mia comprensione di come Service Broker gestisce messaggio invio e la ricezione è quindi (questo è abbastanza semplificata C'è molto più in dettaglio su questo processo nel libro di Klaus Aschenbrenner “Pro SQL Server 2008 Service Broker”.):
- L'applicazione iniziatore crea un messaggio (in questo caso, ben formato XML)
- Se c'è un dialogo conversazione esistente tra il servizio iniziatore e il servizio di destinazione che è nello stato di conversazione, l'applicazione può semplicemente inviare il messaggio sul manico conversazione esistente. In caso contrario, l'applicazione iniziatore dovrebbe iniziare una conversazione di dialogo tra il servizio iniziatore e il servizio di destinazione e inviare il messaggio su quella handle di conversazione.
- Il messaggio viene inserito nella tabella di sistema sys.transmission_queue e Service Broker comincia a fare tentativi di consegna il messaggio al servizio di destinazione.
- Service Broker cerca una via adeguata e servizio remoto e li utilizza per determinare l'indirizzo per collegarsi al fine di consegnare il messaggio.
- Service Broker apre una connessione al bersaglio, autentica, e recapita il messaggio al broker servizio di destinazione.
- L'obiettivo di Service Broker tentativi di classificare il messaggio e determinare che cosa il servizio locale di gestire il messaggio (che utilizza dati di percorso nel database msdb per questo).
- Il target Service Broker recapita il messaggio del servizio di destinazione coda
- Una volta che il messaggio viene recapitato con successo per la coda di destinazione, l'obiettivo Service Broker cerca informazioni sul percorso all'initiator e tenta di fornire un riconoscimento che il caosl'età è stato ricevuto.
- Service Broker del iniziatore riceve il riconoscimento e utilizza il routing informazioni in MSDB per determinare quale servizio locale il riconoscimento è per.
- Al momento di routing con successo il riconoscimento al servizio di origine, il messaggio viene quindi rimosso dalla tabella di sistema sys.transmission_queue.
- Se l'iniziatore non riceve un riconoscimento che il messaggio è stato ricevuto, sarà periodicamente ripetere consegnare il messaggio al target. Se il bersaglio ha già ricevuto il messaggio, sarà semplicemente cadere eventuali tentativi di consegna addizionali e inviare riconoscimenti per loro.
Il comportamento dispari:
Passaggio 11 è dove sto vedendo un comportamento molto strano con Service Broker e AlwaysOn. Vedo il messaggio sempre consegnato al bersaglio e trattati con successo, e vedo anche il riconoscimento sempre rimandato l'iniziatore e ricevuto. Tuttavia, il messaggio rimane nella sys.transmission_queue come se è stata ricevuta nessuna conferma. Per rendere le cose ancora più strano, Service Broker non sta tentando di inviare nuovamente il messaggio come mi aspetterei a se il riconoscimento non è stato ricevuto. Invece, il messaggio è sufficiente rimanere nel sys.transmission_queue, e come nuovi messaggi vengono inviati, ottengono consegnato, ha riconosciuto, e anche loro rimangono nella sys.transmission_queue. Mi sembra come Service Broker sta ottenendo i riconoscimenti e, pertanto, si ferma cercando di recapitare il messaggio, ma non lo rimuove dal sys.transmission_queue per qualche ragione. Il transmission_status per questi messaggi rimane vuoto, che dovrebbe indicare che Service Broker non ha tentato di fornire loro ancora.
Ho controllato l'impostazione di ritenzione sulla coda di servizio, ed è impostato su off, ma che dovrebbe avere un impatto solo la coda di servizio e non lo sys.transmission_queue. Ho anche tracciato entrambi i lati della conversazione utilizzando SQL Profiler, e sono in grado di vedere la sempre inviato il messaggio e il riconoscimento di essere rispedito al promotore e ottenere ricevuto (vedi dati di traccia XML alla fine di questo post).
Una cosa strana ha saltato fuori a me nelle tracce però. Ho notato che entrambe le parti sembrava essere un po 'confuso circa le connessioni TCP, in quanto i messaggi vengono inviati dall'indirizzo IP del nodo stesso, mentre le linee di servizio ei messaggi stessi selezionare il nome / IP del AG ascoltatore. Questa confusione sembra essere la causa ogni lato per chiudere la connessione esistente tra i due servizi e di crearne uno nuovo, al fine di consegnare un messaggio o il riconoscimento. Non sono sicuro se questo è normale o meno, o se ha qualcosa a che fare con il motivo per cui i riconoscimenti non vengono gestiti correttamente, ma era l'unica cosa che ho potuto vedere che potrebbe spiegare il comportamento strano.
La Richiesta d'aiuto:
In questo momento, non ho una soluzione a questo problema di ritenzione messaggio diverso per terminare manualmente la conversazione con pulizia su entrambi i lati, e che non è davvero qualcosa che voglio fare. Se avete qualche idea sul motivo per cui questo potrebbe accadere o che cosa posso fare a questo proposito, si prega di lasciare un commento e fatemi sapere. Se non v'è alcuna informazione aggiuntiva che si desidera me di fornire circa il mio setup o sulla questione, per favore fatemelo sapere nei commenti come bene. Io posto un follow-up a questo post se / quando trovo una soluzione a questo problema.
La traccia dei dati:
Si prega di vedere il mio post sul blog (l'URL è all'inizio della questione).
Soluzione
Nel corso degli ultimi mesi, ho lavorato con il team di supporto del prodotto di Microsoft, e hanno riconosciuto due errori in SQL Server 2012 in relazione a questo problema. Essi sarà il rilascio di patch per quegli insetti come parte del prossimo service pack per SQL Server 2012.