Dela via


Överväganden vid meddelandekodning

Många molnprogram använder asynkrona meddelanden för att utbyta information mellan komponenter i systemet. En viktig aspekt av meddelanden är det format som används för att koda nyttolastdata. När du har valt en meddelandeteknik är nästa steg att definiera hur meddelandena ska kodas. Det finns många tillgängliga alternativ, men rätt val beror på ditt användningsfall.

I den här artikeln beskrivs några av övervägandena.

Behov av meddelandeutbyte

Ett meddelandeutbyte mellan en producent och en konsument behöver:

  • En form eller struktur som definierar nyttolasten för meddelandet.
  • Ett kodningsformat som representerar nyttolasten.
  • Serialiseringsbibliotek för att läsa och skriva den kodade nyttolasten.

Meddelandeproducenten definierar meddelandeformen baserat på affärslogik och den information som den vill skicka till konsumenterna. Om du vill strukturera formen delar du upp informationen i diskreta eller relaterade ämnen (fält). Bestäm egenskaperna för värdena för dessa fält. Tänk på: Vilken är den mest effektiva datatypen? Kommer nyttolasten alltid att ha vissa fält? Kommer nyttolasten att ha en enda post eller en upprepad uppsättning värden?

Välj sedan ett kodningsformat beroende på dina behov. Vissa faktorer inkluderar möjligheten att skapa mycket strukturerade data om du behöver det, tid det tar att koda och överföra meddelandet och möjligheten att parsa nyttolasten. Beroende på kodningsformatet väljer du ett serialiseringsbibliotek som stöds.

En konsument av meddelandet måste vara medveten om dessa beslut så att den vet hur inkommande meddelanden ska läsas.

För att överföra meddelanden serialiserar producenten meddelandet till ett kodningsformat. I den mottagande änden deserialiserar konsumenten nyttolasten för att använda data. På så sätt delar båda entiteterna modellen och så länge formen inte ändras fortsätter meddelanden utan problem. När avtalet ändras bör kodningsformatet kunna hantera ändringen utan att konsumenten påverkas.

Vissa kodningsformat, till exempel JSON, är självbeskrivande, vilket innebär att de kan parsas utan att referera till ett schema. Sådana format tenderar dock att ge större meddelanden. Med andra format kanske data inte parsas lika enkelt, men meddelandena är kompakta. Den här artikeln beskriver några faktorer som kan hjälpa dig att välja ett format.

Överväganden för kodningsformat

Kodningsformatet definierar hur en uppsättning strukturerade data representeras som byte. Typen av meddelande kan påverka formatvalet. Meddelanden som är relaterade till affärstransaktioner innehåller troligen mycket strukturerade data. Du kanske också vill hämta den senare i granskningssyfte. För en händelseström kanske du vill läsa en sekvens med poster så snabbt som möjligt och lagra den för statistisk analys.

Här följer några saker att tänka på när du väljer ett kodningsformat.

Läsbarhet för människor

Meddelandekodning kan delas upp i textbaserade och binära format.

Med textbaserad kodning är meddelandenyttolasten i oformaterad text och kan därför inspekteras av en person utan att använda några kodbibliotek. Läsbara format för människor är lämpliga för arkiveringsdata. Eftersom en människa kan läsa nyttolasten är textbaserade format enklare att felsöka och skicka till loggar för felsökningsfel.

Nackdelen är att nyttolasten tenderar att vara större. Ett vanligt textbaserat format är JSON.

Kryptering

Om det finns känsliga data i meddelandena bör du överväga om dessa meddelanden ska krypteras i sin helhet enligt beskrivningen i den här vägledningen om kryptering av Azure Service Bus-data i vila. Om endast vissa fält behöver krypteras och du föredrar att minska molnkostnaderna kan du också överväga att använda ett bibliotek som NServiceBus för det.

Kodningsstorlek

Meddelandestorleken påverkar nätverkets I/O-prestanda över kabeln. Binära format är mer kompakta än textbaserade format. Binära format kräver serialiserings-/deserialiseringsbibliotek. Nyttolasten kan inte läsas om den inte avkodas.

Använd ett binärt format om du vill minska bankavtrycket och överföra meddelanden snabbare. Den här formatkategorin rekommenderas i scenarier där lagrings- eller nätverksbandbredd är ett problem. Alternativen för binära format är Apache Avro, Google Protocol Buffers (protobuf), MessagePack och Concise Binary Object Representation (CBOR). För- och nackdelarna med dessa format beskrivs i det här avsnittet.

Nackdelen är att nyttolasten inte är läsbar för människor. De flesta binära format använder komplexa system som kan vara kostsamma att underhålla. Dessutom behöver de specialiserade bibliotek för att avkoda, vilket kanske inte stöds om du vill hämta arkiveringsdata.

Förstå nyttolasten

En meddelandenyttolast tas emot som en sekvens med byte. För att parsa den här sekvensen måste konsumenten ha åtkomst till metadata som beskriver datafälten i nyttolasten. Det finns två huvudsakliga metoder för att lagra och distribuera metadata:

