Protokollguide för AMQP 1.0 i Azure Service Bus och Event Hubs

Advanced Message Queueing Protocol 1.0 är ett standardiserat inramnings- och överföringsprotokoll för asynkront, säkert och tillförlitligt överföring av meddelanden mellan två parter. Det är det primära protokollet för Azure Service Bus Messaging och Azure Event Hubs.

AMQP 1.0 är resultatet av ett brett branschsamarbete som sammanförde mellanprogramsleverantörer, till exempel Microsoft och Red Hat, med många mellanprogramsanvändare för meddelanden som JP Morgan Chase som representerar branschen för finansiella tjänster. Det tekniska standardiseringsforumet för AMQP-protokollet och tilläggsspecifikationerna är OASIS, och det har uppnått formellt godkännande som internationell standard som ISO/IEC 19494:2014.

Mål

Den här artikeln sammanfattar huvudbegreppen i AMQP 1.0-meddelandespecifikationen tillsammans med tilläggsspecifikationer som utvecklats av OASIS AMQP Technical Committee och förklarar hur Azure Service Bus implementerar och bygger vidare på dessa specifikationer.

Målet är att alla utvecklare som använder en befintlig AMQP 1.0-klientstack på valfri plattform ska kunna interagera med Azure Service Bus via AMQP 1.0.

Vanliga AMQP 1.0-stackar för generell användning, till exempel Apache Qpid Proton eller AMQP.NET Lite, implementerar alla kärn-AMQP 1.0-protokollelement som sessioner eller länkar. Dessa grundläggande element omsluts ibland med ett API på högre nivå. Apache Proton erbjuder till och med två, det imperativa Messenger-API:et och det reaktiva reaktor-API:et.

I följande diskussion antar vi att hanteringen av AMQP-anslutningar, sessioner och länkar samt hanteringen av ramöverföringar och flödeskontroll hanteras av respektive stack (till exempel Apache Proton-C) och inte kräver mycket om någon specifik uppmärksamhet från programutvecklare. Vi förutsätter abstrakt att det finns några API-primitiver som möjligheten att ansluta, och att skapa någon form av avsändare och mottagarabstraktionsobjekt, som sedan har någon form av send() respektive receive() åtgärder.

När du diskuterar avancerade funktioner i Azure Service Bus, till exempel meddelandebläddring eller hantering av sessioner, förklaras dessa funktioner i AMQP-termer, men också som en pseudoimplementering på flera lager utöver den här antagna API-abstraktionen.

Vad är AMQP?

AMQP är ett inramnings- och överföringsprotokoll. Inramning innebär att den tillhandahåller struktur för binära dataströmmar som flödar i båda riktningarna för en nätverksanslutning. Strukturen ger en avgränsning för distinkta datablock, så kallade ramar, som ska utbytas mellan de anslutna parterna. Överföringsfunktionerna säkerställer att båda de kommunicerande parterna kan skapa en gemensam förståelse för när ramar ska överföras och när överföringar ska anses vara fullständiga.

Till skillnad från tidigare utgångna utkastversioner från AMQP-arbetsgruppen som fortfarande används av några meddelandeköer, föreskriver arbetsgruppens slutgiltiga och standardiserade AMQP 1.0-protokoll inte förekomsten av en meddelandekö eller någon särskild topologi för entiteter i en meddelandekö.

Protokollet kan användas för symmetrisk peer-to-peer-kommunikation, för interaktion med meddelandeköer som stöder köer och publicera/prenumerera entiteter, som Azure Service Bus gör. Den kan också användas för interaktion med meddelandeinfrastruktur där interaktionsmönstren skiljer sig från vanliga köer, vilket är fallet med Azure Event Hubs. En händelsehubb fungerar som en kö när händelser skickas till den, men fungerar mer som en seriell lagringstjänst när händelser läss från den. det liknar en bandenhet. Klienten väljer en förskjutning i den tillgängliga dataströmmen och hanteras sedan alla händelser från den förskjutningen till den senaste tillgängliga.

AMQP 1.0-protokollet är utformat för att vara utökningsbart, vilket möjliggör ytterligare specifikationer för att förbättra dess funktioner. De tre tilläggsspecifikationer som beskrivs i det här dokumentet illustrerar detta. För kommunikation via befintlig HTTPS/WebSockets-infrastruktur kan det vara svårt att konfigurera de inbyggda AMQP TCP-portarna. En bindningsspecifikation definierar hur du lagrar AMQP över WebSockets. För att interagera med meddelandeinfrastrukturen i hanteringssyfte eller för att tillhandahålla avancerade funktioner definierar AMQP-hanteringsspecifikationen de grundläggande interaktionsprimiterna som krävs. För integrering av federerad auktoriseringsmodell definierar AMQP-anspråksbaserad säkerhetsspecifikation hur du associerar och förnyar auktoriseringstoken som är associerade med länkar.

Grundläggande AMQP-scenarier

I det här avsnittet beskrivs den grundläggande användningen av AMQP 1.0 med Azure Service Bus, som omfattar att skapa anslutningar, sessioner och länkar och överföra meddelanden till och från Service Bus-entiteter som köer, ämnen och prenumerationer.

Den mest auktoritativa källan för att lära sig om hur AMQP fungerar är AMQP 1.0-specifikationen, men specifikationen skrevs för att exakt vägleda implementeringen och inte lära ut protokollet. Det här avsnittet fokuserar på att introducera så mycket terminologi som behövs för att beskriva hur Service Bus använder AMQP 1.0. För en mer omfattande introduktion till AMQP, samt en bredare diskussion om AMQP 1.0, kan du läsa den här videokursen.

