Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
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 väljer 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 (eller fält). Bestäm egenskaperna för värdena för dessa fält. Tänk på följande frågor.
- Vilken är den mest effektiva datatypen?
- Har nyttolasten alltid specifika fält?
- Har nyttolasten en enda post eller en upprepad uppsättning värden?
Välj sedan ett kodningsformat beroende på dina behov. Specifika faktorer inkluderar möjligheten att skapa mycket strukturerade data om du behöver det, den tid det tar att koda och överföra meddelandet och möjligheten att parsa nyttolasten. Välj sedan ett kodningsformat som uppfyller dina behov.
Konsumenten måste förstå dessa beslut för att kunna läsa inkommande meddelanden korrekt.
För att överföra meddelanden serialiserar producenten meddelandet till ett kodningsformat. I den mottagande änden deserialiserar konsumenten datapaketet för att få åtkomst till informationen. Den här processen säkerställer att båda entiteterna delar samma modell. Så länge formen förblir oförändrad fortsätter meddelandena 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. Dessa format skapar dock ofta större meddelanden. Andra format kanske inte parsar data lika enkelt, men de resulterar i mer kompakta meddelanden. Den här artikeln beskriver viktiga faktorer som hjälper dig att välja rätt format.
Överväganden för kodningsformat
Kodningsformatet definierar hur en uppsättning strukturerade data representeras som byte. Typen av meddelande kan påverka valet av format. Meddelanden som rör affärstransaktioner innehåller troligen mycket strukturerade data. Du kanske också vill hämta strukturerade data 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.
Tänk på följande faktorer 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, så att en person kan inspektera den utan att använda kodbibliotek. Den här metoden gör data lättare att läsa och förstå. Format som kan läsas av 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 att felsöka fel.
Nackdelen med textbaserad kodning är att nyttolasten tenderar att vara större. Nyttolaststorleken kan ofta minskas genom en minifieringsprocess, så länge den kan vändas för mänsklig läsbarhet när det behövs. Vanliga textbaserade format är JSON och YAML.
Kryptering
Om det finns känsliga data i meddelandena bör du överväga om dessa meddelanden ska krypteras i sin helhet. Om endast specifika fält behöver krypteras och du föredrar att minska molnkostnaderna kan du också överväga att använda ett bibliotek som NServiceBus.
Kodningsstorlek
Meddelandestorleken påverkar nätverkets in- och utdataprestanda i kabeln. Binära format är mer kompakta än textbaserade format. Binära format kräver serialisering och deserialiseringsbibliotek. Nyttolasten kan bara läsas när den 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 senare i Alternativ för kodningsformat.
Nackdelen med binärt format ä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ör icke-binära format tar en minifieringsprocess bort onödiga blanksteg och tecken samtidigt som kompatibiliteten med formatets specifikation bevaras. Den här metoden hjälper till att minska kodningsstorleken utan att ändra strukturen. Utvärdera funktionerna i kodaren för att göra minifieringen till standard. Till exempel JsonSerializerOptions.WriteIndented från . NET:s System.Text.Json.JsonSerializer styr automatisk minifiering när du skapar JSON-text.
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. De två huvudsakliga metoderna för att lagra och distribuera metadata är:
Taggade metadata. I vissa kodningsformat, 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 producenten delar. 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.
Schemat. 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 eller valfria fält, versionsinformation och nyttolastens struktur. Producenten skickar nyttolasten enligt skrivarschemat. Konsumenten tar emot nyttolasten genom att använda ett läsarschema. Meddelandet serialiseras och deserialiseras med hjälp av kodningsspecifika bibliotek. Scheman kan distribueras på två sätt:
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 och 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 är i ett schemaregister. Meddelandet innehåller en referens till schemat och nyttolasten. Producenten skickar schemaidentifieraren i meddelandet. Konsumenten hämtar schemat genom att ange identifikatorn från ett externt lager. Båda parter använder ett formatspecifikt bibliotek för att läsa och skriva meddelanden. Förutom att lagra schemat kan ett register tillhandahålla kompatibilitetskontroller för att säkerställa att kontraktet mellan producenten och konsumenten inte bryts när schemat utvecklas.
Innan du väljer en metod bör du bestämma om överföringsdatastorleken eller möjligheten att parsa arkiverade data senare är viktigare.
Lagring av schemat tillsammans med nyttolasten ger en större kodningsstorlek och är perfekt för tillfälliga meddelanden. Välj den här metoden om överföring av mindre bitar data är avgörande eller om du förväntar dig en följd av poster. Kostnaden för att underhålla ett externt schemaarkiv kan vara hög.
Men om avkodning av nyttolasten på begäran är viktigare än storleken, garanterar inkluderingen av schemat med nyttolasten eller den taggade metadata-metoden avkodning därefter. Det kan finnas en betydande ökning av meddelandestorleken som påverkar kostnaden för lagring.
Versionshantering för schema
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. Versionshantering har två viktiga aspekter:
Konsumenten bör spåra och förstå ä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 deras logik brytas om de inte kan ignorera avsaknaden av det nya fältet. Tänk nu på det motsatta scenariot. Om ett fält tas bort i det nya schemat kanske konsumenter som använder det gamla schemat 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
Fundera på om data i nyttolasten är strukturerade som en sekvens med poster eller som en enda diskret 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 fleradimensionella matriser. Poster har unika nyckel/värde-par. Modellen kan utökas för att representera komplexa strukturer. Några exempel är JSON, Apache Avro och MessagePack.
Den här layouten är lämplig om meddelanden kodas individuellt med olika scheman. Om du har flera poster kan datainnehållet bli alltför redundant. Den här redundansen kan göra att nyttolasten blir uppsvälld.
Tabelldata: Informationen är indelad 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.
Comma-Separated Values (CSV) är ett av de enklaste textbaserade formaten. Den presenterar data som en sekvens av dataposter med en gemensam rubrik. För binär kodning har Apache Avro en ingress som liknar en CSV-rubrik men som genererar en mer kompakt kodningsstorlek.
Biblioteksstöd
Du bör använda välkända format i stället för en egenutvecklad modell. Välkända format stöds via bibliotek som communityn stöder universellt. 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 ett schemabaserat format väljer du ett kodningsbibliotek som gör kompatibilitetskontroller mellan läsaren och skrivarschemat. Specifika 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 din arbetsbelastning använder Stream Analytics är det klokt att välja något av dessa format.
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. Standardiserade format är vanligtvis mer kompatibla än anpassade format. I textbaserade alternativ är JSON en av de mest driftskompatibla.
Alternativ för kodningsformat
Följande populära kodningsformat används för datarepresentation och överföring. Ta hänsyn till övervägandena innan du väljer ett format.
JSON
JSON är en öppen standard med sitt format definierat av IETF (Internet Engineering Task Force) i RFC 8259. JSON ä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 att ange valfria fält, vilket hjälper till med både framåt- och bakåtkompatibilitet.
Den största fördelen är att den är universellt tillgänglig. JSON är det mest kompatibla kodningsformatet och standard för många meddelandetjänster.
Eftersom JSON är ett textbaserat format är det inte effektivt över kabeln och inte idealiskt när lagring är ett problem. Använd minifieringstekniker när det är möjligt. 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). BSON är en binär kodning som är justerad för att fungera med MongoDB.
CSV
CSV är ett textbaserat tabellformat. Rubriken i tabellen anger fälten. CSV passar bra för meddelanden som innehåller en uppsättning poster.
Nackdelen med CSV är bristen på standardisering. Det finns flera sätt att uttrycka avgränsare, rubriker och tomma fält.
Protokollbuffertar
Protocol Buffers (eller protobuf) är ett serialiseringsformat som använder starkt skrivna 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 liten, komprimerad binär nyttolast, vilket resulterar i snabbare dataöverföring. Nackdelen är att nyttolasten inte är läsbar för människor. Eftersom schemat lagras externt är det här formatet inte idealiskt för scenarier som kräver att du hämtar arkiverade data.
Apache Avro
Apache Avro är ett binärt serialiseringsformat som använder en definitionsfil som liknar protobuf, men utan ett kompileringssteg. I stället innehåller serialiserade data alltid en schemaingress.
Ingressen kan innehålla rubriken eller en schemaidentifierare. På grund av dess mindre kodningsstorlek rekommenderas Avro för strömmande data. Eftersom den har en rubrik som gäller för en uppsättning poster passar den också bra för tabelldata.
Apache Parquet
Apache Parquet är ett kolumnformat för lagringsfiler som vanligtvis associeras med Apache Hadoop och relaterade ramverk för databearbetning.
Apache Parquet stöder datakomprimering och har begränsade funktioner för schemautveckling. Det här formatet används vanligtvis när andra stordatatekniker i din arbetsbelastning kräver det för att skapa eller använda data.
MessagePack
MessagePack är ett binärt serialiseringsformat som är utformat för att vara kompakt för överföring över kabeln. MessagePack saknar schemadefinition och typkontroll. Det här formatet rekommenderas inte för masslagring.
CBOR
CBOR (Specification) är ett binärt format som ger en liten kodningsstorlek. Fördelen med att använda CBOR över MessagePack är dess kompatibilitet med IETF i RFC7049.