Dieser Artikel wurde maschinell übersetzt.

Prognose: bewölkt

Windows Azure – AppFabric Service Bus: Themen

Joseph Fultz

 

Dieser Artikel basiert auf dem Windows Azure – AppFabric CTP Juni-Update.Änderungen einer Allen Informationen in Diesem Artikel Sind Vorbehalten.

Joseph FultzEs ist kein Geheimnis unter meiner Kollegen, dass die Windows Azure Service Bus-Funktionalität nicht wirklich viel Unterstützung von mir erhalten.Allerdings hat mit dem Windows Azure – AppFabric CTP Juni Update Microsoft schließlich hinzugefügt genügend Funktionen verschieben den Service Bus, was ich nicht viel mehr als ein Platzhalter für eine wirklich nützliche Technologie betrachtet.Für meine Zwecke ist wesentliche Bestandteil der messaging-Technologie – AppFabric Service Bus jetzt bietet Themen, eine umfangreiche publish-and-subscribe-Funktion.Ich werde auf Themen in diesem Artikel und zeichnen, konzentrieren wie ich bin so oft apt dazu aus meiner Retail Industry Erfahrung zu prüfen, wie die Technologie zur Erleichterung der Kontrollen des Bestandsverzeichnisses inter-store verwendet werden kann.

Haben Sie jemals, etwas kaufen und zuletzt wurde gerade verkauft, oder, dass das gewünschte Element in gewisser Weise ist durcheinander gegangen?Wenn dies geschieht, Verkäufe Sekretärin oft gehen in die POS-System und überprüfen Sie den Lagerstand Läden in der Nähe.Mehr als oft nicht, diese Prüfung ist gegen Bestandszahlen, die in einer zentralen Datenbank oder Enterprise Resource planning (ERP)-System eines Typs aufbewahrt werden und die Schreiber überprüft in der Regel durch ihre Erfahrungen der nahe gelegenen Läden mit Lagernummer.Die Daten ist häufig ein wenig veraltet, da er nur als Teil der End-of-Day verarbeiten, wenn die Transaktionsprotokolle und andere Daten aktualisiert wurde hochgeladen und vom corporate System verarbeitet werden.

Ein Szenario besser geeignet wäre, dass ein Speicher jederzeit eine Anforderung über die Verfügbarkeit der Produkte in den Ether auslösen kann und Läden in der Nähe reagierte, angibt, ob es mussten.Das ist was ich mit Windows Azure – AppFabric Service Bus einrichten, wie dargestellt in Abbildung 1.

An Inventory-Check Message
Abbildung 1 eine Bestandsprüfung Nachricht

Themen einen dauerhaften Mechanismus, der lässt mich um bis zu 2.000 Teilnehmer pro Thema Content heraus schieben.Zwingt Sie, dass Abonnenten Einschränkung bedauerlich, wie sie potenziell eine Lösungsarchitektur (wie ich werde beschreiben) zum Umgehen von irgendwie Segmente im Thema erstellen.Statt nach einem USLager Thema überprüfen, die Abonnenten nach Region filtern, hätte ich eine US South Central erstellenBestandsaufnahme Thema überprüfen, und klicken Sie dann auf die spezifischen lokalen Zweig weiter filtern.Mit diesem Vorbehalt werde ich meine einzelnes Inventar überprüfen Thema fort, wie kann ich Versprechen, dass ich in meinem Wunderland nicht mehr als eine Handvoll der Franchise-Speicherorte haben werden.

 

 

Beim Abrufen der Nachricht aus

Können Sie die Windows Azure – AppFabric CTP Juni-Update vom bit.ly/p3DhAU, und suchen Sie das Management-Portal unter portal.appfabriclabs.com.Ich werde das Management-Portal zu wenige Informationen abzurufen, ich in meinem Code verwenden, müssen, zugreifen (siehe Abbildung 2).

Getting Information from the Windows Azure AppFabric Management Portal
Abbildung 2 Abrufen von Informationen aus dem Windows Azure – AppFabric Management-Portal

Service-Gateway, der Emittent Standard (immer "Owner" in der CTP-Version) und der Standard-Schlüssel ergreifen müssen.Da ich diese in meinem Beispiel benötigen, werde ich ihnen im Gültigkeitsbereich des Objekts erstellen:

private string sbNamespace = "jofultz";
private string issuerName = "owner";
private string issuerKey = "25vtsCkUPBtB39RdiBbUtCQglYRPOdHHC4MvX5fvxxxx";