Anslut och sessioner

AMQP anropar containrar för kommunikationsprogram, de innehåller noder, som är de kommunicerande entiteterna i dessa containrar. En kö kan vara en sådan nod. AMQP möjliggör multiplexering, så en enda anslutning kan användas för många kommunikationsvägar mellan noder. Till exempel kan en programklient samtidigt ta emot från en kö och skicka till en annan kö via samma nätverksanslutning.

Diagram showing Sessions and Connections between containers.

Nätverksanslutningen är därför förankrad i containern. Den initieras av containern i klientrollen som gör en utgående TCP-socketanslutning till en container i mottagarrollen, som lyssnar efter och accepterar inkommande TCP-anslutningar. I handskakningen för anslutningen ingår att förhandla om protokollversionen, deklarera eller förhandla om användning av TLS/SSL (Transport Level Security) och en handskakning för autentisering/auktorisering i anslutningsomfånget som baseras på SASL.

Azure Service Bus eller Azure Event Hubs kräver att TLS används hela tiden. Den stöder anslutningar via TCP-port 5671, där TCP-anslutningen först läggs över med TLS innan du går in i AMQP-protokollets handskakning och även stöder anslutningar via TCP-port 5672 där servern omedelbart erbjuder en obligatorisk uppgradering av anslutningen till TLS med hjälp av den AMQP-föreskrivna modellen. AMQP WebSockets-bindningen skapar en tunnel över TCP-port 443 som sedan motsvarar AMQP 5671-anslutningar.

När du har konfigurerat anslutningen och TLS erbjuder Service Bus två SASL-mekanismalternativ:

  • SASL PLAIN används ofta för att skicka autentiseringsuppgifter för användarnamn och lösenord till en server. Service Bus har inte konton, men har namnet Säkerhetsregler för delad åtkomst, som ger rättigheter och är associerade med en nyckel. Namnet på en regel används som användarnamn och nyckel (som base64-kodad text) används som lösenord. De rättigheter som är associerade med den valda regeln styr de åtgärder som tillåts för anslutningen.
  • SASL ANONYMOUS används för att kringgå SASL-auktorisering när klienten vill använda cbs-modellen (claims-based-security) som beskrivs senare. Med det här alternativet kan en klientanslutning upprättas anonymt under en kort tid under vilken klienten bara kan interagera med CBS-slutpunkten och CBS-handskakningen måste slutföras.

När transportanslutningen har upprättats deklarerar containrarna var och en den maximala ramstorlek som de är villiga att hantera, och efter en tidsgräns för inaktivitet kopplas de ensidigt från om det inte finns någon aktivitet på anslutningen.

De deklarerar också hur många samtidiga kanaler som stöds. En kanal är en enkelriktad, utgående virtuell överföringssökväg ovanpå anslutningen. En session tar en kanal från var och en av de sammankopplade containrarna för att bilda en dubbelriktad kommunikationssökväg.

Sessioner har en fönsterbaserad flödeskontrollmodell. När en session skapas deklarerar varje part hur många ramar den är villig att acceptera i sitt mottagningsfönster. När parterna byter ramar fyller överförda ramar fönstret och överföringarna stoppas när fönstret är fullt och tills fönstret återställs eller expanderas med hjälp av flödet performativt (performativt är AMQP-termen för gester på protokollnivå som utbyts mellan de två parterna).

Den här fönsterbaserade modellen motsvarar ungefär TCP-begreppet för fönsterbaserad flödeskontroll, men på sessionsnivå i socketen. Protokollets koncept att tillåta flera samtidiga sessioner finns så att högprioriterad trafik kan rusas förbi begränsad normal trafik, som på en motorväg express lane.

Azure Service Bus använder för närvarande exakt en session för varje anslutning. Den maximala ramstorleken för Service Bus är 262 144 byte (256 K byte) för Service Bus Standard. Det är 1048576 (100 MB) för Service Bus Premium och Event Hubs. Service Bus tillämpar inte några specifika fönster på sessionsnivå, men återställer fönstret regelbundet som en del av flödeskontrollen på länknivå (se nästa avsnitt).

Anslut ioner, kanaler och sessioner är tillfälliga. Om den underliggande anslutningen kollapsar måste anslutningar, TLS-tunnel, SASL-auktoriseringskontext och sessioner återupprättas.

Utgående AMQP-portkrav

Klienter som använder AMQP-anslutningar via TCP kräver att portarna 5671 och 5672 öppnas i den lokala brandväggen. Tillsammans med dessa portar kan det vara nödvändigt att öppna ytterligare portar om funktionen EnableLinkRedirect är aktiverad. EnableLinkRedirect är en ny meddelandefunktion som hjälper till att hoppa över ett hopp när du tar emot meddelanden, vilket hjälper till att öka dataflödet. Klienten skulle börja kommunicera direkt med serverdelstjänsten över portintervall 104XX enligt följande bild.

List of destination ports

En .NET-klient skulle misslyckas med en SocketException ("Ett försök gjordes att komma åt en socket på ett sätt som är förbjudet för dess åtkomstbehörigheter") om dessa portar blockeras av brandväggen. Funktionen kan inaktiveras genom att ange EnableAmqpLinkRedirect=false i anslutningssträng, vilket tvingar klienterna att kommunicera med fjärrtjänsten via port 5671.

