Question

J'ai également posté cette question sur mon blog: http://www.sqldiablo.com/2012/04/15/service-broker-alwayson-availability-groups-odd-transmission-queue-behavior/ .

Je travaille sur un projet au cours des derniers mois qui utiliseront Service Broker et groupes de disponibilité AlwaysOn pour répondre à certains des objectifs HA et DR de l'entreprise où je travaille (plus d'info: http://www.sqldiablo.com/service-broker-replication/). Tout récemment, je suis en mesure de mettre en œuvre la solution complète dans mon laboratoire de développement et tracent une instance de notre site Web à elle. Pendant que nous travaillions sur quelques petits défauts dans notre base de données et site Web pour obtenir les deux fonctionnent bien avec mon projet Service Broker réplication, j'ai commencé à remarquer un comportement étrange dans Service Broker quand il est utilisé avec groupes de disponibilité AlwaysOn, et je voulais blog à ce sujet dans une tentative pour voir si quelqu'un d'autre a vu cette question et pourrait avoir une idée de comment y faire face.

Le programme d'installation:

J'ai un hôte Hyper-V exécutant 6 Windows Server 2008 R2 machines virtuelles (BTDevSQLVM1-BTDevSQLVM6). Les machines virtuelles sont regroupées en WSFCs 2 noeuds avec quorum de partage nœud et fichier. J'ai installé SQL autonome 2012 Developer Edition instances sur chacune des machines virtuelles, et a créé un groupe de disponibilité avec un écouteur sur chaque groupe (SBReplDistrib, SBRepl1, et SBRepl2).

Aux fins de ce billet de blog, je me concentrerai sur la communication entre SBRepl1 et SBReplDistrib. L'illustration ci-dessous montre les objets Service Broker pour chaque côté de la conversation:

