440 likes | 633 Views
Message Queueing. Stille Post mit dem .Net-Framework. Marcel Gnoth, NTeam GmbH. No. 240. Zur Person. Dipl. Inf. Marcel Gnoth www.gnoth.net NTeam GmbH, Berlin www.nteam.de Senior Consultant, Trainer VB6, COM, Datenbanken Verteilte Informationssysteme Und .... .Net. Überblick.
E N D
Message Queueing Stille Post mit dem .Net-Framework Marcel Gnoth, NTeam GmbH No. 240
Zur Person • Dipl. Inf. Marcel Gnoth • www.gnoth.net • NTeam GmbH, Berlin • www.nteam.de • Senior Consultant, Trainer • VB6, COM, Datenbanken • Verteilte Informationssysteme • Und .....Net
Überblick • Einführung MSMQ • Vorstellen des Anwendungsszenarios • MSMQ im Detail
Message Queueing Einführung
Message – Queueing • Transport von Nachrichten zwischen Computern
Einführung Konzepte • Asynchrone Abarbeitung von Aufgaben • Empfänger oder Sender kann Offline sein • Nachrichten werden zwischengepuffert • Aktiver Austausch von Informationen • zwischen Programmen / Computern • Pushen der Infos
Einführung Technik • Versionen • NT4: MSMQ 1.0 (Option Pack) • ab Win2k MSMQ 2.0 • Bestandteil des Win2k / WinXP Setup • Active Directory / Domänen Controller • MQIS • Message Queue Information Store • Public Queues • Aktive Directory • Ohne MQIS nur Private Queues
Einführung Programmieren • Referenz auf System.Messaging • MessageQueue • Zugriff auf eine Warteschlange • Public Queues • Sind im MQIS eingetragen • Private Queues • Ohne Active Directory • Message • Nachrichten, die verschickt oder empfangen werden
Öffnen einer Queue • MessageQueue.Create (Path As String) • New MessageQueue (Path As String) • MessageQueue.Exists (Path As String) Imports System.Messaging Private WithEvents m_JobQueue As MessageQueue Sub Test() m_JobQueue = New MessageQueue _ ("Gengar\Private$\Jobs") End Sub Dim mqs As MessageQueue() = _ MessageQueue.GetPrivateQueuesByMachine("Gengar")
Wie findet MSMQ eine Queue? • Mit MQIS (Active Directory) • Public und Private • Path - Property • Label - Property • FormatName - Property • Ohne MQIS • Nur Private • FormatName - Property
Öffnen mit Path • Zugriff auf MQIS • Kein Offline • Private Queues nur lokal öffnen Dim mq As MessageQueue, s As String s = "Gengar\Jobs" 'Public s = "Gengar\Private$\Jobs" 'Private mq = New MessageQueue(s)
Öffnen mit Label • Label = Name einer Queue • Sucht über MQIS die Queue • Langsamer, da Zugriff auf MQIS • Kein Offline • Nur Public Queues Dim myQueue As New MessageQueue("Label:TheLabel")
Öffnen mit FormatName • Offline Mode • Ohne MQIS • Schnellste und flexibelste Methode FormatName:Public=5A5F7535-AE9A-41d4-935C-845C2AFF7112 FormatName:DIRECT=SPX:NetworkNumber;HostNumber\QueueName FormatName:DIRECT=TCP:IPAddress\QueueName FormatName:DIRECT=OS:MachineName\QueueName FormatName:DIRECT=OS:MachineName\Private$\QueueName Dim myQueue As New MessageQueue _ ("FormatName:DIRECT=OS:Gengar\private$\Jobs")
Senden einer Nachricht • Queue öffnen • Send Methode mit einen String oder einem Objekt aufrufen • Object wird serialisiert • XML ist Standardformat • z.B. DataSets verschicken msgQ.Send(myObject, "Message Label")
Senden mit explizitem Message - Objekt • Konfigurieren der Message – Parameter • Format, Verschlüsselung, TimeOuts • Formate für Serialisierung: • XMLMessageFormatter • BinaryMessageFormatter • ActiveXMessageFormatter With myMsg .Label = "Job " + theJob.ID .Formatter = New BinaryMessageFormatter() .AppSpecific = 34 .Priority = MessagePriority.VeryHigh .Body = theJob End With
Inhalt einer Queue ansehen • Peek – Methode • GetEnumerator myMsg = m_JobQueue.Peek() Dim eM As IEnumerator = mqJobs.GetEnumerator() lstJobMessages.Items.Clear() Do While eM.MoveNext() Dim q As Message q = CType(eM.Current, Message) lstJobMessages.Items.Add(q.Label) Loop
Nachricht empfangen • Receive • BeginReceive • Asynchrones Empfangen Dim msg As Message = mqResults.Receive() mqResults.BeginReceive() Private Sub mqResults_ReceiveCompleted(..., _ ByVal e As ...ReceiveCompletedEventArgs) _Handles mqResults.ReceiveCompleted Dim myMsg As System.Messaging.Message myMsg = e.Message End Sub
Format der Nachricht • Body ist vom Typ Object • Mögliche Typen festlegen • Formatter initialisieren • Für Deserialisierung zuständig Dim m_MsgTargetTypes(1) As Type m_MsgTargetTypes(0) = GetType(String) m_MsgTargetTypes(1) = GetType(Job) Dim m_XmlMsgFrmt As XmlMessageFormatter m_XmlMsgFrmt = New _ XmlMessageFormatter(m_MsgTargetTypes)
Nachrichten Body auspacken • Der Formatter deserialisiert den Body • Erzeugt gewünschtes Objekt Dim j As Job, s As String myMsg.Formatter = m_XmlMsgFrmt If TypeOf (myMsg.Body) Is Job Then 'Job Object j = CType(myMsg.Body, Job) ProcessJob(j) Else 'String s = CStr(myMsg.Body) Console.Write(s) End If
Woher weiß der Formatter das? • Durch Reflection kann zur Laufzeit ein Object „untersucht“ werden • Klasse als <Serializable()> kennzeichnen • Wird automatisch serialisiert <Serializable()> Public Class Job Public Name As String End Class
MSMQ in der Praxis Job Shop Scheduling als Anwendungsszenario
Job Shop Scheduling • Viele Jobs die lange dauern • Arbeit auf mehrere Rechner verteilen • Ergebnisse werden eingesammelt • Eine oder mehrere • Queue(s) mit Aufträgen • Queue(s) mit Ergebnissen
Projekte • JobShopComponent (Dll) • Klassen Job und Jobs • Kapselt Aufträge • JobShopManager (Exe) • Erzeugt Jobs • Sammelt Ergebnisse ein • Kontrolliert Bestätigungen • JobShopWorker (Exe) • Nimmt Job aus Queue • Verarbeitet Job • Sendet Ergebnis in Queue
JobShopManager.vbpj • frmCreatorMain • Erzeugt Jobs / Nachrichten • Stellt Nachrichten in Job-Queue
JobShopManager.vbpj • frmResult • Überwacht Result-Queue • Zeigt Ergebnisse an
JobShopWorker.vbpj • Lauscht an der Job-Queue • Bearbeitet Jobs • Sendet Ergebnisse an Result-Queue
MSMQ im Detail Acknowledgements TimeOuts Journlaing Transaktionen
Time Outs • Was passiert, wenn Nachricht nicht gelesen wird? • MSMQ informiert wenn Zeiten zum Übermitteln und zum Lesen überschritten werden • Properties: • TimeToReachQueue • TimeToBeReceived
Acknowlegdgements • MSMQ schickt Bestätigungs - Nachrichten • ReachQueue: Erreichen der Queue • Receive: Aus der Queue entnommen • AcknowledgeTypes: • None • FullReachQueue, PositiveArrival • NotAcknowledgeReachQueue • FullReceive, NotAcknowledgeReceive • NegativeReceive, PositiveReceive
Acknowledgements • AdministratorQueue: • Wurde der Nachricht beim Versenden übergeben • Benachrichtigungen landen in dieser Queue • Ganz „normale“ Queue • Nach dem Senden ist Message.ID gesetzt theMsg.TimeToBeReceived = New TimeSpan(0, 0, 20) theMsg.AcknowledgeType = _ AcknowledgeTypes.FullReachQueue Or _ AcknowledgeTypes.FullReceive theMsg.AdministrationQueue = m_JobAckQueue m_JobQueue.Send(theMsg) myJob.MQMessageID = theMsg.Id 'für CorrelationID
Acknowledgement Nachrichten • MessageType: • Acknowledgment • CorrelationId: • Kennung der betroffenen Nachricht • Beim Öffnen der Ack-Queue: m_JobAckQueue.MessageReadPropertyFilter.CorrelationId = True Dim j As Job, s As String j = m_Jobs.ItemByMQMessageID(theMsg.CorrelationID) s = Msg.Acknowledgment.ToString
Journaling • Überwacht Transport der Nachrichten zwischen einzelnen Computern • Nur bei Versand zwischen Computern! • Journal-Queues: • System-Queues • Individuelle für jede Queue • Eine Systemweite Journal-Queue
Journaling • Szenario: • Negatives Acknowledgement überwachen • Betroffene Nachricht aus der Journal-Queue holen (ReceiveByID) • System – Journal – Queue • Queue eigene Journal - Queue theMsg.UseJournalQueue = True theQueue.UseJournalQueue = True
Transaktion • Interne MSMQ Transaktionen • DTC – Transaktionen • Distributed Transaktion Coordinator • MSMQ, SQL-Server, Oracle, Sybase • Ressource-Manager arbeiten mit DTC zusammen • Infos: • http://msdn.microsoft.com/library/en-us/dnbda/html/bdadotnettransact1.asp
Fazit - MSMQ • Einfacher Daten (Objekt) – Austausch in der Windowswelt • Bridges in andere Welten • http://www.microsoft.com/msmq/interop.htm • http://www.envoytech.com/ • Wann Einsetzen: • Rechnerübergreifende Kommunikation • Asynchrone Abarbeitung von Programmen • Disconected Programmierung
Fazit - Queues • Public Queues • sind bequemer • nur bei solidem Active Directory • Private Queues • Schneller, weniger Overhead • Ermöglichen Offline – Betrieb • kein Domänen- oder Active Directory Controller vorhanden
Fazit – Formate • XML: • Kleine Datenmenge • BLOBs ??? • Gut lesbar • Binary: • Weniger Overhead, effizienter • Nur wenn XML keinen Sinn macht • Serialisierung kann kontrolliert werden
Links • Basic Pro 5/2001 • „Nachrichtenbasierte Informationssysteme“ • auf MSDN suchen • „Accessing Message Queues“ • http://msdn.microsoft.com/library/en-us/dnbda/html/bdadotnetasync1.asp • „Reliable Messaging with MSMQ and .NET“ • http://msdn.microsoft.com/library/en-us/dnbda/html/bdadotnetasync2.asp • MSMQ Home-Page • http://www.microsoft.com/msmq/overview.htm
Uff... Fragen?