AMQP WebSocket-bindningen tillhandahåller en mekanism för att tunneltrafikera en AMQP-anslutning via en WebSocket-transport. Den här bindningen skapar en tunnel över TCP-port 443, vilket motsvarar AMQP 5671-anslutningar. Använd AMQP WebSockets om du är bakom en brandvägg som blockerar TCP-anslutningar via portarna 5671, 5672 men tillåter TCP-anslutningar via port 443 (https).

AMQP överför meddelanden via länkar. En länk är en kommunikationssökväg som skapats under en session som gör det möjligt att överföra meddelanden i en riktning. överföringsstatusförhandlingen är över länken och dubbelriktad mellan de anslutna parterna.

Screenshot showing a Session carrying a link connection between two containers.

Länkar kan skapas av antingen containern när som helst och under en befintlig session, vilket gör AMQP annorlunda än många andra protokoll, inklusive HTTP och MQTT, där initiering av överföringar och överföringssökväg är en exklusiv behörighet för den part som skapar socketanslutningen.

Den länkinitierande containern ber den motsatta containern att acceptera en länk och väljer en roll som antingen avsändare eller mottagare. Därför kan antingen containern initiera skapandet av enkelriktade eller dubbelriktade kommunikationsvägar, med den senare modellerad som länkpar.

Länkar namnges och associeras med noder. Som anges i början är noder de kommunicerande entiteterna i en container.

I Service Bus motsvarar en nod direkt en kö, ett ämne, en prenumeration eller en deadletter-underfråga för en kö eller prenumeration. Nodnamnet som används i AMQP är därför det relativa namnet på entiteten i Service Bus-namnområdet. Om en kö heter myqueueär det också dess AMQP-nodnamn. En ämnesprenumeration följer HTTP API-konventionen genom att sorteras i en resurssamling för "prenumerationer" och därför har en prenumerationsunder i ett ämne mytopic AMQP-nodnamnet mytopic/subscriptions/sub.

Den anslutande klienten måste också använda ett lokalt nodnamn för att skapa länkar. Service Bus är inte normativt för dessa nodnamn och tolkar dem inte. AMQP 1.0-klientstackar använder vanligtvis ett schema för att säkerställa att dessa tillfälliga nodnamn är unika i klientens omfång.

Överföringar

När en länk har upprättats kan meddelanden överföras via den länken. I AMQP utförs en överföring med en explicit protokollgest (överföringens performativa) som flyttar ett meddelande från avsändaren till mottagaren via en länk. En överföring är klar när den är "avgjord", vilket innebär att båda parter har upprättat en gemensam förståelse för resultatet av överföringen.

A diagram showing a message's transfer between the Sender and Receiver and disposition that results from it.

I det enklaste fallet kan avsändaren välja att skicka meddelanden "i förväg avgjorda", vilket innebär att klienten inte är intresserad av resultatet och mottagaren inte ger någon feedback om resultatet av åtgärden. Det här läget stöds av Service Bus på AMQP-protokollnivå, men visas inte i någon av klient-API:erna.

Det vanliga fallet är att meddelanden skickas oreglerade, och mottagaren anger sedan godkännande eller avvisande med hjälp av borttagningen performativ. Avvisande inträffar när mottagaren inte kan acceptera meddelandet av någon anledning och avvisningsmeddelandet innehåller information om orsaken, vilket är en felstruktur som definierats av AMQP. Om meddelanden avvisas på grund av interna fel i Service Bus returnerar tjänsten extra information i den strukturen som kan användas för att tillhandahålla diagnostiktips för att stödja personal om du skickar supportbegäranden. Du får mer information om fel senare.

En särskild form av avvisande är frisläppt tillstånd, vilket anger att mottagaren inte har några tekniska invändningar mot överföringen, men inte heller något intresse av att reglera överföringen. Det fallet finns till exempel när ett meddelande levereras till en Service Bus-klient och klienten väljer att "överge" meddelandet eftersom det inte kan utföra det arbete som följer av bearbetningen av meddelandet. själva meddelandeleveransen är inte fel. En variant av det tillståndet är det ändrade tillståndet, vilket tillåter ändringar i meddelandet när det släpps. Det tillståndet används för närvarande inte av Service Bus.

AMQP 1.0-specifikationen definierar ett ytterligare borttagningstillstånd som kallas mottaget, som specifikt hjälper till att hantera länkåterställning. Länkåterställning gör det möjligt att återskapa tillståndet för en länk och eventuella väntande leveranser ovanpå en ny anslutning och session, när den tidigare anslutningen och sessionen förlorades.

Service Bus stöder inte länkåterställning. Om klienten förlorar anslutningen till Service Bus med en väntande oreglerad meddelandeöverföring går meddelandeöverföringen förlorad och klienten måste återansluta, återupprätta länken och försöka överföra igen.

Därför stöder Service Bus och Event Hubs överföring "minst en gång" där avsändaren kan vara säker på att meddelandet har lagrats och accepterats, men inte stöder "exakt en gång"-överföringar på AMQP-nivå, där systemet skulle försöka återställa länken och fortsätta att förhandla om leveranstillståndet för att undvika duplicering av meddelandeöverföringen.

För att kompensera för möjliga duplicerade sändningar har Service Bus stöd för dubblettidentifiering som en valfri funktion i köer och ämnen. Dubblettidentifiering registrerar meddelande-ID:t för alla inkommande meddelanden under ett användardefinierat tidsfönster och släpper sedan tyst alla meddelanden som skickas med samma meddelande-ID under samma fönster.

Flödeskontroll

Förutom den flödeskontrollmodell på sessionsnivå som tidigare diskuterats har varje länk en egen flödeskontrollmodell. Flödeskontroll på sessionsnivå skyddar containern från att behöva hantera för många bildrutor samtidigt. Flödeskontrollen på länknivå gör att programmet ansvarar för hur många meddelanden den vill hantera från en länk och när.