Ich verwende diese Variablen in Funktionen im Thema erstellen und dann zum Thema Nachrichten senden. Es gibt eine REST-Schnittstelle für diejenigen, die sie verwenden möchten oder Wer sind nicht auf einer Plattform, die Verwendung der Clientbibliothek gestattet bereitstellen. Da ich einen Windows-Client erstellen, wird die Bibliothek verwendet. Dazu muss ich Verweise auf die Microsoft.ServiceBus, Microsoft.ServiceBus.Message und System.ServiceModel, hinzufügen wie in gezeigt Abbildung 3.

Adding References
Abbildung 3 Hinzufügen von verweisen

Sobald dies geschehen ist, sind einfache ein paar Zeilen Code alle, die erforderlich ist, um das Thema einrichten zu erhalten:

SharedSecretCredential credential =
  TransportClientCredentialBase.CreateSharedSecretCredential(
  issuerName, issuerKey);
 
Uri sbUri = ServiceBusEnvironment.CreateServiceUri(
  "sb", sbNamespace, String.Empty);
ServiceBusNamespaceClient sbNSClient =
  new ServiceBusNamespaceClient(sbUri, credential);
Topic newTopic = sbNSClient.CreateTopic(topicName);

Was wird wichtig, da draußen Auslösen von Nachrichten werden zunächst ist die Fähigkeit der Speicher Nachrichten filtern und nur diejenigen, die an den empfangenden Speicherort basierend auf Region relevant sind. Die API unterstützt, Korrelation und Abonnement-IDs als vorrangigen, aber für die Filterung ich mein wissen über die Daten und Filter basierend auf den Inhalt der Anforderung verwenden möchten. Daher möchte ich geografisch schließen speichert zu suchen und des jeweils anderen Anforderungen für den Bestand auf der Grundlage von Region zu reagieren. Zur gleichen Zeit muss ich sicherstellen, dass seine eigenen Anforderungen der ursprüngliche Informationsspeicher abholen nicht. Anforderungen umfassen die SKU des fraglichen Artikels, der Region, in der die Anfrage gestellt wird, und die RequesterID der ursprüngliche Informationsspeicher seine eigenen Anforderungen zum Thema herausfiltern kann:

[Serializable]
class InventoryQueryData
{
  public string Region;
  public string ResponderID;
  public string RequesterID;
  public string Sku;
  public int Count;
}

Beachten Sie das Attribut [Serializable], das ich zur Klasse hinzugefügt haben. Sie könnte und markieren Sie die Eigenschaften als DataMembers DataContract als auch verwenden, aber der Punkt ist, dass gleich welcher Art, die ich zum Thema senden möchten serialisierbar sein muss.

Ich habe ein einfaches Formular erstellt, mit dem ich geben eine beliebige Zeichenfolge für die SKU, und wählen aus einer Liste für den Informationsspeicher buchen. Der Code hinter der Schaltfläche meine Abfrage ähnelt der Code eine Verbindung herstellen, und erstellen Sie das Thema und ähnelt der typische Konstrukte Sie finden bei der Arbeit mit messaging-APIs, wie in gezeigt Abbildung 4.

Abbildung 4 Abrufen der Daten

// Assign data values.
InventoryQueryData data = new InventoryQueryData();
data.Sku = txtSKU.Text;
data.StoreID = cboStore.SelectedText;
data.Region = cboStore.SelectedValue.ToString();
 
Uri sbUri = ServiceBusEnvironment.CreateServiceUri("sb", sbNamespace, string.Empty);
SharedSecretCredential credential = TransportClientCredentialBase.CreateSharedSecretCredential(issuerName, issuerKey);
 
MessagingFactory msgFactory = MessagingFactory.Create(sbUri, credential);
TopicClient topicClient = msgFactory.CreateTopicClient(topicName);
MessageSender MsgSender = topicClient.CreateSender();
 
BrokeredMessage msg = BrokeredMessage.CreateMessage(data);
// Add props to message for filtering.
msg.Properties["Region"] = data.Region;
msg.Properties["RequesterID"] = data.RequesterID;
 
msg.TimeToLive = TimeSpan.FromSeconds(60);
 
MsgSender.Send(data);

Es gibt zwei Dinge zu beachten. Zuerst habe ich die Name-Wert-Paare hinzugefügt zum Filtern der Auflistung BrokeredMessage.Properties benötigten. Zweitens als eine Angelegenheit von Common Language Runtime-Wartung, habe ich TimeToLive (TTL) einen Wert von 60 Sekunden gegeben die Abonnements zu diesem Thema sollten aus abrufen zu gesichert. Natürlich, Sie sollten im Allgemeinen einen fundiertere Ansatz für die Kommissionierung der TTL-Wert, aber ich herausfinden, wenn die Anforderung keinen Abonnenten in dieser Zeit nicht erreicht, es ist wahrscheinlich zu lang, weil es ein Kunde ist warten dort stehen. Außerdem ist dies nur ein Beispiel.

