Nous avons récemment identifié un problème avec l'une de nos bases de données où suite à une configuration 'fire & forget' (ie: les conversations sont fermées immédiatement après envoi), notre table sys.conversation_endpoints se remplissait de messages DI/DISCONNECTED_INBOUND. Cela a finalement débordé dans le tempDB, l'amenant à se développer énormément et à manger de l'espace disque précieux. Nous avons finalement résolu ce problème en commentant la ligneService Broker: Sys.Conversation_endpoints se remplit de messages CO/CONVERSING lors de l'utilisation de With Withup
END CONVERSATION @handle WITH CLEANUP
dans notre envoi SP et fermer les conversations dans notre SP de réception en utilisant le même code,
END CONVERSATION @handle WITH CLEANUP
Cependant, nous avons maintenant un nouveau problème. Depuis le déplacement des serveurs (et la migration de SQL Server 2005 vers SQL Server 2008), nous avons récemment découvert que sys.conversation_endpoints est maintenant rempli de messages CO/CONVERSING, indiquant que les conversations ne sont pas fermées. Le SP destinataire les ferme, ou au moins exécute la commande pour le faire, donc je ne comprends pas d'où viennent ces messages.
J'ai essayé de revenir à la fin de la conversation au moment de l'envoi, mais cela n'a aucun effet. Est-ce mal de mettre fin aux conversations sur le destinataire en utilisant WITH CLEANUP
? Ou y a-t-il un autre problème?
Ce post on techtarget semble suggérer son un bug, et que l'exécution d'un travail pour le nettoyage des restes est la seule solution ...
MISE À JOUR: Pawel a souligné ci-dessous que j'éviterons le feu & Oublier Motif , et j'ai ajouté un SP activé à la file d'attente de l'initiateur pour mettre fin à toutes les conversations. Cependant, sys.conversation_endpoints est encore en train de se remplir, cette fois avec des messages CD/CLOSED. Voici la structure de mes files d'attente
Send_SP:
DECLARE @h UNIQUEIDENTIFIER
BEGIN DIALOG CONVERSATION @h
FROM SERVICE 'InitiatorQueue' TO SERVICE 'TargetQueue'
ON CONTRACT 'MyContract' WITH ENCRYPTION = OFF;
SEND ON CONVERSATION @h MESSAGE TYPE 'MyMessage' (@msg)
Receive_SP (Activé SP sur TargetQueue)
DECLARE @type SYSNAME, @h UNIQUEIDENTIFIER, @msg XML;
DECLARE @target TABLE (
[message_type_name] SYSNAME,
[message_body] VARBINARY(MAX),
[conversation_handle] UNIQUEIDENTIFIER
)
WHILE(1=1)
BEGIN TRANSACTION
WAITFOR(RECEIVE TOP (1000)
[message_type_name],[message_body],[conversation_handle]
FROM TargetQueue INTO @target), TIMEOUT 2000
IF(@@rowcount!=0)
BEGIN
WHILE((SELECT count(*) FROM @target) > 0)
BEGIN
SELECT TOP (1) @type = [message_type_name],
@msg = [message_body],
@h = [conversation_handle] FROM @target;
// Handle Message Here
END CONVERSATION @h;
DELETE TOP (1) FROM @target;
END
END
COMMIT TRANSACTION;
End_SP (Activé SP sur InitiatorQueue)
DECLARE @type SYSNAME, @h UNIQUEIDENTIFIER, @msg XML;
DECLARE @init TABLE (
[message_type_name] SYSNAME,
[message_body] VARBINARY(MAX),
[conversation_handle] UNIQUEIDENTIFIER
)
WHILE(1=1)
BEGIN TRANSACTION
WAITFOR(RECEIVE TOP (1000)
[message_type_name],[message_body],[conversation_handle]
FROM InitiatorQueue INTO @init), TIMEOUT 2000
IF(@@rowcount!=0)
BEGIN
WHILE((SELECT count(*) FROM @init) > 0)
BEGIN
SELECT TOP (1) @type = [message_type_name],
@msg = [message_body],
@h = [conversation_handle] FROM @init;
END CONVERSATION @h;
DELETE TOP (1) FROM @init;
END
END
COMMIT TRANSACTION;
Salut Pawel, je peux certainement supprimer le NETTOYAGE AVEC J'utilise, vous pensez que cela pose problème? Je comprends que le modèle que j'utilise n'est pas le meilleur, mais il convient au type de service que nous avons. – roryok
Lorsque vous dites que le modèle «fire-and-forget» convient au type de service que vous avez, vous reconnaissez implicitement que les problèmes inhérents au fire-and-forget conviennent également au type de service. En d'autres termes, vous êtes en train de dire que vous êtes satisfait des conversations_endpoints, des messages perdus et des erreurs manquées. Personnellement, je ne crois pas que tout type de service (du moins pas que je voudrais utiliser) devrait être OK avec ces choses et c'est pourquoi j'ai recommandé de laisser tomber l'approche fire-and-forget. Mais à la fin du cours, le choix est à vous. –
Salut Pawel, je n'ai pas entièrement compris. Nous avons actuellement un système qui envoie des messages unilatéraux d'une application asp.net à une base de données via une file d'attente de courtier de service. La procédure de réception activée utilise une variable de table et extrait 1000 messages de la file d'attente à la fois, en traitant et en terminant chacun d'eux. Pour cette raison, les messages peuvent rester dans la file d'attente pendant quelques secondes. J'ai supposé (peut-être incorrectement) que changer l'initiateur pour écouter aussi les conversations finales de ces messages mettrait un retard sérieux sur le système (c'est-à-dire quelques secondes par requête), n'est-ce pas? – roryok