Screenshot of a log showing Source, Destination, Source Port, Destination Port, and Protocol Name. In the first row the Destination Port 10401 (0x28 A 1) is outlined in black.

På en länk kan överföringar bara ske när avsändaren har tillräckligt med länkkredit. Länkkredit är en räknare som anges av mottagaren med hjälp av flödets performativa, som är begränsad till en länk. När avsändaren tilldelas länkkredit försöker den använda krediten genom att leverera meddelanden. Varje meddelandeleverans minskar den återstående länkkrediten med 1. När länkkrediten är förbrukad stoppas leveranserna.

När Service Bus är i mottagarrollen ger det omedelbart avsändaren gott om länkkredit, så att meddelanden kan skickas omedelbart. När länkkredit används skickar Service Bus ibland ett flöde som fungerar till avsändaren för att uppdatera länkkreditsaldot.

I avsändarrollen skickar Service Bus meddelanden för att använda en utestående länkkredit.

Ett "ta emot"-anrop på API-nivå översätts till ett flöde som skickas till Service Bus av klienten, och Service Bus använder den krediten genom att ta det första tillgängliga, olåsta meddelandet från kön, låsa den och överföra den. Om det inte finns något meddelande som är lättillgängligt för leverans förblir eventuell utestående kredit från en länk som upprättats med den specifika entiteten registrerad i ankomstordning och meddelanden låses och överförs när de blir tillgängliga för att använda utestående kredit.

Låset på ett meddelande släpps när överföringen regleras till något av de terminaltillstånd som accepteras, avvisas eller släpps. Meddelandet tas bort från Service Bus när terminaltillståndet godkänns. Den finns kvar i Service Bus och levereras till nästa mottagare när överföringen når något av de andra tillstånden. Service Bus flyttar automatiskt meddelandet till entitetens deadletter-kö när det når det maximala leveransantal som tillåts för entiteten på grund av upprepade avslag eller versioner.

Även om Service Bus-API:erna inte exponerar ett sådant alternativ direkt i dag kan en AMQP-protokollklient på lägre nivå använda länkkreditmodellen för att omvandla "pull-style"-interaktionen att utfärda en kreditenhet för varje mottagande begäran till en "push-style"-modell genom att utfärda ett stort antal länkkrediter och sedan ta emot meddelanden när de blir tillgängliga utan ytterligare interaktion. Push stöds via egenskapsinställningarna ServiceBusProcessor.PrefetchCount eller ServiceBusReceiver.PrefetchCount . När de inte är noll använder AMQP-klienten den som länkkredit.

I det här sammanhanget är det viktigt att förstå att klockan för förfallodatumet för låset på meddelandet i entiteten startar när meddelandet tas från entiteten, inte när meddelandet sätts på tråden. När klienten anger beredskap att ta emot meddelanden genom att utfärda länkkredit förväntas den därför aktivt hämta meddelanden över nätverket och vara redo att hantera dem. Annars kan meddelandelåset ha upphört att gälla innan meddelandet ens levereras. Användningen av länkkreditflödeskontroll bör direkt återspegla den omedelbara beredskapen att hantera tillgängliga meddelanden som skickas till mottagaren.

Sammanfattningsvis ger följande avsnitt en schematisk översikt över det performativa flödet under olika API-interaktioner. Varje avsnitt beskriver en annan logisk åtgärd. Vissa av dessa interaktioner kan vara "lata", vilket innebär att de kanske bara utförs när det behövs. Att skapa en meddelandesändare kanske inte orsakar en nätverksinteraktion förrän det första meddelandet skickas eller begärs.

Pilarna i följande tabell visar den performativa flödesriktningen.

Skapa meddelandemottagare

Klient Service Bus
--> attach(<br/>name={link name},<br/>handle={numeric handle},<br/>role=**receiver**,<br/>source={entity name},<br/>target={client link ID}<br/>) Klienten ansluter till entiteten som mottagare
Service Bus-svar kopplar slutet av länken <-- attach(<br/>name={link name},<br/>handle={numeric handle},<br/>role=**sender**,<br/>source={entity name},<br/>target={client link ID}<br/>)

Skapa meddelandesändare

Klient Service Bus
--> attach(<br/>name={link name},<br/>handle={numeric handle},<br/>role=**sender**,<br/>source={client link ID},<br/>target={entity name}<br/>) Ingen åtgärd
Ingen åtgärd <-- attach(<br/>name={link name},<br/>handle={numeric handle},<br/>role=**receiver**,<br/>source={client link ID},<br/>target={entity name}<br/>)

Skapa meddelandesändare (fel)

Klient Service Bus
--> attach(<br/>name={link name},<br/>handle={numeric handle},<br/>role=**sender**,<br/>source={client link ID},<br/>target={entity name}<br/>) Ingen åtgärd
Ingen åtgärd <-- attach(<br/>name={link name},<br/>handle={numeric handle},<br/>role=**receiver**,<br/>source=null,<br/>target=null<br/>)<br/><br/><-- detach(<br/>handle={numeric handle},<br/>closed=**true**,<br/>error={error info}<br/>)

Stäng meddelandemottagare/avsändare

Klient Service Bus
--> detach(<br/>handle={numeric handle},<br/>closed=**true**<br/>) Ingen åtgärd
Ingen åtgärd <-- detach(<br/>handle={numeric handle},<br/>closed=**true**<br/>)

Skicka (lyckades)