Jede Nachricht, die an den Bus gesendet wird, wird in Form einer BrokeredMessage, die eine Factorymethode CreateMessage hat. Dies schließt einfach die Daten in eine Instanz eines Typs, die alle für eine voll funktionsfähige Messagingsystem benötigten Konstrukte enthält BrokeredMessage.

Mit diesem ich alle, die ich haben, brauche um eine Nachricht an die Abonnenten das Lager Thema Überprüfen heraus, so jetzt fange ich das Einrichten der Abonnementclients zum Abrufen von Nachrichten und Antworten.

Durch Tippen auf den Thema Stream und reagieren

Mit meinem Client im Ort ich bin bereit, einen stetigen Strom von Anfragen zu senden, aber Recht dies jetzt werden kaum mehr als Vermietung Bits lose in the wild Ether. Erstellen Sie eine Windows Form-Anwendung, und der Liste der XML-Speicher und die InventoryQueryData in der ersten (Absender) Anwendung wiederverwenden. I müssen, erstellen Sie ein Abonnement eindeutig für jeden Client, der mit dem Thema abhört. Dies geschieht einfach genug durch die Kombination von Namens eines Abonnements mit der Lagernummer überwacht werden soll. Meine kleinen Test app erlaubt mir die Lagernummer aus einem Kombinationsfeld auswählen, so dass ich diesen Wert auf den Basisnamen Abonnement nur landen, um den eindeutigen Namen des Abonnements erstellen. Es ist wichtig, um sicherzustellen, dass jeder Client ein eindeutiger Abonnement hat; gewinnen würden zwei oder mehr mit gleichen Abonnements eine Racebedingung erstellen würden, würde die Abonnenten konkurrieren, für die Meldung und die erste zu empfangen und zu löschen:

Topic invTopic = sbNSClient.GetTopic(topicName);
SubscriptionName = "InventoryQuerySubscription" + this.cboStore.Text;
SqlFilterExpression RegionFilter = new SqlFilterExpression("Region = '" +
  cboStore.SelectedValue + "' AND RequesterID <> '" + cboStore.Text + "'");
 
Subscription sub = invTopic.AddSubscription(SubscriptionName, RegionFilter);

Nach dem Hinzufügen von Abonnements zu dem Thema kann ich auch in einem Filter übergeben, so dass jedes Geschäft nur Lager Kontrollkästchen für die Anträge der eigenen Region erhält. Beachten Sie, dass Sie können Ihren eigenen FilterExpression-Typ vom Basistyp entwickeln, aber die API vier Typen, die in den meisten Szenarios abdecken soll, umfasst vor allem, wenn gemeinsam verwendet: CorrelationFilterExpression, MatchAllFilterExpression, MatchNoneFilterExpression und SqlFilterExpression. Ich verwendete SqlFilterExpression, die mir erlaubt, einfach und instinktiv Schreiben dieses Ausdrucks auf die Nachrichten für die Region Texas, z. B. get und Ausschließen von Nachrichten, die aus meiner eigenen Speicher stammen:

"Region = '[Region]' AND RequesterID <> '[StoreID]'"

Ich möchte nur die Anfragen durch Filtern, aber in einigen Fällen ich könnte theoretisch "Reparieren" einige Daten auf dem Weg mit einem RuleDescription um zu sagen, ein SqlFilterExpression mit einem SqlFilterAction zu kombinieren. Erstere identifiziert Nachrichten, die ich bin targeting während letztere die Aktion definiert, die ergriffen werden sollten. Diese Art von Funktionalität kann nützlich sein, wenn die Dateneinträge in etwas massiert werden muss, die für den Empfänger und beide Seiten des Busses funktioniert nicht möglich oder nicht geändert werden.

Nachdem das Abonnement festgelegt ist bis es bleiben auch nach der Client wird geschlossen. Dies ist ideal für dieses Szenario. Ich werde einfach einen SubscriptionClient erstellen, jedes Mal, wenn ich starten Sie die Überwachung, und es wird die bestehende Verbindung zuordnen. Nicht jeder möchten jedoch dieses Verhalten. Ich kann Situationen vorstellen, soll das Abonnement zu entfernen, wenn der Client heruntergefahren wird:

SubscriptionClient subClient = msgFactory.CreateSubscriptionClient(
  topicName, SubscriptionName);
