Jusqu'à quand peut-on utiliser MSMQ ? — La décision de migration d'une file d'attente héritée « qui n'est même pas dépréciée »
· Go Komura · Windows, .NET, C#, MSMQ, File de messages, Technologie héritée, Migration, Systèmes d'information
« Ce système utilise MSMQ, mais on m’a dit que c’était abandonné. Faut-il migrer d’urgence ? » — c’est une question qui revient sans cesse depuis un an environ dans les consultations sur la migration de systèmes hérités.
La réponse est un peu tordue. MSMQ (Microsoft Message Queuing) n’est, loin d’être abandonné, même pas officiellement déprécié. En juillet 2026, le nom de MSMQ n’apparaît pas dans la liste des fonctionnalités dépréciées de Microsoft, et il est toujours inclus dans les versions actuelles de Windows en tant que fonctionnalité optionnelle. Si, sur le terrain, on a néanmoins l’impression d’une « technologie terminée », c’est parce que l’API managée officielle côté .NET est fermée. La bibliothèque standard qui gère MSMQ, System.Messaging, n’existe que dans .NET Framework et n’a jamais été portée vers .NET (Core et versions ultérieures).
Autrement dit, MSMQ n’est pas une technologie qui « s’arrêtera demain », mais une technologie qui « devient un mur au moment même où l’on tente de faire évoluer l’application vers .NET ».
Le public visé par cet article est constitué des développeurs chargés de la maintenance et de la migration de systèmes existants utilisant MSMQ, ainsi que des responsables des systèmes d’information à qui l’on demande de trancher. L’objectif est de vérifier la véracité de la rumeur « il paraît que c’est abandonné » et de vous mettre en mesure de décider, selon les conditions propres à votre environnement, s’il faut migrer ou non.
Cet article distingue la rumeur des faits, puis passe en revue la décision entre continuer à utiliser MSMQ ou migrer, et la façon de choisir la cible de migration. La migration proprement dite depuis VB6 ou .NET Framework est traitée dans « Migration pratique de VB6 vers .NET » et « Liste de contrôle avant la migration de .NET Framework vers .NET » ; cet article-ci se concentre donc sur la partie file d’attente.
1. La conclusion, d’abord
- MSMQ n’est pas officiellement déprécié. Il ne figure ni sur la liste des fonctionnalités dépréciées du client Windows, ni sur la liste des fonctionnalités supprimées ou dont le développement a cessé de Windows Server (en date de juillet 2026).12
- Mais il n’existe aucune API managée officielle pour .NET. System.Messaging ne couvre que .NET Framework 1.1 à 4.8.1,3 et n’est pas non plus inclus dans le pack de compatibilité Windows, le moyen de compatibilité utilisé lors d’une migration vers .NET.4 La possibilité d’appeler l’API Win32 native via P/Invoke subsiste, mais elle se situe dans le registre du sursis (chapitre 3).
- Un portage existe via CoreWCF, mais il ne concerne que la migration des services WCF (côté récepteur) passant par une file d’attente ; c’est une voie à emprunter après vérification des conditions. CoreWCF lui-même dispose d’une politique de support de Microsoft, mais l’implémentation du transport MSMQ (CoreWCF.MSMQ) dépend d’un portage communautaire de System.Messaging pour .NET Framework.5
- L’axe de décision est « fait-on évoluer l’application vers .NET ou non ». Si oui, le principe est de migrer la file d’attente en même temps (il existe aussi des voies de sursis via P/Invoke ou CoreWCF, mais c’est une décision qui revient à assumer une charge de maintenance). Si non (conservation figée), il est possible de planifier de continuer à faire fonctionner le système tant que .NET Framework 4.8 est pris en charge en tant que composant du système d’exploitation.6
- Le premier candidat pour la cible de migration n’est pas un courtier de messages, mais une file d’attente sur table de base de données. La cohérence que MSMQ assurait avec les transactions distribuées (DTC) se remplace plus naturellement par une file d’attente sur table, traitée dans la même transaction que la base de données métier (chapitre 5).
- Commencez par faire l’inventaire du format des messages. La sérialisation de type BinaryFormatter a été supprimée du runtime dans .NET 9,7 et faire coexister l’ancien et le nouveau système avec un ancien format bloquera le processus (chapitre 6).
2. MSMQ en 30 secondes
MSMQ est une plateforme de file d’attente de messages incluse dans Windows depuis longtemps. Une application écrit des messages dans une file, et une autre application (sur la même machine ou sur une machine différente) les retire au moment qui lui convient. Ses caractéristiques se résument à trois points.
- Store-and-forward : même si le destinataire est en panne, le message s’accumule localement et parvient à destination une fois la connexion rétablie. Robuste face à des liaisons instables entre sites. Cette persistance n’est toutefois pas inconditionnelle : le message rapide (express) par défaut peut rester en mémoire, et se perd lors d’un redémarrage du service MSMQ ou de la machine. Seuls les messages pour lesquels l’émetteur a spécifié le mode Recoverable (récupérable), ou les messages transactionnels, sont persistés sur disque.
- Transactions : les opérations sur la file peuvent être transactionnelles, et combinées avec MS DTC (coordinateur de transactions distribuées), elles permettent de valider « le retrait de la file » et « la mise à jour de la base de données » dans une seule transaction distribuée.
- Inclus dans l’OS : utilisable sans installer de middleware supplémentaire, ce qui l’a fait largement adopter dans les systèmes métier des années 2000, en particulier pour l’échange de données de commandes, le traitement asynchrone de documents, ou la liaison entre étapes de production en usine.
C’est précisément parce que cette combinaison — « inclus dans l’OS, transactionnel, robuste hors ligne » — était excellente qu’elle reste encore en usage aujourd’hui. Pour envisager la cible de migration, la question centrale est de savoir lequel de ces trois points est réellement utilisé.
L’ensemble minimal de termes utilisés dans cet article
Le tableau de décision du chapitre 5 et l’inventaire du chapitre 6 supposent connus les termes suivants. Assimilez-les ici, en une fois.8
- File privée — une file qui n’est pas publiée dans le service d’annuaire (Active Directory) et n’est enregistrée que sur cet ordinateur. Elle se spécifie sous une forme comme
.\private$\nom_de_file. À l’inverse, une file publique est enregistrée dans le service d’annuaire et peut être recherchée au sein du domaine. Dans les systèmes métier de petite ou moyenne taille, ce sont presque toujours des files privées qui sont utilisées. - Message express — le mode d’envoi par défaut. Rapide car il reste en mémoire pendant et après le transport, mais il est perdu si le service MSMQ ou la machine s’arrête.
- Message recoverable (récupérable) — un mode dans lequel le message est écrit sur disque à l’émetteur et à chaque ordinateur relais, et conservé sur disque également dans la file de destination. Il survit à un redémarrage. L’émetteur doit le spécifier explicitement.
- File transactionnelle — une file qui ne traite que des messages transactionnels. Cela se décide à la création de la file et ne peut plus être modifié ensuite (ce point compte pour la procédure de migration du chapitre 6).
- DTC (Distributed Transaction Coordinator) — un service Windows qui arbitre les transactions s’étendant sur plusieurs ressources (une file MSMQ et une base de données, par exemple). C’est le mécanisme qui permet de valider ensemble « le retrait de la file » et « la mise à jour de la BD », et il constitue le point de discussion le plus important dans la décision de migration du chapitre 5.
- File journal / file des messages non distribués (dead letter) — des files système générées automatiquement par MSMQ. La file journal accumule les « copies des messages envoyés/retirés », et la file des messages non distribués accumule les « messages qui n’ont pas pu être livrés ». Si on les laisse sans surveillance, elles consomment de l’espace ; en exploitation figée, elles doivent donc être surveillées (chapitre 7).
3. Les faits — « abandonné » n’est pas exact
La question « peut-on encore utiliser MSMQ » prête à confusion parce que la réponse diffère selon la couche considérée, alors qu’on en parle comme d’un tout. Voici d’abord une vue d’ensemble sous forme de tableau.
| Couche | État actuel | Portée pratique |
|---|---|---|
| Fonctionnalité de l’OS (fonctionnalité optionnelle de Windows) | Toujours en vigueur. Incluse dans les versions actuelles de Windows client/Server, aucune déclaration de dépréciation n’a été émise12 | Fonctionne encore aujourd’hui une fois activée. Utilisable tant que dure la période de support de l’OS |
API Win32 native (MQSendMessage, etc.) |
Documentée et utilisable9 | La voie de l’appel depuis .NET via P/Invoke subsiste. Mais les formateurs et l’intégration transactionnelle doivent être écrits et maintenus soi-même |
| System.Messaging de .NET Framework | Utilisable. Mais limité à .NET Framework 1.1 à 4.8.13 | Les systèmes existants tournent ici. Il n’y a pas de suite |
| API managée officielle de .NET (Core et versions ultérieures) | N’existe pas. Non incluse dans le pack de compatibilité Windows non plus4 | Au moment de faire évoluer l’application vers .NET, la partie file d’attente doit être reconstruite |
| Liaison MSMQ de WCF → CoreWCF.MSMQ | Un portage communautaire existe. CoreWCF lui-même a une politique de support, mais l’implémentation MSMQ dépend d’un portage communautaire de System.Messaging5 | Utilisable pour prolonger la durée de vie du service WCF appelé via la file d’attente (côté récepteur), mais ce n’est ni un remplacement du côté émetteur ni une API de file d’attente générique |
| Adoption pour un nouveau projet | Non recommandée | Faute de voie officielle pour l’avenir |
Ci-dessous, nous vérifions dans l’ordre le fondement de chaque ligne de ce tableau.
Premièrement, MSMQ ne figure pas sur la liste des dépréciations. Dans la liste « Deprecated features » du client Windows, on trouve NTLM, VBScript ou WordPad, mais pas d’entrée pour MSMQ.1 Du côté de Windows Server, la liste « Features Removed or No Longer Developed » ne mentionne pas non plus MSMQ, y compris dans l’onglet Windows Server 2025.2 La dépréciation (deprecated) est une déclaration officielle signifiant « le développement actif a cessé », et cette déclaration elle-même n’a pas été émise — voilà où en sont les choses aujourd’hui.
Deuxièmement, System.Messaging s’est arrêté à .NET Framework. La version couverte par la référence va de .NET Framework 1.1 à 4.8.1, et il n’existe pas de version pour .NET (Core et versions ultérieures).3 Le pack de compatibilité Windows (Microsoft.Windows.Compatibility), qui sert de réceptacle pour les API réservées à .NET Framework, fournit environ 20 000 API — registre, WMI, services Windows, EventLog, etc. — mais son inventaire de domaines techniques n’inclut pas la messagerie (System.Messaging).4 Pour être précis, ce qui est fermé, c’est l’API managée. L’API Win32 native de MSMQ (MQSendMessage, MQReceiveMessage, etc.) est toujours documentée aujourd’hui, et l’appeler depuis .NET via P/Invoke reste possible en soi. Mais cela implique d’écrire soi-même, en tant que wrapper, les formateurs et l’intégration transactionnelle que System.Messaging prenait en charge, et de les maintenir dans la durée ; ce n’est donc pas « la solution de référence pour continuer à l’utiliser », mais « un moyen de sursis pour le cas où l’on tient absolument à le conserver ».
Troisièmement, l’intégration MSMQ de WCF se trouve dans le même mur. Le WCF de .NET Framework disposait d’une liaison utilisant MSMQ comme couche sous-jacente, mais reproduire ce chemin sur un .NET moderne mène au projet communautaire CoreWCF. CoreWCF publie, dans le cadre de ses transports de type file d’attente, un paquet compatible MSMQ (CoreWCF.MSMQ), mais son implémentation indique explicitement une dépendance à un portage communautaire de la bibliothèque System.Messaging pour .NET Framework.5 En termes de fonctionnement, cela fonctionne effectivement, et CoreWCF lui-même dispose d’une politique de support officielle de Microsoft, ce qui n’en fait pas non plus « une bibliothèque totalement sauvage ».5 Reste que la question de savoir si le portage communautaire de System.Messaging, dont dépend le transport MSMQ, bénéficie du même traitement est une autre affaire. Si vous l’adoptez, vérifiez d’abord si la version utilisée relève de la politique de support et quel traitement est réservé à cette dépendance, avant de trancher.
Voilà les fondements de chaque ligne du tableau présenté au début. Ce n’est pas que « MSMQ a été abandonné », mais que « il n’existe pas de voie officielle d’un .NET moderne vers MSMQ » — garder cette distinction en tête permet aux discussions internes de mieux converger.
4. La vraie nature du « problème alors que ça fonctionne »
Les consultations sur les systèmes impliquant MSMQ commencent presque toujours non pas par une panne, mais par une estimation de migration. La vraie nature du problème n’est pas MSMQ en lui-même, mais le fait que MSMQ devient une ancre qui retient toute l’application dans .NET Framework.
.NET Framework 4.8 est traité comme un composant de Windows et bénéficie d’un support qui suit le cycle de vie du système d’exploitation sur lequel il est installé.6 On peut donc répondre à la question « continuera-t-il de fonctionner » par « il continuera de fonctionner pour l’instant ». Il n’empêche que les points suivants s’alourdissent inexorablement avec le temps.
- On ne trouve plus de personnel, et la transmission devient impossible. Le nombre d’ingénieurs capables d’expliquer System.Messaging et DTC diminue d’année en année. C’est un exemple typique de la configuration décrite dans « Assurer la maintenance d’un système sans code source ni documentation ».
- On ne bénéficie pas des avantages du runtime ni des nouvelles bibliothèques. Beaucoup des nouvelles syntaxes C# restent utilisables sous .NET Framework par la seule mise à jour du compilateur, mais les améliorations de performance côté runtime et les nouvelles bibliothèques standard restent hors d’atteinte, et les paquets récents qui retirent .NET Framework de leur périmètre de support deviennent de moins en moins disponibles.
- Les transactions distribuées deviennent l’obstacle le plus difficile de la migration. La conception MSMQ+DTC, qui rend atomiques « le retrait de la file » et « la mise à jour de la BD », ne peut pas être reproduite avec les services de file d’attente du cloud. Si l’on ne s’occupe que de la périphérie en migrant vers .NET tout en laissant ce point de côté, c’est le noyau le plus dur qui finit par rester en dernier.
- Une bombe à retardement dans le format de sérialisation. Le corps des messages des anciens systèmes est parfois sous forme de sérialisation binaire, et BinaryFormatter a été retiré du runtime dans .NET 9.7 Il faut revoir le format des messages en même temps que la migration.
Autrement dit, la réponse pratique à la question « jusqu’à quand peut-on utiliser MSMQ » est : « ça fonctionnera tant que l’OS le prend en charge, mais la difficulté de la migration augmente à mesure qu’on attend ». Même si vous repoussez la décision, vous devriez au moins repérer d’avance, avec le tableau de décision du chapitre suivant, « où se situent les points durs ».
5. Le tableau de décision pour la cible de migration
La cible de migration ne se choisit pas en se demandant « quel est le produit successeur de MSMQ », mais selon les propriétés réellement utilisées.
5.1. Traduire d’abord les besoins en quatre questions
- L’interlocuteur de la file d’attente (le traitement côté récepteur) est-il un traitement qui met à jour votre propre base de données ?
- Utilisez-vous des transactions distribuées (DTC) ? (file transactionnelle + mise à jour de BD)
- L’émetteur et le récepteur sont-ils sur des machines ou des sites différents ? La résilience hors ligne (store-and-forward) est-elle réellement utilisée ?
- Quel est le volume réel de messages ? (Pour la plupart des systèmes métier, il s’agit de quelques milliers à quelques dizaines de milliers par jour, un volume que toutes les options gèrent sans difficulté)
5.2. Tableau de décision
| Propriété utilisée | Premier candidat | Raison et remarques |
|---|---|---|
| Traitement asynchrone au sein d’un même système (le récepteur met à jour une BD) | File d’attente sur table de BD | Permet de valider « le retrait du message » et « la mise à jour des données métier » dans une seule transaction locale, rendant DTC inutile. La sauvegarde, la surveillance et l’exploitation existantes restent utilisables telles quelles. Notez que côté émetteur aussi, « la mise à jour des données métier et l’ajout d’une ligne de message » peuvent être placées dans la même transaction, ce qui correspond au patron dit Outbox |
| Rend atomiques la file d’attente et la mise à jour de BD via DTC | File d’attente sur table de BD | L’essentiel de la migration consiste à remplacer la transaction distribuée par une transaction locale. Comme les files d’attente cloud ne peuvent pas participer à DTC, tant que ce besoin existe, les solutions à courtier constituent un détour |
| Liaison faiblement couplée entre plusieurs systèmes ou plusieurs langages | RabbitMQ (sur site) / Azure Service Bus (possible dans le cloud) | La diffusion en éventail (fan-out) et le routage sont le domaine de prédilection des courtiers. Pour RabbitMQ, prévoyez la charge d’une exploitation autogérée (redondance, mises à jour) |
| Résilience hors ligne entre sites (store-and-forward) | Azure Service Bus, etc. + conception de renvoi, ou file d’attente sur table côté site + synchronisation | Peu de mécanismes remplacent de façon transparente le « accumuler localement côté émetteur et livrer plus tard » de MSMQ. Il faut changer la conception pour confier explicitement à l’application la responsabilité d’accumuler côté émetteur |
| Producteur/consommateur au sein d’un même processus | File d’attente en mémoire comme les Channels de .NET | Un cas où une file inter-processus n’était en fait pas nécessaire. À faire tenir entièrement dans le processus, et si la persistance est requise, migrer vers une file d’attente sur table |
| Utilisé uniquement comme communication inter-processus entre services Windows | IPC comme les tubes nommés (named pipes) | Ce remplacement n’est toutefois valable que si les deux parties fonctionnent toujours simultanément. Même pendant l’arrêt du récepteur, MSMQ accepte l’envoi (même en message express) et le livre plus tard, alors qu’un tube échoue immédiatement. Si vous comptez sur cette accumulation pendant l’arrêt, implémentez le renvoi et la mise en tampon côté application, ou conservez la file d’attente. Pour le choix, voir « Le tableau de décision de l’IPC Windows » |
5.3. Implémentation minimale d’une file d’attente sur table
Beaucoup nous disent que l’expression « file d’attente sur table » ne parle pas d’elle-même ; voici donc la forme minimale. D’abord la définition de la table (SQL Server).
CREATE TABLE dbo.JobQueue (
Id BIGINT IDENTITY(1,1) PRIMARY KEY,
Payload NVARCHAR(MAX) NOT NULL, -- corps du message, conservé en JSON
Status TINYINT NOT NULL DEFAULT 0, -- 0:non traité 1:en cours 2:terminé
EnqueuedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
StartedAt DATETIME2 NULL, -- sert à récupérer les lignes restées "en cours" après un plantage
RetryCount INT NOT NULL DEFAULT 0
);
CREATE INDEX IX_JobQueue_Status ON dbo.JobQueue (Status, Id);
Le retrait marque une seule ligne comme « en cours de traitement » tout en récupérant son contenu. Ajouter READPAST permet de sauter les lignes verrouillées par d’autres workers sans attendre (on peut ainsi faire tourner plusieurs processus en parallèle).
WITH next_job AS (
SELECT TOP (1) *
-- READCOMMITTEDLOCK est nécessaire sur une BD où READ_COMMITTED_SNAPSHOT est à ON (voir plus loin).
-- Sur une BD à OFF, cela correspond au comportement par défaut, donc le garder fonctionne dans les deux cas
FROM dbo.JobQueue WITH (READPAST, UPDLOCK, READCOMMITTEDLOCK)
WHERE Status = 0
ORDER BY Id -- retire dans l'ordre d'insertion. C'est la condition pour que ce soit une « file »
)
UPDATE next_job
SET Status = 1, StartedAt = SYSUTCDATETIME()
OUTPUT inserted.Id, inserted.Payload;
READPAST ne peut pas être utilisé tel quel sur une base de données où READ_COMMITTED_SNAPSHOT est à ON. La documentation officielle précise explicitement que « lorsque READ_COMMITTED_SNAPSHOT est à ON et que le niveau d’isolement de la session est READ COMMITTED (ou que l’indice READCOMMITTED est également utilisé), READPAST ne peut pas être spécifié », et indique, comme parade dans ce cas, d’ajouter l’indice READCOMMITTEDLOCK.10 Le niveau d’isolement par défaut étant READ COMMITTED, sur une base de données où l’on s’est contenté d’activer READ_COMMITTED_SNAPSHOT, ce retrait ne se contente pas de « sauter les lignes des autres workers » : l’instruction elle-même échoue avec une erreur. Sur Azure SQL Database, ce paramètre est ON par défaut, et il n’est pas rare non plus, sur site, de l’avoir activé comme mesure contre le blocage en lecture. Vérifiez d’abord lequel des deux cas s’applique à la base de données de destination.
SELECT is_read_committed_snapshot_on FROM sys.databases WHERE name = DB_NAME();
Si l’on omet ROWLOCK par rapport au WITH (READPAST, UPDLOCK, ROWLOCK) qu’on voit souvent, c’est parce que ROWLOCK et READCOMMITTEDLOCK appartiennent au même groupe d’« indices de granularité », et qu’on ne peut pas spécifier les deux sur une même table.10 Comme READPAST ne peut sauter que les verrous de ligne et pas les verrous de page, on aimerait bien préciser ROWLOCK, mais une escalade ne se produit en pratique jamais pour la seule ligne récupérée par une recherche d’index avec TOP (1). Si vous savez que READ_COMMITTED_SNAPSHOT est à OFF et souhaitez préciser ROWLOCK, retirez plutôt READCOMMITTEDLOCK.
Si l’on omet ORDER BY et écrit simplement UPDATE TOP (1), la ligne sélectionnée devient indéterminée. Il est officiellement précisé que le TOP d’un UPDATE ne trie pas les lignes concernées, et même avec un index sur (Status, Id), cela ne garantit pas l’ordre de retrait.11 Pour une liaison qui suppose un traitement dans l’ordre d’insertion, cela se traduit par un dysfonctionnement où les anciens travaux sont indéfiniment repoussés.
Cela dit, ORDER BY Id ne garantit que l’ordre de retrait. L’ordre de fin de traitement n’est pas garanti. Comme READPAST sert à « sauter les lignes verrouillées par d’autres workers », pendant que le worker A a saisi le job 1 et met longtemps, le worker B peut saisir le job 2 et valider avant lui.
| Ce qui est garanti | Ce qui ne l’est pas |
|---|---|
Quelle ligne est retirée en premier (ORDER BY Id) |
Quelle ligne est répercutée en premier sur les données métier |
Pour une liaison où l’ordre de répercussion a de l’importance — par exemple « il serait problématique que les mises à jour d’un même numéro de commande soient inversées » — cela ne suffit pas. Les formes possibles sont l’une des deux suivantes.
- Réduire les consommateurs à un seul. Sacrifier le parallélisme pour garantir l’ordre. Si le débit est suffisant, c’est la forme la plus simple et la plus robuste.
- Répartir par clé. Soit affecter les workers de façon fixe selon une clé comme le numéro de commande, soit ajouter côté retrait une condition « ne pas retirer si une ligne de la même clé est en cours de traitement », de manière à ne garantir l’ordre qu’à l’intérieur d’une même clé. On renonce à l’ordre entre clés différentes.
Si vous n’adoptez ni l’une ni l’autre, indiquez explicitement dans la conception de la migration que le FIFO global n’existe plus dès lors qu’on parallélise. C’est un point particulièrement négligé lors d’une migration depuis MSMQ. La même chose se produit avec une file MSMQ reçue en parallèle, mais si l’on migre en conservant l’idée que « c’est une file, donc l’ordre est respecté », le problème d’ordre semble surgir tout à coup dès qu’on passe à une file d’attente sur table.
Le worker côté récepteur n’a plus qu’à exécuter cela dans la même transaction locale que le traitement métier (C#, pseudo-code).
while (!stoppingToken.IsCancellationRequested)
{
using var tx = connection.BeginTransaction();
var job = DequeueOne(connection, tx); // le UPDATE ... OUTPUT ci-dessus
if (job is null)
{
tx.Commit();
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken); // si vide, on attend juste l'intervalle de scrutation
continue;
}
ApplyBusinessData(connection, tx, job); // ← mise à jour des données métier (le vrai travail voulu)
MarkDone(connection, tx, job.Id); // Status = 2
tx.Commit(); // « le retrait » et « la mise à jour métier » sont validés simultanément par cette ligne
}
C’est précisément là que réside le remplacement de MSMQ+DTC. Avec MSMQ, « le retrait de la file » et « la mise à jour de la BD » étaient deux ressources distinctes, ce qui nécessitait une transaction distribuée (DTC) pour les réunir. Si la file d’attente est une table de BD, les deux opérations sont des mises à jour de la même base de données, si bien que une transaction locale ordinaire suffit. Introduire RabbitMQ ou Azure Service Bus fait perdre cette propriété (la file et la BD redeviennent des ressources distinctes), et il faut alors implémenter soi-même l’idempotence et le renvoi côté application.
En exploitation réelle, il faut ajouter à peu près les trois choses suivantes.
- La récupération des lignes restées « en cours » à cause d’un plantage. Mettez en place un traitement de récupération exécuté périodiquement, qui remet à
Status = 0les lignes oùStatus = 1et oùStartedAtest plus ancien qu’un certain seuil. - Une limite de nouvelles tentatives et une mise à l’écart. Les lignes dont
RetryCountdépasse la limite sont déplacées vers une table séparée (ou versStatus = 9). C’est l’équivalent de la file des messages non distribués de MSMQ. - Le nettoyage des lignes terminées. Supprimez ou archivez périodiquement les lignes où
Status = 2. Sans cela, la table grossit et l’efficacité de l’index diminue.
Côté émetteur, placez la mise à jour des données métier et l’INSERT de la ligne de message dans la même transaction (patron Outbox). Cela fait aussi disparaître l’incohérence où « les données métier ont été mises à jour mais le message n’est pas parti ».
Ce que nous voulons souligner, c’est que pour les systèmes métier de petite ou moyenne taille, la file d’attente sur table est souvent le premier candidat. Les articles comparant les produits de file de messages ont tendance à prendre la forme « RabbitMQ contre Kafka contre Service Bus », mais ce que les systèmes de génération MSMQ mettent le plus souvent dans leur file, ce sont des « tâches asynchrones qui mettent à jour la même BD », et cela se réalise très bien — de façon même plus simple — avec une table de BD et de la scrutation (ou une notification). Le coût d’exploitation d’un middleware supplémentaire (surveillance, redondance, correctifs, formation du personnel) pèse particulièrement lourd pour une structure de petite ou moyenne taille.
6. La procédure pratique de migration
La démarche suit le principe habituel de la migration de systèmes hérités : « observer avant d’agir ».
-
Faire l’inventaire des dépendances. Repérez dans le code les références à
System.Messaginget les endroits où desMessageQueuesont créés. Recherchez également, dans les fichiers de configuration WCF,netMsmqBinding/msmqIntegrationBinding, ainsi que les appels à l’API native (les fonctionsMQ*telles queMQSendMessage) ou via COM. Il peut exister des chemins dépendant de MSMQ même sans référence à System.Messaging. Les points à vérifier sont : (a) le chemin de la file (locale ou distante, privée ou publique), (b) s’il s’agit d’une file transactionnelle, si les messages sont marqués Recoverable (si aucun des deux, le système actuel fonctionne en partant du principe que les messages peuvent être perdus lors d’un redémarrage), (c) le formateur (XmlMessageFormatter/BinaryMessageFormatter/ActiveXMessageFormatter), (d) l’utilisation de la file journal et de la file des messages non distribués, et (e) qui crée et supprime la file (l’installeur ou l’application).Le simple fait de vérifier ne suffit pas à alimenter la décision de migration. Remplissez une ligne par file d’attente sous la forme suivante, et utilisez-la directement comme fondement de l’orientation de migration (elle peut servir telle quelle d’annexe à un document d’approbation interne).
Point de vue Où regarder Ce qu’il faut consigner Impact sur la décision (a) Chemin de la file La chaîne de chemin passée à MessageQueue, la destination de connexion dans le fichier de configuration, la spécificationFormatName:Local/distant, privé/public, nom de la machine interlocutrice Si distant/inter-sites, détermine la nécessité du store-and-forward (ligne « résilience hors ligne » du 5.2). Si tout est local, correspond à la première ligne du 5.2 (b) Transaction et Recoverable L’endroit où la file est créée (file transactionnelle ?), si Recoverable est spécifié à l’envoi, si DTC est utilisé File transactionnelle ou non, spécification de Recoverable ou non, participation à DTC ou non Si DTC est présent, la cible de migration est presque certainement une file d’attente sur table. Si aucun des deux n’est présent, indiquez explicitement que le système actuel fonctionne en partant du principe que « les messages peuvent disparaître lors d’un redémarrage » (c) Formateur Les endroits où sont spécifiés XmlMessageFormatter/BinaryMessageFormatter/ActiveXMessageFormatterLe formateur utilisé et le type du corps du message Si c’est un formateur de type BinaryFormatter, le remplacement par JSON est indispensable (étape 2). Cela devient le principal facteur de charge de la migration7 (d) File journal / file des messages non distribués Les propriétés de la file (journal activé ?), le contenu des files système, les procédures d’exploitation L’utilisation ou non du journal, si la file des messages non distribués est réellement consultée La question de savoir « comment sont traités les messages en échec » devient une exigence de conception de la cible de migration (une table de mise à l’écart pour une file d’attente sur table) (e) Qui crée et supprime L’installeur, les scripts de déploiement, les appels à Createau démarrage de l’applicationLe responsable de la création, et qui configure les autorisations Détermine directement « qui préparera la nouvelle file » lors de la migration. En cas de conservation figée, à reporter dans la procédure de préparation des postes (chapitre 7) - Déterminer le format des messages. Prenez JSON comme format par défaut après migration. Ce qu’il ne faut pas transporter, c’est une sérialisation de type BinaryFormatter, comme BinaryMessageFormatter. BinaryFormatter est déjà supprimé dans .NET 9 et n’est pas non plus recommandé du point de vue de la sécurité.7 En revanche, si vous utilisez un format binaire dont les spécifications sont maintenues indépendamment, comme Protocol Buffers ou MessagePack, transporter tel quel ce format vers le nouveau système ne pose pas de problème en soi.
- Migrer en commençant par le côté récepteur. Préparez d’abord la nouvelle file (par exemple une file d’attente sur table), adaptez le traitement côté récepteur à la nouvelle file, puis basculez l’émetteur. Pendant la période de migration, insérer un petit pont qui déplace les messages de l’ancien MSMQ vers la nouvelle file (celui-ci peut rester en .NET Framework) permet d’éviter de basculer tous les émetteurs d’un coup. Mais si ce pont tombe en panne entre « le retrait depuis MSMQ » et « l’écriture vers la nouvelle file », il perd le message ou le fait circuler en double. Si la source de migration est une file transactionnelle, la condition minimale est de configurer la réception côté MSMQ en mode transactionnel afin de pouvoir revenir en arrière en cas d’échec d’écriture, et de concevoir le côté nouvelle file de façon à rejeter les doublons par l’identifiant du message (conception idempotente). Si la source de migration est une file non transactionnelle, cette méthode est inutilisable, car l’attribut transactionnel d’une file se décide à la création et ne peut plus être modifié ensuite. Dans ce cas, organisez le flux ainsi : « lire avec Peek → écrire de façon idempotente vers la nouvelle file → confirmer que l’écriture a réussi avant de retirer » (même en cas de panne avant le retrait, le doublon est absorbé par l’idempotence de la nouvelle file). Si aucune des deux implémentations n’est proportionnée à l’ampleur du système, il est plus sûr de se rabattre, sans pont, sur l’étape 5, « vider puis basculer ».
- Fixer le comportement avant de réécrire. Le traitement des files d’attente est un domaine propice aux bugs dépendant du timing. Préparer avant la migration des tests de caractérisation du type « pour ce message d’entrée, ce résultat » rend la vérification après remplacement mécanique (« Figer le comportement avec des tests de caractérisation avant de refactoriser »).
- Basculer lorsque la file est vide. Basculer alors que des messages subsistent est un terreau pour les traitements en double ou les pertes. Vider entièrement la file lors d’un arrêt planifié avant de basculer reste, au final, la méthode la plus sûre et la plus rapide.
7. Les conditions minimales pour choisir la conservation figée
La décision de « ne pas migrer pour l’instant, faute de projet de faire évoluer l’application vers .NET et au vu du rapport coût-bénéfice » est raisonnable, sous conditions. Voici les conditions minimales pour ce cas, sous forme de liste de contrôle transposable telle quelle dans un document d’approbation ou de revue interne. Considérez que la « conservation figée » ne devient une option qu’une fois les quatre points cochés.
| Vérification | Condition minimale | Action concrète | Ce qui se passe si non respecté |
|---|---|---|---|
| □ | Indiquer explicitement MSMQ dans les procédures de préparation des postes et de restauration | MSMQ est une fonctionnalité optionnelle de Windows. Notez, dans le manuel de mise en place de l’environnement, la procédure d’activation via « Activer ou désactiver des fonctionnalités Windows » ou via DISM/PowerShell | Lors du remplacement d’un PC ou d’un serveur, l’activation est oubliée et le système ne fonctionne pas le jour de la migration, pour une cause qui reste incomprise |
| □ | Surveiller la longueur de la file | Mettre en place une surveillance par seuil du nombre de messages en attente, avec notification. Inclure également la file des messages non distribués et la file journal | Si le récepteur s’arrête, il n’y a pas d’erreur et les messages continuent de s’accumuler, si bien que l’activité s’arrête sans que personne ne s’en aperçoive |
| □ | Documenter la configuration | Consigner le chemin de la file, les autorisations, la présence de transactions, le formateur et les paramètres du journal (le tableau d’inventaire du chapitre 6 peut être réutilisé tel quel) | La future estimation de migration devra repartir d’une enquête complète, ce qui dégrade à la fois la précision et la charge de travail |
| □ | Réexaminer la décision une fois par an | Vérifier chaque année si « MSMQ a été ajouté à la liste des dépréciations » et si « une mise à jour de l’OS a modifié son comportement » | On finit par agir dans la précipitation une fois l’annonce de dépréciation publiée |
Le quatrième point est particulièrement sujet à être négligé, mais c’est précisément cette vérification annuelle qui permet de ne pas paniquer même une fois l’annonce publiée. À l’inverse, une conservation figée dans un environnement où ces quatre points ne sont pas remplis revient à « attendre un arrêt invisible ».
8. Conclusion
- MSMQ n’est pas officiellement déprécié en juillet 2026 et perdure en tant que fonctionnalité de l’OS. La perception d’un « abandon » n’est pas exacte.12
- En revanche, System.Messaging reste réservé à .NET Framework, n’est pas inclus dans le pack de compatibilité, et il n’existe pas de voie officielle vers .NET (Core et versions ultérieures). CoreWCF lui-même dispose d’une politique de support, mais son transport MSMQ dépend d’un portage communautaire de System.Messaging.345
- L’axe de décision est « fait-on évoluer l’application vers .NET ». Si oui, le principe est de migrer la file d’attente en même temps (un sursis via P/Invoke, etc., s’échange contre une charge de maintenance) ; si l’on choisit la conservation figée, cela ne tient qu’à condition de surveillance et de documentation.6
- Le premier candidat pour la cible de migration est une file d’attente sur table de BD. L’essentiel consiste à remplacer la cohérence de MSMQ+DTC par une transaction locale ; l’introduction d’un produit à courtier n’est à envisager qu’ensuite.
- La sérialisation de type BinaryFormatter ne peut plus être transportée vers le nouveau système, du fait de sa suppression dans .NET 9. Lors de la migration, prenez JSON par défaut, tout en pouvant conserver tel quel un format maintenu indépendamment comme protobuf.7
- Basculer dans l’ordre récepteur → pont → émetteur, en fixant le comportement avec des tests de caractérisation avant de réécrire, est la démarche qui évite les incidents.
Articles connexes
- Jusqu’à quand une application VB6 fonctionnera-t-elle ? — État du support du runtime et un chemin pratique vers la migration vers .NET
- Liste de contrôle avant la migration de .NET Framework vers .NET
- Figer le comportement avec des tests de caractérisation (Characterization Test) avant de refactoriser
- Le tableau de décision de l’IPC (communication inter-processus) Windows
- Le malentendu selon lequel on pourrait recevoir avec Receive chaque unité envoyée avec Send en TCP — concevoir la réception pour traiter les données comme un flux d’octets
- Comment assumer la maintenance d’un système sans code source ni documentation
- Migration de schéma de base de données et gestion de versions pour les applications métier
Domaines de conseil associés
合同会社小村ソフト (Komura Software LLC) prend en charge l’inventaire et la planification de migration des configurations héritées incluant MSMQ, la migration de .NET Framework vers .NET, ainsi que la refonte de systèmes métier incluant le traitement de files d’attente.
- Valorisation des actifs existants et accompagnement de migration
- Refonte et maintenance de logiciels Windows existants
- Développement d’applications Windows
- Contact
Références
-
Microsoft Learn, Deprecated features in the Windows client. La liste officielle des fonctionnalités du client Windows dont le développement actif a cessé (dépréciées). Le fait que la liste en date de juillet 2026 mentionne NTLM, VBScript, WordPad, etc., mais pas MSMQ (Microsoft Message Queuing), et que la dépréciation (deprecated) désigne un stade où « le développement n’est plus actif et la fonctionnalité pourrait être supprimée dans une future mise à jour », distinct de la suppression (removed). ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Features Removed or No Longer Developed in Windows Server. La liste officielle des fonctionnalités supprimées et des fonctionnalités dont le développement a cessé (dépréciées) pour Windows Server. Le fait que MSMQ ne figure pas dans la liste en date de juillet 2026, y compris dans l’onglet Windows Server 2025, et que les composants dépréciés continuent d’être inclus dans Windows Server, restent pris en charge en production selon le cycle de vie du produit, et continuent de recevoir des mises à jour de sécurité et de qualité. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, MessageQueue Class (System.Messaging). Le fait que la référence de la classe System.Messaging.MessageQueue couvre les versions .NET Framework 1.1 à 4.8.1, et qu’il n’existe pas de version pour .NET (Core et versions ultérieures). ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Use the Windows Compatibility Pack to port code to .NET. Le fait que le pack de compatibilité Windows (paquet Microsoft.Windows.Compatibility) fournisse environ 20 000 API pour combler la dépendance aux API réservées à .NET Framework lors d’une migration vers .NET, et que son inventaire de domaines techniques (CodeDom, configuration, Directory Services, Drawing, ODBC, ACL, WCF, registre, WMI, compteurs de performance, services Windows, EventLog, etc.) n’inclue pas la messagerie (System.Messaging). ↩ ↩2 ↩3 ↩4
-
CoreWCF project, CoreWCF.MSMQ (NuGet) et CoreWCF 1.4.0 Preview release, Microsoft, CoreWCF Support Policy. Le fait que CoreWCF soit un projet communautaire portant le côté serveur de WCF vers .NET, pour lequel Microsoft fournit une politique de support officielle ; qu’un support MSMQ (paquet CoreWCF.MSMQ) soit publié dans le cadre des transports de type file d’attente ; et que cette implémentation MSMQ dépende d’un portage communautaire de la bibliothèque System.Messaging pour .NET Framework. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, .NET Framework official support policy. Le fait que .NET Framework 4.8 soit défini comme un composant du système d’exploitation Windows, et pris en charge selon la politique de cycle de vie du produit parent (l’OS) sur lequel il est installé. ↩ ↩2 ↩3
-
Microsoft Learn, BinaryFormatter migration guide. Le fait que BinaryFormatter soit progressivement retiré pour des raisons de sécurité, que son implémentation soit supprimée du runtime à partir de .NET 9 et ne soit plus utilisable par défaut, et que des formats de sérialisation sûrs comme JSON (System.Text.Json) soient recommandés comme cible de migration. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn (archives), Express and Recoverable Messaging, System-Generated Queues, Message Queuing (MSMQ). Le fait que le message express soit conservé en RAM pendant et après le transport, et se perde si l’ordinateur où réside le message ou le service MSMQ s’arrête ; que le message recoverable soit écrit sur disque chez l’émetteur et à chaque ordinateur relais, et conservé sur disque également dans la file de destination ; que la file publique soit enregistrée dans le service d’annuaire tandis que la file privée n’est enregistrée que sur l’ordinateur local et n’est pas publiée dans le service d’annuaire ; et que la file journal, qui conserve les messages retirés de la file ou une copie des messages envoyés, et la file des messages non distribués (dead letter), qui conserve les messages qui n’ont pas pu être livrés, soient des files système générées par MSMQ. ↩
-
Microsoft Learn (archives), Message Queuing Functions et MQSendMessage, MQReceiveMessage. Le fait que l’API Win32 native de MSMQ (MQCreateQueue, MQSendMessage, MQReceiveMessage, etc.) soit documentée pour les applications C/C++, et permette de créer, envoyer et recevoir des files sans passer par une API managée. ↩
-
Microsoft Learn, Indicateurs de table (Transact-SQL). Sur le fait que
READPASTsoit un indice qui saute, sans les lire, les lignes verrouillées par d’autres transactions, que seuls les verrous au niveau ligne puissent être sautés (pas les verrous au niveau page), et qu’il ne puisse être spécifié qu’aux niveaux d’isolementREAD COMMITTEDouREPEATABLE READ. En particulier, sur la précision suivante : « si l’option de base de donnéesREAD_COMMITTED_SNAPSHOTest définie surON, et que (a) le niveau d’isolement de transaction de la session estREAD COMMITTED, ou que (b) l’indice de tableREADCOMMITTEDest également spécifié dans la requête, alors l’indice de tableREADPASTne peut pas être spécifié. Pour spécifier l’indiceREADPASTdans ces cas, retirez l’indice de tableREADCOMMITTEDs’il est présent, et incluez l’indice de tableREADCOMMITTEDLOCKdans la requête ». Voir également la même page pour le fait queREADCOMMITTEDLOCKsoit un indice qui impose unREAD COMMITTEDpar verrouillage indépendamment du paramétrage deREAD_COMMITTED_SNAPSHOT, et qu’on ne puisse pas spécifier plus d’un indice de granularité (PAGLOCK/NOLOCK/READCOMMITTEDLOCK/ROWLOCK/TABLOCK/TABLOCKX) pour une même table. Le paramétrage côté base de données peut être vérifié viais_read_committed_snapshot_ondans sys.databases. ↩ ↩2 -
Microsoft Learn, TOP (Transact-SQL). Sur le fait que, lors de l’utilisation de TOP avec INSERT, UPDATE, MERGE ou DELETE, les lignes référencées ne soient triées selon aucun ordre particulier, et que pour déterminer un ordre, il faille utiliser une sous-requête combinant TOP et ORDER BY. ↩
Articles associés
Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.
Jusqu'à quand les applications VB6 continueront-elles de fonctionner ? — état du support du runtime et démarche concrète vers une migration .NET
Jusqu'à quand les applications VB6 continueront-elles de fonctionner ? Cet article clarifie l'asymétrie entre la politique de support du ...
Bonnes pratiques de multithreading en pratique — édition .NET : ce qu'il faut décider avant d'ajouter des threads
Un ensemble de bonnes pratiques de conception pour .NET/C# afin d'éviter que « démarrer un thread » ne fasse planter ou geler l'applicati...
Utiliser WMI/CIM depuis C# et PowerShell — Guide pratique pour la récupération d'informations matérielles, la surveillance des processus et l'interrogation à distance
La récupération du numéro de série d'un PC, la surveillance de l'espace disque libre et la détection du démarrage de processus reposent c...
Le TPM sous Windows expliqué en images — le « coffre-fort qui ne laisse jamais sortir la clé » et le démarrage mesuré
Explique le TPM en images : le mécanisme qui empêche la clé de sortir de la puce, les PCR et le démarrage mesuré, son usage dans BitLocke...
Compatibilité descendante des interfaces DLL et COM — Tableau de décision : quels changements cassent les appelants
Quels changements apportés à une DLL ou à un composant COM cassent réellement leurs appelants ? Nous détaillons les trois niveaux de comp...
Sujets associés
Ces pages replacent le sujet dans un contexte plus large de services et de décisions.
Thèmes techniques Windows
Portail des sujets sur le développement Windows, l'analyse des incidents et la valorisation des actifs existants.
Migration ActiveX
Choisir de conserver, encapsuler ou remplacer des composants COM / ActiveX / OCX.
Services liés à ce sujet
Cet article est directement lié aux services suivants.
Développement d'applications Windows
Applications métier, intégration d'équipements et outils de communication, des besoins au développement.
Maintenance et modernisation de logiciels Windows
Ajouts de fonctions, maintenance et modernisation progressive de logiciels Windows existants.
Questions fréquentes
Questions souvent posées lors d’une consultation sur le sujet de cet article.
- MSMQ a-t-il été abandonné ?
- Non. En juillet 2026, MSMQ ne figure ni sur la liste des fonctionnalités dépréciées du client Windows, ni sur la liste des « fonctionnalités supprimées ou dont le développement a cessé » de Windows Server. Il est toujours inclus dans les systèmes d'exploitation actuels en tant que fonctionnalité optionnelle de Windows. L'expression « abandonné » s'est répandue parce qu'elle est confondue avec la situation côté .NET. La bibliothèque de classes standard qui gère MSMQ, System.Messaging, n'existe que dans .NET Framework et n'a jamais été portée vers .NET (Core et versions ultérieures). Autrement dit, plus précisément : « la fonctionnalité perdure en tant que composant du système d'exploitation, mais il n'existe aucun moyen officiel de l'utiliser depuis un .NET moderne ».
- Existe-t-il un moyen d'utiliser MSMQ depuis .NET 8 ou .NET 10 ?
- Il n'existe aucune API managée officielle. System.Messaging est une API qui s'arrête à .NET Framework 4.8.1 et n'est pas non plus incluse dans le pack de compatibilité Windows (Microsoft.Windows.Compatibility). Il est techniquement possible d'appeler l'API Win32 native de MSMQ (MQSendMessage, etc.) via P/Invoke, mais cela revient à devoir écrire et maintenir soi-même un wrapper incluant les formateurs et l'intégration transactionnelle. Du côté communautaire, le projet CoreWCF publie un paquet pour le transport MSMQ (CoreWCF.MSMQ), mais celui-ci sert à héberger sur un .NET moderne des services WCF appelés via une file d'attente (le portage du côté serveur de WCF) ; ce n'est ni une API de file d'attente générique se substituant à System.Messaging, ni un remplacement pour le client émetteur. Son implémentation dépend elle-même d'un portage communautaire de System.Messaging pour .NET Framework. Cela peut constituer une option de validation ou de sursis provisoire. CoreWCF lui-même dispose d'une politique de support officielle de Microsoft, mais cette garantie ne s'étend pas nécessairement au portage communautaire de System.Messaging dont dépend cette implémentation MSMQ ; si vous envisagez de fonder un système métier sur cette base, vérifiez d'abord si la version que vous utilisez est couverte par la politique de support, ainsi que le traitement réservé à cette dépendance, avant de trancher. En pratique, la bonne approche consiste à migrer la file d'attente en même temps que l'application vers .NET.
- Faut-il choisir RabbitMQ ou Azure Service Bus comme cible de migration ?
- Avant ce choix binaire, envisagez d'abord de transformer une table de base de données en file d'attente. La plupart des systèmes métier de petite ou moyenne taille utilisant MSMQ ont, comme interlocuteur de la file d'attente, un traitement qui met à jour leur propre base de données. Dans ce cas, une file d'attente basée sur une table permet de valider « le retrait du message » et « la mise à jour des données métier » dans la même transaction locale que les données métier, remplaçant par un mécanisme plus simple la cohérence qu'assuraient MSMQ et les transactions distribuées (DTC). Si la file d'attente sur table ne suffit pas à des besoins comme une diffusion faiblement couplée entre plusieurs systèmes ou un débit élevé, envisagez alors RabbitMQ si les contraintes sur site sont fortes, ou Azure Service Bus si le cloud est possible — cet ordre limite le risque d'échec.
- Est-il acceptable de rester pour l'instant sur .NET Framework, en « conservation figée » ?
- C'est acceptable, sous conditions. .NET Framework 4.8 est pris en charge comme composant de Windows, suivant le cycle de vie du système d'exploitation, et MSMQ lui-même n'est pas déprécié, si bien qu'on peut raisonnablement prévoir qu'il « continuera de fonctionner ». Cependant, si vous choisissez la conservation figée, faites au minimum ces quatre choses : indiquer explicitement l'activation de la fonctionnalité MSMQ dans la procédure de préparation des postes, mettre en place une surveillance de la longueur des files et des journaux, documenter le format des messages et la configuration des connexions, et conserver une procédure de reprise en cas de changement de personnel responsable. Le vrai risque de la conservation figée n'est pas technique : c'est qu'il ne reste plus personne capable d'y toucher.
Profil de l’auteur
Page de présentation de l’auteur de l’article.
Go Komura
Représentant de KomuraSoft LLC
Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.