Klient Service Bus
--> transfer(<br/>delivery-id={numeric handle},<br/>delivery-tag={binary handle},<br/>settled=**false**,,more=**false**,<br/>state=**null**,<br/>resume=**false**<br/>) Ingen åtgärd
Ingen åtgärd <-- disposition(<br/>role=receiver,<br/>first={delivery ID},<br/>last={delivery ID},<br/>settled=**true**,<br/>state=**accepted**<br/>)

Skicka (fel)

Klient Service Bus
--> transfer(<br/>delivery-id={numeric handle},<br/>delivery-tag={binary handle},<br/>settled=**false**,,more=**false**,<br/>state=**null**,<br/>resume=**false**<br/>) Ingen åtgärd
Ingen åtgärd <-- disposition(<br/>role=receiver,<br/>first={delivery ID},<br/>last={delivery ID},<br/>settled=**true**,<br/>state=**rejected**(<br/>error={error info}<br/>)<br/>)

Ta emot

Klient Service Bus
--> flow(<br/>link-credit=1<br/>) Ingen åtgärd
Ingen åtgärd < transfer(<br/>delivery-id={numeric handle},<br/>delivery-tag={binary handle},<br/>settled=**false**,<br/>more=**false**,<br/>state=**null**,<br/>resume=**false**<br/>)
--> disposition(<br/>role=**receiver**,<br/>first={delivery ID},<br/>last={delivery ID},<br/>settled=**true**,<br/>state=**accepted**<br/>) Ingen åtgärd

Ta emot flera meddelanden

Klient Service Bus
--> flow(<br/>link-credit=3<br/>) Ingen åtgärd
Ingen åtgärd < transfer(<br/>delivery-id={numeric handle},<br/>delivery-tag={binary handle},<br/>settled=**false**,<br/>more=**false**,<br/>state=**null**,<br/>resume=**false**<br/>)
Ingen åtgärd < transfer(<br/>delivery-id={numeric handle+1},<br/>delivery-tag={binary handle},<br/>settled=**false**,<br/>more=**false**,<br/>state=**null**,<br/>resume=**false**<br/>)
Ingen åtgärd < transfer(<br/>delivery-id={numeric handle+2},<br/>delivery-tag={binary handle},<br/>settled=**false**,<br/>more=**false**,<br/>state=**null**,<br/>resume=**false**<br/>)
--> disposition(<br/>role=receiver,<br/>first={delivery ID},<br/>last={delivery ID+2},<br/>settled=**true**,<br/>state=**accepted**<br/>) Ingen åtgärd

Meddelanden

I följande avsnitt förklaras vilka egenskaper från standardavsnitten för AMQP-meddelanden som används av Service Bus och hur de mappas till Service Bus API-uppsättningen.

Alla egenskaper som programmet behöver definiera ska mappas till AMQP:s application-properties karta.

Fältnamn Användning API-namn
Hållbara - -
prioritet - -
ttl Time to live för det här meddelandet TimeToLive
first-acquirer - -
leveransantal - DeliveryCount

egenskaper

Fältnamn Användning API-namn
message-id Programdefinierad, friformulärsidentifierare för det här meddelandet. Används för dubblettidentifiering. Messageid
användar-ID Programdefinierad användaridentifierare, inte tolkad av Service Bus. Inte tillgänglig via Service Bus-API:et.
Programdefinierad målidentifierare, inte tolkad av Service Bus. Om du vill
certifikatmottagare Programdefinierad identifierare för meddelandesyfte, inte tolkad av Service Bus. Ämne
svara på Programdefinierad svarssökvägsindikator, inte tolkad av Service Bus. ReplyTo
korrelations-ID Programdefinierad korrelationsidentifierare, inte tolkad av Service Bus. CorrelationId
innehållstyp Programdefinierad innehållstypsindikator för brödtexten, inte tolkad av Service Bus. Contenttype
content-encoding Programdefinierad innehållskodningsindikator för brödtexten, inte tolkad av Service Bus. Inte tillgänglig via Service Bus-API:et.
absolut förfallotid Deklarerar vid vilket absolut ögonblick meddelandet upphör att gälla. Ignoreras vid indata (rubrik-TTL observeras), auktoritativt för utdata. Inte tillgänglig via Service Bus-API:et.
creation-time Deklarerar när meddelandet skapades. Används inte av Service Bus Inte tillgänglig via Service Bus-API:et.
grupp-ID Programdefinierad identifierare för en relaterad uppsättning meddelanden. Används för Service Bus-sessioner. Sessionid
gruppsekvens Räknaren identifierar meddelandets relativa sekvensnummer i en session. Ignoreras av Service Bus. Inte tillgänglig via Service Bus-API:et.
reply-to-group-id - ReplyToSessionId

Meddelandeanteckningar

Det finns få andra egenskaper för Service Bus-meddelanden, som inte ingår i AMQP-meddelandeegenskaper, och som skickas som MessageAnnotations i meddelandet.

Kartnyckel för anteckning Användning API-namn
x-opt-scheduled-enqueue-time Deklarerar vid vilken tidpunkt meddelandet ska visas på entiteten ScheduledEnqueueTime
x-opt-partition-key Programdefinierad nyckel som avgör vilken partition meddelandet ska landa i. PartitionKey
x-opt-via-partition-key Programdefinierat partitionsnyckelvärde när en transaktion ska användas för att skicka meddelanden via en överföringskö. TransactionPartitionKey
x-opt-enqueued-time Tjänstdefinierad UTC-tid som representerar den faktiska tiden för att ange meddelandet. Ignoreras vid indata. EnqueuedTime
x-opt-sequence-number Tjänstdefinierat unikt nummer som tilldelats ett meddelande. SequenceNumber
x-opt-offset Tjänstdefinierat kodat sekvensnummer för meddelandet. EnqueuedSequenceNumber
x-opt-locked-until Tjänstdefinierad. Datum och tid till vilken meddelandet kommer att låsas i kön/prenumerationen. LockedUntil
x-opt-deadletter-source Tjänstdefinierad. Om meddelandet tas emot från kön med obeställbara meddelanden representerar det källan till det ursprungliga meddelandet. DeadLetterSource