MessageReceiver msgReceiver = subClient.CreateReceiver(ReceiveMode.ReceiveAndDelete);
msgReceiver.Open();

Beachten Sie im Aufruf von CreateReceiver, dass ich ReceiveMode auf ReceiveAndDelete festgelegt haben. Sie könnten auch PeekLock für die ReceiveMode verwenden. Hier möchte ich einfach die Nachricht und den Prozess, und ich keine Notwendigkeit haben, den richtigen Eingang zu gewährleisten, und die Verarbeitung vor deren Löschung, denn wenn die Nachricht verloren geht, ist es eine große Sache nicht greifen. Wenn ich Verhalten, die garantierte und zuverlässigere war benötigt, würde ich wahrscheinlich zwei Dinge tun. Ich würde nicht den TTL-Wert für die Nachricht, Thema oder Abonnement festgelegt und lassen Sie stattdessen die Nachrichten auf unbestimmte Zeit live. Oder würde ich Geben sie eine sehr hohe TTL, so dass der Empfänger hatte genügend Zeit zu verarbeiten oder zu einer Ausnahmewarteschlange verschieben, sodass nur wirklich nicht zustellbare Nachrichten in der Warteschlange für unzustellbare enden würde. Darüber hinaus würde ich PeekLock auf dem Empfänger zum Lesen und Verarbeiten der Daten und entfernen nur die Nachricht nach dem Abschluss des zugehörigen Prozesses verwenden. Manuelle Erstellung dieses Verhalten für die verteilte Transaktion kann schnell zu anderen Problemen, wie nicht verarbeitbare Warteschlangen führen, aber wir werden dieses Verhalten zu beheben und Problem einer anderen Zeit eingestellt.

Wenn ich den Empfänger geöffnet haben, den ich eine Schleife, um nach Nachrichten suchen eingeben. Die API hat eine direkte Receive-Methode, die die BrokeredMessage zurückgibt. Allerdings werde ich die TryReceive-Methode, die zurückgeben einen Bool um Erfolg anzuzeigen verwenden (siehe Abbildung 5). Ich werde einen relativ kurzen Timeout an diese Methode übergeben, die sollte lange genug, um zu überprüfen und die Meldung. Wenn eine Nachricht empfangen wird, werde ich arbeiten und sofort eine weitere Nachricht überprüfen. Wenn keine Nachricht empfangen wird, ich den Thread für ein wenig schlafen und überprüfen Sie erneut.

Abbildung 5 Nachrichten prüfen

while (MonitorOn)
{
  BrokeredMessage NewMsg;
  bool recvSuccess = msgReceiver.TryReceive(TimeSpan.FromSeconds(3), out NewMsg);
 
  if (recvSuccess)
  {
    this.lbMessages.Items.Add(NewMsg.MessageId);
    InventoryQueryData RequestObject =
      NewMsg.GetBody<CreateInquiry.InventoryQueryData>();
    ProcessMessage(RequestObject);
  }
  else
  {
    System.Threading.Thread.Sleep(3000);
  }
}

Meine Request-Objekt in der BrokeredMessage enthalten ist und Abrufen dieser rufe ich GetBody <T>, Übergabe des Objekttyps. Hier die Implikation ist, dass Objekttypen auf beiden Seiten des Busses übereinstimmen müssen. Sie erreichen dies Proxytypen verwenden oder bei der Ungewissheit oder plain old XML über kommen konnte des Objekts als Zeichenfolge übergeben und als XML zu behandeln.

Bis zum nächsten Mal …

Zu diesem Zeitpunkt erfolgt die Arbeit die Nachricht erstellen und es allen interessierten Knoten und für sie zum Abrufen der Nachricht aus dem Thema zu erhalten. Ich habe Features gezeigt, die lassen Sie mich nicht nur die Meldung gesendet, sondern auch filtern, entsprechend für den abonnierten Receiver. Nächsten Monat werde ich über die Rückreise demonstrieren die komplementäre Nutzung der Warteschlangen und Korrelation bis zum Ende des Szenarios und runden Sie Ihr Grundlegendes Verständnis der neuen Funktionen in der Windows Azure – AppFabric Service Bus arbeiten. Ich habe auch den vollständigen Code für Sie zum download zur Verfügung.

Joseph Fultz ist Softwarearchitekt bei Hewlett-Packard, arbeiten als Teil der Packard Global IT-Gruppe.  Zuvor war er ein Software-Architekt für Microsoft und arbeitet mit Top-Tier-Unternehmen und ISV-Kunden definieren Architektur und Entwerfen von Lösungen.

Dank der folgenden technischen Experten für die Überprüfung dieses Artikels: Jim Keane