Taggade metadata. I vissa kodningar, särskilt JSON, taggas fält med datatypen och identifieraren i meddelandets brödtext. Dessa format är självbeskrivande eftersom de kan parsas i en ordlista med värden utan att referera till ett schema. Ett sätt för konsumenten att förstå fälten är att fråga efter förväntade värden. Producenten skickar till exempel en nyttolast i JSON. Konsumenten parsar JSON i en ordlista och kontrollerar förekomsten av fält för att förstå nyttolasten. Ett annat sätt är att konsumenten tillämpar en datamodell som delas av producenten. Om du till exempel använder ett statiskt skrivet språk kan många JSON-serialiseringsbibliotek parsa en JSON-sträng i en typinskriven klass.

Schema. Ett schema definierar formellt strukturen och datafälten i ett meddelande. I den här modellen har producenten och konsumenten ett kontrakt via ett väldefinierat schema. Schemat kan definiera datatyper, obligatoriska/valfria fält, versionsinformation och nyttolastens struktur. Producenten skickar nyttolasten enligt skrivschemat. Konsumenten tar emot nyttolasten genom att använda ett läsarschema. Meddelandet serialiseras/deserialiseras med hjälp av kodningsspecifika bibliotek. Det finns två sätt att distribuera scheman:

  • Lagra schemat som en ingress eller rubrik i meddelandet men separat från nyttolasten.

  • Lagra schemat externt.

Vissa kodningsformat definierar schemat och använder verktyg som genererar klasser från schemat. Producenten och konsumenten använder dessa klasser och bibliotek för att serialisera och deserialisera nyttolasten. Biblioteken tillhandahåller också kompatibilitetskontroller mellan skrivar- och läsarschemat. Både protobuf och Apache Avro följer den metoden. Den viktigaste skillnaden är att protobuf har en språkoberoende schemadefinition, men Avro använder kompakt JSON. En annan skillnad är hur båda formaten ger kompatibilitetskontroller mellan läsar- och skrivarscheman.

Ett annat sätt att lagra schemat externt i ett schemaregister. Meddelandet innehåller en referens till schemat och nyttolasten. Producenten skickar schemaidentifieraren i meddelandet och konsumenten hämtar schemat genom att ange identifieraren från ett externt arkiv. Båda parter använder formatspecifikt bibliotek för att läsa och skriva meddelanden. Förutom att lagra schemat kan ett register tillhandahålla kompatibilitetskontroller för att se till att kontraktet mellan producenten och konsumenten inte bryts när schemat utvecklas.

Innan du väljer en metod bör du bestämma vad som är viktigare: överföringsdatastorleken eller möjligheten att parsa arkiverade data senare.

Lagring av schemat tillsammans med nyttolasten ger en större kodningsstorlek och föredras för tillfälliga meddelanden. Välj den här metoden om överföring av mindre bitar av byte är avgörande eller om du förväntar dig en sekvens med poster. Kostnaden för att underhålla ett externt schemaarkiv kan vara hög.

Men om avkodning på begäran av nyttolasten är viktigare än storleken, garanterar även schemat med nyttolasten eller taggade metadata-metoden avkodning efteråt. Det kan finnas en betydande ökning av meddelandestorleken och kan påverka kostnaden för lagring.

Schemaversionshantering

När affärskraven ändras förväntas formen ändras och schemat utvecklas. Med versionshantering kan producenten ange schemauppdateringar som kan innehålla nya funktioner. Det finns två aspekter av versionshantering:

  • Konsumenten bör vara medveten om ändringarna.

    Ett sätt är att konsumenten kontrollerar alla fält för att avgöra om schemat har ändrats. Ett annat sätt är att producenten publicerar ett schemaversionsnummer med meddelandet. När schemat utvecklas ökar producenten versionen.

  • Ändringar får inte påverka eller bryta konsumenternas affärslogik.

    Anta att ett fält läggs till i ett befintligt schema. Om konsumenter som använder den nya versionen får en nyttolast enligt den gamla versionen kan logiken brytas om de inte kan förbise bristen på det nya fältet. Anta att ett fält tas bort i det nya schemat med tanke på det omvända fallet. Användare som använder det gamla schemat kanske inte kan läsa data.

    Kodningsformat som Avro ger möjlighet att definiera standardvärden. Om fältet läggs till med ett standardvärde i föregående exempel fylls det saknade fältet i med standardvärdet. Andra format som protobuf ger liknande funktioner via obligatoriska och valfria fält.

Nyttolaststruktur

Överväg hur data ordnas i nyttolasten. Är det en sekvens med poster eller en diskret enkel nyttolast? Nyttolaststrukturen kan kategoriseras i någon av följande modeller:

  • Matris/ordlista/värde: Definierar poster som innehåller värden i en eller flera dimensionella matriser. Poster har unika nyckel/värde-par. Det kan utökas för att representera de komplexa strukturerna. Några exempel är JSON, Apache Avro och MessagePack.

    Den här layouten är lämplig om meddelanden är individuellt kodade med olika scheman. Om du har flera poster kan nyttolasten bli alltför redundant, vilket gör att nyttolasten blir uppsvälld.

  • Tabelldata: Informationen är uppdelad i rader och kolumner. Varje kolumn anger ett fält eller ämnet för informationen och varje rad innehåller värden för dessa fält. Den här layouten är effektiv för en upprepad uppsättning information, till exempel tidsseriedata.

    CSV är ett av de enklaste textbaserade formaten. Den visar data som en sekvens med poster med ett gemensamt huvud. För binär kodning har Apache Avro en ingress som liknar en CSV-rubrik men genererar en kompakt kodningsstorlek.