Transaktionsfunktion

En transaktion grupperar två eller flera åtgärder tillsammans i en körning. En sådan transaktion måste till sin natur se till att alla åtgärder som hör till en viss åtgärdsgrupp antingen lyckas eller misslyckas gemensamt. Åtgärderna grupperas efter en identifierare txn-id.

För transaktionell interaktion fungerar klienten som en transaction controller , som styr de åtgärder som ska grupperas tillsammans. Service Bus Service fungerar som en transactional resource och utför arbete enligt begäran av transaction controller.

Klienten och tjänsten kommunicerar via en control link , som upprättas av klienten. Meddelandena declare och discharge skickas av kontrollanten via kontrolllänken för att allokera respektive slutföra transaktioner (de representerar inte avgränsningen av transaktionsarbete). Den faktiska sändningen/mottagningen utförs inte på den här länken. Varje transaktionsåtgärd som begärs identifieras uttryckligen med önskat txn-id och kan därför inträffa på valfri länk i Anslut ionen. Om kontrolllänken stängs när det finns icke-slutförda transaktioner som den skapade, återställs alla sådana transaktioner omedelbart och försök att utföra ytterligare transaktionsarbete på dem leder till fel. Meddelanden på kontrolllänken får inte vara i förväg avgjorda.

Varje anslutning måste initiera en egen kontrolllänk för att kunna starta och avsluta transaktioner. Tjänsten definierar ett särskilt mål som fungerar som en coordinator. Klienten/kontrollanten upprättar en kontrolllänk till det här målet. Kontrolllänken ligger utanför gränsen för en entitet, d.v.s. samma kontrolllänk kan användas för att initiera och utföra transaktioner för flera entiteter.

Starta en transaktion

Så här påbörjar du transaktionsarbete. kontrollanten måste erhålla en txn-id från koordinatorn. Det gör den genom att skicka ett declare typmeddelande. Om deklarationen lyckas svarar koordinatorn med ett borttagningsresultat som bär den tilldelade txn-id.

Klient (kontrollant) Riktning Service Bus (koordinator)
attach(
name={link name},
... ,
role=sender,
target=Coordinator
)
------>
<------ attach(
name={link name},
... ,
target=Coordinator()
)
transfer(
delivery-id=0, ...)
{ AmqpValue (Declare())}
------>
<------ disposition(
first=0, last=0,
state=Declared(
txn-id={transaktions-ID}
))

Avläsa en transaktion

Kontrollanten avslutar transaktionsarbetet genom att skicka ett discharge meddelande till koordinatorn. Kontrollanten anger att den vill checka in eller återställa transaktionsarbetet genom att ange fail flaggan på urladdningstexten. Om koordinatorn inte kan slutföra urladdningen avvisas meddelandet med det här resultatet med transaction-error.

Obs! fail=true refererar till Återställning av en transaktion och fail=false refererar till Commit.

Klient (kontrollant) Riktning Service Bus (koordinator)
transfer(
delivery-id=0, ...)
{ AmqpValue (Declare())}
------>
<------ disposition(
first=0, last=0,
state=Declared(
txn-id={transaktions-ID}
))
. . .
Transaktionsarbete
på andra länkar
. . .
transfer(
delivery-id=57, ...)
{ AmqpValue (
Urladdning(txn-id=0,
fail=false))
}
------>
<------ disposition(
first=57, last=57,
state=Accepted())

Skicka ett meddelande i en transaktion

Allt transaktionsarbete utförs med transaktionsleveranstillståndet transactional-state som bär txn-id. När meddelanden skickas överförs transaktionstillståndet av meddelandets överföringsram.

Klient (kontrollant) Riktning Service Bus (koordinator)
transfer(
delivery-id=0, ...)
{ AmqpValue (Declare())}
------>
<------ disposition(
first=0, last=0,
state=Declared(
txn-id={transaktions-ID}
))
transfer(
handle=1,
delivery-id=1,
state=
TransactionalState(
txn-id=0)
)
{ nyttolast }
------>
<------ disposition(
first=1, last=1,
state=TransactionalState(
txn-id=0,
outcome=Accepted())
)

Ta bort ett meddelande i en transaktion

Meddelandeborttagning innehåller åtgärder som CompleteDefer / / Abandon / DeadLetter. Om du vill utföra dessa åtgärder i en transaktion skickar du transactional-state med borttagningen.

Klient (kontrollant) Riktning Service Bus (koordinator)
transfer(
delivery-id=0, ...)
{ AmqpValue (Declare())}
------>
<------ disposition(
first=0, last=0,
state=Declared(
txn-id={transaktions-ID}
))
<------ transfer(
handle=2,
delivery-id=11,
state=null)
{ nyttolast }
disposition(
first=11, last=11,
state=TransactionalState(
txn-id=0,
outcome=Accepted())
)
------>

Avancerade Service Bus-funktioner