(je suis nouveau et ne peut pas encore publier des images, donc s'il vous plaît voir mon blog à l'adresse ci-dessus pour l'image)

Les points de terminaison Service Broker et les itinéraires sont configurés par cet article MSDN .La voie SBRepl_Receive dans MSDB est pour le service de serveur local (// SBReplDistrib / SBRepl sur SBReplDistrib et // SBRepl1 / SBRepl sur SBRepl1), et les points à l'instance locale. La route SBRepl_Send sur SBRepl1 cartes // Service SBReplDistrib / SBRepl TCP: // SBReplDistrib:. 4022, et la route SBRepl_Send_SBRepl1 sur SBReplDistrib est une application similaire pour le service sur SBRepl1

Le comportement attendu:

Ma compréhension de la façon dont gère Service Broker l'envoi de messages et la réception est donc (Il y a beaucoup plus de détails sur ce processus dans le livre de Klaus Aschenbrenner « Pro SQL Server 2008 Service Broker » Ceci est assez simplifié.):

  1. L'application initiateur crée un message (dans ce cas, XML bien formé)
  2. S'il y a une conversation de dialogue existant entre le service initiateur et le service cible qui se trouve dans l'état conversant, l'application peut simplement envoyer le message sur la poignée de conversation existante. Dans le cas contraire, l'application initiateur doit commencer une conversation de dialogue entre le service initiateur et le service cible et envoyer le message sur cette poignée de conversation.
  3. Le message est placé dans la table système sys.transmission_queue et Service Broker commence à faire des tentatives de transmettre le message au service cible.
  4. Service Broker recherche un itinéraire approprié et service à distance de liaison et utilise eux pour déterminer l'adresse de se connecter à afin de livrer le message.
  5. Service Broker ouvre une connexion à la cible, authentifie et transmet le message au courtier de service cible.
  6. Les cibles tentatives Service Broker pour classer le message et déterminer quel service local gérer le message (il utilise des données d'itinéraire dans la base de données msdb pour cela).
  7. La cible Service Broker remet le message à la file d'attente du service cible
  8. Une fois que le message est livré avec succès à la file d'attente cible, la cible Service Broker recherche des informations route de retour à l'initiateur et tente de délivrer un accusé de réception que le désordrel'âge a été reçu.
  9. Service Broker reçoit l'accusé de réception et utilise les informations de routage de l'initiateur dans MSDB pour déterminer quel service local la reconnaissance est pour.
  10. Une fois le routage réussi de la reconnaissance au service initiateur, le message est ensuite retiré de la table système sys.transmission_queue.
  11. Si l'initiateur ne reçoit pas un accusé de réception que le message a été reçu, il va réessayer périodiquement passer le message à la cible. Si la cible a déjà reçu le message, il sera tout simplement déposer des relances de livraison supplémentaires et d'envoyer des accusés de réception pour eux.

Le comportement Odd:

Étape 11 est l'endroit où je vois un comportement très étrange avec Service Broker et AlwaysOn. Je vois le message se livré à la cible et traitée avec succès, et je vois aussi la reconnaissance se renvoyé à l'initiateur et reçu. Cependant, le message reste dans sys.transmission_queue comme si aucun accusé de réception a été reçu. Pour rendre les choses encore plus étrange, Service Broker ne cherche pas à renvoyer le message comme j'attendre à si l'accusé n'a pas été reçu. Au lieu de cela, le message reste simplement dans le sys.transmission_queue, et que de nouveaux messages sont envoyés, ils sont livrés, reconnu, et ils restent aussi dans le sys.transmission_queue. Il me semble que le courtier de service reçoit les remerciements et arrête donc d'essayer de transmettre le message, mais ne supprime pas de la sys.transmission_queue pour une raison quelconque. Le transmission_status pour ces messages reste vide, ce qui devrait indiquer que le Service Broker n'a pas tenté de les livrer encore.

J'ai vérifié le réglage de rétention sur la file d'attente de service, et il est désactivé, mais cela ne devrait avoir un impact de la file d'attente de service et non l'sys.transmission_queue. J'ai aussi tracé les deux côtés de la conversation à l'aide de profils SQL, et je suis en mesure de voir le message se envoyé et l'accusé de réception étant renvoyé à l'initiateur et obtenir reçu (voir les données de trace XML à la fin de ce post).

Une chose étrange ne sauter à moi dans les traces cependant. J'ai remarqué que les deux parties semblaient être un peu confus sur les connexions TCP, car les messages sont envoyés à partir de l'adresse IP du nœud lui-même alors que les voies de service et les messages eux-mêmes pointez sur le nom / IP de l'auditeur AG. Cette confusion semble être à l'origine de chaque côté pour fermer la connexion existante entre les deux services et créer un nouveau afin de délivrer un message ou accusé de réception. Je ne sais pas si cela est normal ou non ou si elle n'a rien à voir avec la raison pour laquelle les accusés de réception ne sont pas traités correctement, mais c'était la seule chose que je pouvais voir qui pourrait expliquer le comportement étrange.

La demande d'aide:

A ce moment, je ne pas de solution à ce problème un message de rétention autre que de mettre fin manuellement la conversation avec le nettoyage des deux côtés, et ce n'est pas vraiment quelque chose que je veux faire. Si vous avez des idées pour lesquelles cela pourrait se produire ou ce que je peux faire à ce sujet, s'il vous plaît laissez-moi un commentaire et faites-moi savoir. S'il y a des informations supplémentaires que vous voulez que je vous fournir au sujet de mon installation ou sur la question, s'il vous plaît laissez-moi savoir dans les commentaires aussi. Je vais poster un suivi à ce poste si / quand je trouve une solution à cette question.

Les données Trace:

S'il vous plaît voir mon blog (l'URL est au début de la question).

Était-ce utile?

La solution

Au cours des derniers mois, je travaille avec l'équipe de support technique de Microsoft, et ils ont reconnu deux bugs dans SQL Server 2012 par rapport à cette question. Ils publieront des correctifs pour les bogues dans le cadre du prochain service pack pour SQL Server 2012.

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top