Biblioteksstöd

Överväg att använda välkända format över en egen modell.

Välkända format stöds via bibliotek som stöds universellt av communityn. Med specialiserade format behöver du specifika bibliotek. Din affärslogik kan behöva kringgå några av de API-designval som tillhandahålls av biblioteken.

För schemabaserat format väljer du ett kodningsbibliotek som gör kompatibilitetskontroller mellan läsaren och skrivarschemat. Vissa kodningsbibliotek, till exempel Apache Avro, förväntar sig att konsumenten anger både skrivar- och läsarschemat innan meddelandet deserialiseras. Den här kontrollen säkerställer att användaren är medveten om schemaversionerna.

Samverkan

Ditt val av format kan bero på den specifika arbetsbelastningen eller det tekniska ekosystemet.

Till exempel:

  • Azure Stream Analytics har inbyggt stöd för JSON, CSV och Avro. När du använder Stream Analytics är det klokt att välja ett av dessa format om möjligt. Om inte kan du ange en anpassad deserialiserare, men detta lägger till ytterligare komplexitet i din lösning.

  • JSON är ett standardutbytesformat för HTTP REST-API:er. Om ditt program tar emot JSON-nyttolaster från klienter och sedan placerar dem i en meddelandekö för asynkron bearbetning kan det vara klokt att använda JSON för meddelanden i stället för att koda om till ett annat format.

Det här är bara två exempel på samverkansöverväganden. I allmänhet är standardiserade format mer kompatibla än anpassade format. I textbaserade alternativ är JSON en av de mest driftskompatibla.

Alternativ för kodningsformat

Här är några populära kodningsformat. Ta hänsyn till övervägandena innan du väljer ett format.

JSON

JSON är en öppen standard (IETF RFC8259). Det är ett textbaserat format som följer matrisen/ordlistan/värdemodellen.

JSON kan användas för att tagga metadata och du kan parsa nyttolasten utan schema. JSON stöder alternativet för att ange valfria fält, vilket hjälper till med framåt- och bakåtkompatibilitet.

Den största fördelen är att dess universellt tillgängliga. Det är mest driftskompatibelt och standardkodningsformatet för många meddelandetjänster.

Eftersom det är ett textbaserat format är det inte effektivt över kabeln och inte ett idealiskt val i fall där lagring är ett problem. Om du returnerar cachelagrade objekt direkt till en klient via HTTP kan lagring av JSON spara kostnaden för deserialisering från ett annat format och sedan serialisera till JSON.

Använd JSON för enstaka postmeddelanden eller för en sekvens med meddelanden där varje meddelande har ett annat schema. Undvik att använda JSON för en sekvens med poster, till exempel för tidsseriedata.

Det finns andra varianter av JSON, till exempel binär JSON (BSON), som är en binär kodning som är justerad för att fungera med MongoDB.

Kommaavgränsade värden (CSV)

CSV är ett textbaserat tabellformat. Rubriken i tabellen anger fälten. Det är ett föredraget val där meddelandet innehåller en uppsättning poster.

Nackdelen är brist på standardisering. Det finns många sätt att uttrycka avgränsare, rubriker och tomma fält.

Protokollbuffertar (protobuf)

Protokollbuffertar (eller protobuf) är ett serialiseringsformat som använder starkt typerade definitionsfiler för att definiera scheman i nyckel/värde-par. Dessa definitionsfiler kompileras sedan till språkspecifika klasser som används för serialisering och deserialisering av meddelanden.

Meddelandet innehåller en komprimerad binär liten nyttolast, vilket resulterar i snabbare överföring. Nackdelen är att nyttolasten inte är läsbar för människor. Eftersom schemat är externt rekommenderas det inte för fall där du måste hämta arkiverade data.

Apache Avro

Apache Avro är ett binärt serialiseringsformat som använder definitionsfil som liknar protobuf, men det finns inget kompileringssteg. I stället innehåller serialiserade data alltid en schemaingress.

Ingressen kan innehålla rubriken eller en schemaidentifierare. På grund av den mindre kodningsstorleken rekommenderas Avro för strömmande data. Eftersom den har en rubrik som gäller för en uppsättning poster är det också ett bra val för tabelldata.

MessagePack

MessagePack är ett binärt serialiseringsformat som är utformat för att vara kompakt för smidig överföring. Det finns inga meddelandescheman eller typkontroll för meddelanden. Det här formatet rekommenderas inte för masslagring.

CBOR

Koncis representation av binärt objekt (CBOR) (Specifikation) är ett binärt format som erbjuder liten kodningsstorlek. Fördelen med CBOR jämfört med MessagePack är att den är kompatibel med IETF i RFC7049.

Nästa steg