Det här avsnittet beskriver avancerade funktioner i Azure Service Bus som baseras på utkast till tillägg till AMQP, som för närvarande utvecklas i OASIS Technical Committee for AMQP. Service Bus implementerar de senaste versionerna av dessa utkast och antar ändringar som introduceras när dessa utkast når standardstatus.

Kommentar

Avancerade åtgärder för Service Bus-meddelanden stöds via ett mönster för begäran/svar. Information om de här åtgärderna beskrivs i artikeln AMQP 1.0 i Service Bus: request-response-based operations (Begäranssvarsbaserade åtgärder).

AMQP-hantering

AMQP-hanteringsspecifikationen är den första av de utkasttillägg som beskrivs i den här artikeln. Den här specifikationen definierar en uppsättning protokoll som ligger ovanpå AMQP-protokollet och som möjliggör hanteringsinteraktioner med meddelandeinfrastrukturen via AMQP. Specifikationen definierar allmänna åtgärder som att skapa, läsa, uppdatera och ta bort för att hantera entiteter i en meddelandeinfrastruktur och en uppsättning frågeåtgärder.

Alla dessa gester kräver en interaktion mellan klienten och meddelandeinfrastrukturen, och därför definierar specifikationen hur interaktionsmönstret ska modelleras ovanpå AMQP: klienten ansluter till meddelandeinfrastrukturen, initierar en session och skapar sedan ett par länkar. På en länk fungerar klienten som avsändare och å andra sidan fungerar den som mottagare, vilket skapar ett par länkar som kan fungera som en dubbelriktad kanal.

Logisk åtgärd Klient Service Bus
Skapa sökväg för begärandesvar --> attach(<br/>name={*link name*},<br/>handle={*numeric handle*},<br/>role=**sender**,<br/>source=**null**,<br/>target=”myentity/$management”<br/>) Ingen åtgärd
Skapa sökväg för begärandesvar Ingen åtgärd \<-- attach(<br/>name={*link name*},<br/>handle={*numeric handle*},<br/>role=**receiver**,<br/>source=null,<br/>target=”myentity”<br/>)
Skapa sökväg för begärandesvar --> attach(<br/>name={*link name*},<br/>handle={*numeric handle*},<br/>role=**receiver**,<br/>source=”myentity/$management”,<br/>target=”myclient$id”<br/>)
Skapa sökväg för begärandesvar Ingen åtgärd \<-- attach(<br/>name={*link name*},<br/>handle={*numeric handle*},<br/>role=**sender**,<br/>source=”myentity”,<br/>target=”myclient$id”<br/>)

Med det paret länkar på plats är implementeringen av begäran/svar enkel: en begäran är ett meddelande som skickas till en entitet i meddelandeinfrastrukturen som förstår det här mönstret. I det begärandemeddelandet anges svarsfältet i egenskapsavsnittet till målidentifieraren för länken som svaret ska levereras till. Hanteringsentiteten bearbetar begäran och levererar sedan svaret via länken vars målidentifierare matchar den angivna svar-till-identifieraren .

Mönstret kräver naturligtvis att klientcontainern och den klientgenererade identifieraren för svarsmålet är unika för alla klienter och av säkerhetsskäl också svåra att förutsäga.

Meddelandet utbyter används för hanteringsprotokollet och för alla andra protokoll som använder samma mönster sker på programnivå. de definierar inte nya gester på AMQP-protokollnivå. Det är avsiktligt, så att program kan dra omedelbar nytta av dessa tillägg med kompatibla AMQP 1.0-staplar.

Service Bus implementerar för närvarande inte någon av huvudfunktionerna i hanteringsspecifikationen, men mönstret för begäran/svar som definieras av hanteringsspecifikationen är grundläggande för den anspråksbaserade säkerhetsfunktionen och för nästan alla avancerade funktioner som beskrivs i följande avsnitt:

Anspråksbaserad auktorisering

CBS-specifikationsutkastet (AMQP Claims-Based-Authorization) bygger på mönstret för begäran/svar för hanteringsspecifikation och beskriver en generaliserad modell för hur du använder federerade säkerhetstoken med AMQP.

Standardsäkerhetsmodellen för AMQP som beskrivs i introduktionen baseras på SASL och integreras med AMQP-anslutningshandskakningen. Att använda SASL har fördelen att det ger en utökningsbar modell för vilken en uppsättning mekanismer har definierats från vilka alla protokoll som formellt lutar sig mot SASL kan dra nytta av. Bland dessa mekanismer finns "PLAIN" för överföring av användarnamn och lösenord, "EXTERN" för att binda till säkerhet på TLS-nivå, "ANONYM" för att uttrycka frånvaron av explicit autentisering/auktorisering och en mängd olika ytterligare mekanismer som tillåter överföring av autentiserings- och/eller auktoriseringsautentiseringsuppgifter eller token.

AMQP:s SASL-integrering har två nackdelar:

  • Alla autentiseringsuppgifter och token är begränsade till anslutningen. En meddelandeinfrastruktur kanske vill tillhandahålla differentierad åtkomstkontroll per entitet. Till exempel att låta ägaren av en token skicka till kö A men inte köa B. Med auktoriseringskontexten fäst på anslutningen går det inte att använda en enda anslutning och ändå använda olika åtkomsttoken för kö A och kö B.
  • Åtkomsttoken är vanligtvis endast giltiga under en begränsad tid. Den här giltigheten kräver att användaren regelbundet hämtar token och ger tokenutfärdaren möjlighet att vägra utfärda en ny token om användarens åtkomstbehörigheter har ändrats. AMQP-anslutningar kan pågå under långa tidsperioder. SASL-modellen ger bara en chans att ange en token vid anslutningstiden, vilket innebär att meddelandeinfrastrukturen antingen måste koppla från klienten när token upphör att gälla eller att den måste acceptera risken för att tillåta fortsatt kommunikation med en klient som har åtkomsträttigheter kan ha återkallats under tiden.

AMQP CBS-specifikationen, som implementeras av Service Bus, möjliggör en elegant lösning för båda dessa problem: Det gör att en klient kan associera åtkomsttoken med varje nod och uppdatera dessa token innan de upphör att gälla, utan att avbryta meddelandeflödet.

CBS definierar en virtuell hanteringsnod med namnet $cbs som ska tillhandahållas av meddelandeinfrastrukturen. Hanteringsnoden accepterar token för andra noder i meddelandeinfrastrukturen.

Protokollgesten är ett utbyte av begäran/svar enligt definitionen i hanteringsspecifikationen. Det innebär att klienten upprättar ett par länkar med noden $cbs och skickar sedan en begäran på den utgående länken och väntar sedan på svaret på den inkommande länken.

Begärandemeddelandet har följande programegenskaper:

Key Valfri Värdetyp Värdeinnehåll
operation Inga sträng put-token
type Inga sträng Typen av token som sätts in.
name Inga sträng Den "målgrupp" som token gäller för.
expiration Ja timestamp Förfallotiden för token.

Namnegenskapen identifierar den entitet som token ska associeras med. I Service Bus är det sökvägen till kön, eller ämne/prenumeration. Typegenskapen identifierar tokentypen:

Tokentyp Tokenbeskrivning Brödtexttyp OBS!
jwt JSON-webbtoken (JWT) AMQP-värde (sträng)
servicebus.windows.net:sastoken Service Bus SAS-token AMQP-värde (sträng) -

Behörigheter för tokenkonferens. Service Bus känner till tre grundläggande rättigheter: "Skicka" gör det möjligt att skicka, "Lyssna" aktiverar mottagning och "Hantera" möjliggör manipulering av entiteter. Service Bus SAS-token refererar till regler som konfigurerats på namnområdet eller entiteten, och dessa regler har konfigurerats med rättigheter. Genom att signera token med nyckeln som är associerad med den regeln uttrycks därmed respektive behörighet för token. Den token som är associerad med en entitet med put-token tillåter att den anslutna klienten interagerar med entiteten enligt tokenrättigheterna. En länk där klienten tar på sig avsändarrollen kräver rättigheten "Skicka". Om du tar på dig mottagarrollen krävs rättigheten "Lyssna".

Svarsmeddelandet har följande värden för programegenskaper

Key Valfri Värdetyp Värdeinnehåll
status-code Inga heltal HTTP-svarskod [RFC2616].
status-description Ja sträng Beskrivning av statusen.

Klienten kan anropa put-token upprepade gånger och för valfri entitet i meddelandeinfrastrukturen. Token är begränsade till den aktuella klienten och förankrade i den aktuella anslutningen, vilket innebär att servern släpper alla kvarhållna token när anslutningen avbryts.

Den aktuella Service Bus-implementeringen tillåter endast CBS tillsammans med SASL-metoden "ANONYMOUS". En SSL/TLS-anslutning måste alltid finnas före SASL-handskakningen.

Anonym-mekanismen måste därför stödjas av den valda AMQP 1.0-klienten. Anonym åtkomst innebär att den första handskakningen för anslutningen, inklusive skapandet av den första sessionen, sker utan att Service Bus vet vem som skapar anslutningen.

När anslutningen och sessionen har upprättats är det bara de tillåtna åtgärderna att koppla länkarna till den $cbs noden och skicka put-token-begäran . En giltig token måste anges med hjälp av en put-token-begäran för en viss entitetsnod inom 20 sekunder efter att anslutningen har upprättats, annars tas anslutningen ensidigt bort av Service Bus.

Klienten ansvarar därefter för att hålla reda på att token upphör att gälla. När en token upphör att gälla släpper Service Bus omedelbart alla länkar på anslutningen till respektive entitet. För att förhindra att problem uppstår kan klienten ersätta token för noden med en ny när som helst via den virtuella $cbs hanteringsnoden med samma put-token-gest och utan att komma i vägen för nyttolasttrafiken som flödar på olika länkar.

Funktionen Skicka via

Send-via/Transfer Sender är en funktion som gör att Service Bus kan vidarebefordra ett visst meddelande till en målentitet via en annan entitet. Den här funktionen används för att utföra åtgärder mellan entiteter i en enda transaktion.

Med den här funktionen skapar du en avsändare och upprättar länken till via-entity. När länken upprättas skickas ytterligare information för att fastställa det sanna målet för meddelandena/överföringarna på den här länken. När anslutningsåtgärden har lyckats vidarebefordras alla meddelanden som skickas på den här länken automatiskt till målentiteten via entiteten.

Obs! Autentisering måste utföras för både via entitet och målentitet innan den här länken upprättas.

Klient Riktning Service Bus
attach(<br/>name={link name},<br/>role=sender,<br/>source={client link ID},<br/>target=**{via-entity}**,<br/>**properties=map [(<br/>com.microsoft:transfer-destination-address=<br/>{destination-entity} )]** ) ------>
<------ attach(<br/>name={link name},<br/>role=receiver,<br/>source={client link ID},<br/>target={via-entity},<br/>properties=map [(<br/>com.microsoft:transfer-destination-address=<br/>{destination-entity} )] )

Nästa steg

Mer information om AMQP finns i Översikt över Service Bus AMQP.