ทั้งหมดนี้มีการจัดลำดับไบนารีเฟรมเวิร์ก RPC และ IDL ฉันสนใจในความแตกต่างที่สำคัญระหว่างสิ่งเหล่านี้และลักษณะเฉพาะ (ประสิทธิภาพการใช้งานง่ายการรองรับภาษาโปรแกรม)
หากคุณรู้จักเทคโนโลยีอื่นที่คล้ายคลึงกันโปรดระบุคำตอบ
ทั้งหมดนี้มีการจัดลำดับไบนารีเฟรมเวิร์ก RPC และ IDL ฉันสนใจในความแตกต่างที่สำคัญระหว่างสิ่งเหล่านี้และลักษณะเฉพาะ (ประสิทธิภาพการใช้งานง่ายการรองรับภาษาโปรแกรม)
หากคุณรู้จักเทคโนโลยีอื่นที่คล้ายคลึงกันโปรดระบุคำตอบ
คำตอบ:
ASN.1เป็นมาตรฐาน ISO / ISE มีภาษาต้นฉบับที่อ่านได้ง่ายและ back-end ที่หลากหลายทั้งไบนารีและมนุษย์อ่านได้ เป็นมาตรฐานสากล (และเป็นภาษาเก่าในตอนนั้น!) ภาษาต้นทางค่อนข้างจมครัว (ในลักษณะเดียวกับที่มหาสมุทรแอตแลนติกเปียกเล็กน้อย) แต่มีการระบุไว้เป็นอย่างดีและมีการสนับสนุนที่เหมาะสม . (คุณอาจพบไลบรารี ASN.1 สำหรับภาษาใด ๆ ที่คุณตั้งชื่อถ้าคุณขุดยากพอและหากไม่มีไลบรารีภาษาซีที่ดีที่คุณสามารถใช้ใน FFI ได้) มันเป็นภาษามาตรฐานที่มีการจัดทำเอกสารและ มีแบบฝึกหัดดีๆให้ด้วย
ความมัธยัสถ์ไม่ใช่มาตรฐาน มีพื้นเพมาจาก Facebook และต่อมาเป็นโอเพ่นซอร์สและปัจจุบันเป็นโครงการระดับบนสุดของ Apache มันไม่ได้รับการบันทึกไว้อย่างดี - โดยเฉพาะระดับการสอน - และการมองอย่างรวดเร็ว (ยอมรับสั้น ๆ ) ของฉันดูเหมือนจะไม่เพิ่มสิ่งอื่นใดความพยายามก่อนหน้านี้ยังไม่ได้ทำ (และในบางกรณีก็ดีกว่า) เพื่อความเป็นธรรมมันมีภาษาจำนวนหนึ่งที่ค่อนข้างน่าประทับใจที่สนับสนุนนอกกรอบรวมถึงภาษาที่ไม่ใช่กระแสหลักที่มีรายละเอียดสูงกว่า IDL ยังคลุมเครือเหมือน C
โปรโตคอลบัฟเฟอร์ไม่ใช่มาตรฐาน เป็นผลิตภัณฑ์ของ Google ที่กำลังเผยแพร่สู่ชุมชนในวงกว้าง มีข้อ จำกัด เล็กน้อยในแง่ของภาษาที่รองรับนอกกรอบ (รองรับเฉพาะ C ++, Python และ Java) แต่มีการสนับสนุนจากบุคคลที่สามจำนวนมากสำหรับภาษาอื่น ๆ (ที่มีคุณภาพตัวแปรสูง) Google ทำงานเกือบทั้งหมดโดยใช้ Protocol Buffers ดังนั้นจึงเป็นโปรโตคอลที่ผ่านการทดสอบการต่อสู้และผ่านการทดสอบแล้ว (แม้ว่าจะไม่แข็งกร้าวในการต่อสู้เหมือน ASN.1 ก็ตามมีเอกสารประกอบที่ดีกว่า Thrift มาก แต่เป็น ผลิตภัณฑ์ของ Google มีแนวโน้มสูงที่จะไม่เสถียร (ในแง่ของการเปลี่ยนแปลงตลอดเวลาไม่ใช่ในแง่ของความไม่น่าเชื่อถือ) IDL ก็เหมือน C
ระบบทั้งหมดข้างต้นใช้สคีมาที่กำหนดไว้ใน IDL บางประเภทเพื่อสร้างรหัสสำหรับภาษาเป้าหมายที่ใช้ในการเข้ารหัสและถอดรหัส Avro ไม่ การพิมพ์ของ Avro เป็นแบบไดนามิกและข้อมูลสคีมาจะถูกใช้ที่รันไทม์โดยตรงทั้งในการเข้ารหัสและถอดรหัส (ซึ่งมีค่าใช้จ่ายที่ชัดเจนในการประมวลผล แต่ยังมีประโยชน์บางประการที่ชัดเจนในภาษาแบบไดนามิกและไม่จำเป็นต้องใช้ประเภทการติดแท็กเป็นต้น) . สคีมาใช้ JSON ซึ่งทำให้การสนับสนุน Avro ในภาษาใหม่ง่ายต่อการจัดการหากมีไลบรารี JSON อยู่แล้ว เช่นเดียวกับระบบคำอธิบายโปรโตคอลการสร้างล้อใหม่ส่วนใหญ่ Avro ก็ไม่ได้มาตรฐานเช่นกัน
โดยส่วนตัวแล้วแม้ว่าฉันจะมีความสัมพันธ์แบบรัก / เกลียด แต่ฉันก็อาจใช้ ASN.1 สำหรับ RPC ส่วนใหญ่และวัตถุประสงค์ในการส่งข้อความแม้ว่ามันจะไม่มีสแต็ค RPC (คุณต้องสร้างขึ้นมาใหม่ แต่ IOCs ก็ทำเช่นนั้น ง่ายพอ)
...
เครื่องหมายส่วนขยายหรือผ่านอัตโนมัติEXTENSIBILITY IMPLIED
ในส่วนหัวของโมดูล Protocol Buffers, IIRC รองรับการกำหนดเวอร์ชันด้วยตนเอง ฉันไม่รู้ว่ามันรองรับอะไรเช่นความสามารถในการขยายโดยนัย (และฉันขี้เกียจค้นหา) Thrift ยังรองรับการกำหนดเวอร์ชันบางอย่าง แต่ก็ทำให้ฉันประทับใจอีกครั้งในฐานะกระบวนการแบบแมนนวลโดยไม่มีความสามารถในการขยายโดยนัย
EXTENSIBILITY IMPLIED
ดังนั้นทุกข้อความโปรโตคอลบัฟเฟอร์มี
เราเพิ่งทำการศึกษาภายในเกี่ยวกับ serializers นี่คือผลลัพธ์บางส่วน (สำหรับการอ้างอิงในอนาคตของฉันด้วย!)
ความแตกต่างที่ใหญ่ที่สุดคือ Thrift ไม่ใช่แค่โปรโตคอลการทำให้เป็นอนุกรม แต่เป็นสแต็ก RPC แบบเต็มรูปแบบซึ่งเหมือนกับสแต็ก SOAP สมัยใหม่ ดังนั้นหลังจากการทำให้เป็นอนุกรมวัตถุสามารถ (แต่ไม่ได้รับคำสั่ง) ถูกส่งระหว่างเครื่องผ่าน TCP / IP ใน SOAP คุณเริ่มต้นด้วยเอกสาร WSDL ที่อธิบายบริการที่มีอยู่ทั้งหมด (วิธีการระยะไกล) และอาร์กิวเมนต์ / วัตถุที่คาดไว้ วัตถุเหล่านั้นถูกส่งผ่าน XML ใน Thrift ไฟล์. thrift จะอธิบายวิธีการที่มีอยู่อย่างครบถ้วนอ็อบเจ็กต์พารามิเตอร์ที่คาดหวังและอ็อบเจ็กต์จะถูกทำให้เป็นอนุกรมผ่านหนึ่งในซีเรียลไลเซอร์ที่มีอยู่ (ด้วยCompact Protocol
โปรโตคอลไบนารีที่มีประสิทธิภาพซึ่งเป็นที่นิยมมากที่สุดในการผลิต)
ASN.1 ได้รับการออกแบบโดย folks โทรคมนาคมในยุค 80 และเป็นที่น่าอึดอัดใจที่จะใช้เนื่องจากการ จำกัด การสนับสนุนห้องสมุดเมื่อเทียบกับ serializers ล่าสุดที่โผล่ออกมาจากคน compsci มีสองรูปแบบการเข้ารหัส DER (ไบนารี) และการเข้ารหัส PEM (ascii) ทั้งสองอย่างรวดเร็ว แต่ DER เร็วกว่าและมีประสิทธิภาพมากกว่าของทั้งสอง ในความเป็นจริง ASN.1 DER สามารถติดตามซีเรียลไลเซอร์ (และบางครั้งก็เอาชนะ) ที่ออกแบบมา30 ปีได้อย่างง่ายดายหลังจากนั้นเองเป็นข้อพิสูจน์ถึงการออกแบบทางวิศวกรรมที่ดี มีขนาดกะทัดรัดมากเล็กกว่า Protocol Buffers และ Thrift ซึ่ง Avro เอาชนะได้เท่านั้น ปัญหาคือมีห้องสมุดที่ยอดเยี่ยมเพื่อรองรับและตอนนี้ Bouncy Castle ดูเหมือนจะเป็นสิ่งที่ดีที่สุดสำหรับ C # / Java ASN.1 เป็นราชาในระบบความปลอดภัยและการเข้ารหัสลับและจะไม่หายไปไหนดังนั้นอย่ากังวลกับ 'การพิสูจน์อักษรในอนาคต' แค่ได้ห้องสมุดดีๆ ...
มันไม่ได้แย่ แต่ก็ไม่เร็วที่สุดหรือเล็กที่สุดหรือได้รับการสนับสนุนที่ดีที่สุด ไม่มีเหตุผลในการผลิตให้เลือก
นอกเหนือจากนั้นพวกมันค่อนข้างคล้ายกัน ส่วนใหญ่เป็นรูปแบบพื้นฐานTLV: Type-Length-Value
หลักการ
Protocol Buffers (ที่มาของ Google), Avro (ใช้ Apache, ใช้ใน Hadoop), Thrift (ที่มาของ Facebook ตอนนี้คือโครงการ Apache) และ ASN.1 (Telecom กำเนิด) ทั้งหมดเกี่ยวข้องกับการสร้างรหัสบางระดับที่คุณแสดงข้อมูลของคุณในซีเรียลไลเซอร์เป็นครั้งแรก - เฉพาะรูปแบบจากนั้น serializer "คอมไพเลอร์" จะสร้างซอร์สโค้ดสำหรับภาษาของคุณผ่านทางcode-gen
เฟส แหล่งที่มาของแอปของคุณจะใช้code-gen
คลาสเหล่านี้สำหรับ IO โปรดทราบว่าการใช้งานบางอย่าง (เช่นไลบรารี Avro ของ Microsoft หรือ ProtoBuf.NET ของ Marc Gavel) ช่วยให้คุณสามารถตกแต่งออบเจ็กต์ POCO / POJO ในระดับแอปของคุณได้โดยตรงจากนั้นไลบรารีจะใช้คลาสที่ได้รับการตกแต่งเหล่านั้นโดยตรงแทนคลาสของ code-gen เราได้เห็นข้อเสนอนี้เพิ่มประสิทธิภาพเนื่องจากกำจัดขั้นตอนการคัดลอกออบเจ็กต์ (จากฟิลด์ POCO / POJO ระดับแอปพลิเคชันไปจนถึงฟิลด์รหัส -GEN)
โครงการนี้ ( https://github.com/sidshetye/SerializersCompare ) เปรียบเทียบอนุกรมที่สำคัญในโลก C # ชาว Java มีสิ่งที่คล้ายกันอยู่แล้ว
1000 iterations per serializer, average times listed
Sorting result by size
Name Bytes Time (ms)
------------------------------------
Avro (cheating) 133 0.0142
Avro 133 0.0568
Avro MSFT 141 0.0051
Thrift (cheating) 148 0.0069
Thrift 148 0.1470
ProtoBuf 155 0.0077
MessagePack 230 0.0296
ServiceStackJSV 258 0.0159
Json.NET BSON 286 0.0381
ServiceStackJson 290 0.0164
Json.NET 290 0.0333
XmlSerializer 571 0.1025
Binary Formatter 748 0.0344
Options: (T)est, (R)esults, s(O)rt order, (S)erializer output, (D)eserializer output (in JSON form), (E)xit
Serialized via ASN.1 DER encoding to 148 bytes in 0.0674ms (hacked experiment!)
There are two variants, DER (binary) encoding and PEM (ascii) encoding
. โปรดทราบว่า PEM เป็นเพียงข้อมูลไบนารีฐาน 64 ที่เข้ารหัสภายในความคิดเห็น BEGIN END ข้อมูลไบนารีนี้อาจถูกสร้างขึ้นโดยใช้การเข้ารหัส DER ดังนั้นจึงเป็นเรื่องแปลกที่จะเปรียบเทียบ PEM และ DER
เมื่อเพิ่มมุมมองด้านประสิทธิภาพ Uber ได้ประเมินห้องสมุดเหล่านี้หลายแห่งในบล็อกด้านวิศวกรรมของพวกเขา:
https://eng.uber.com/trip-data-squeeze/
ผู้ชนะสำหรับพวกเขา? MessagePack + zlib สำหรับการบีบอัด
เป้าหมายของเราคือการค้นหาการรวมกันของโปรโตคอลการเข้ารหัสและอัลกอริทึมการบีบอัดที่ให้ผลลัพธ์ที่กะทัดรัดที่สุดด้วยความเร็วสูงสุด เราทดสอบการเข้ารหัสโปรโตคอลและอัลกอริธึมการบีบอัดรวมกันใน 2,219 การเดินทางแบบไม่ระบุตัวตนปลอมจาก Uber New York City (ใส่ไฟล์ข้อความเป็น JSON)
บทเรียนต่อไปนี้คือความต้องการของคุณขับเคลื่อนห้องสมุดที่เหมาะกับคุณ สำหรับ Uber พวกเขาไม่สามารถใช้โปรโตคอลที่ใช้ IDL ได้เนื่องจากลักษณะการส่งข้อความที่ไม่มีสคีมา สิ่งนี้กำจัดตัวเลือกมากมาย นอกจากนี้สำหรับพวกเขาไม่ใช่แค่เวลาเข้ารหัส / ถอดรหัสแบบดิบเท่านั้นที่เข้ามามีบทบาท แต่ขนาดของข้อมูลที่เหลือ
ขนาดผลลัพธ์
ผลลัพธ์ความเร็ว
สิ่งที่สำคัญอย่างหนึ่งเกี่ยวกับ ASN.1 คือถูกออกแบบมาสำหรับข้อกำหนดที่ ไม่นำไปใช้งาน ดังนั้นจึงเป็นการดีมากในการซ่อน / ละเว้นรายละเอียดการใช้งานในภาษาโปรแกรม "จริง" ใด ๆ
เป็นหน้าที่ของ ASN.1-Compiler ในการใช้กฎการเข้ารหัสกับไฟล์ asn1 และสร้างจากโค้ดปฏิบัติการทั้งสอง กฎการเข้ารหัสอาจกำหนดไว้ใน EnCoding Notation (ECN) หรืออาจเป็นหนึ่งในกฎมาตรฐานเช่น BER / DER, PER, XER / EXER นั่นคือ ASN.1 คือประเภทและโครงสร้างกฎการเข้ารหัสจะกำหนดการเข้ารหัสบนสายและสุดท้าย แต่ไม่ท้ายสุดคอมไพเลอร์จะโอนไปยังภาษาโปรแกรมของคุณ
คอมไพเลอร์ฟรีรองรับ C, C ++, C #, Java และ Erlang สำหรับความรู้ของฉัน คอมไพเลอร์เชิงพาณิชย์ (ราคาแพงและมีสิทธิบัตร / ใบอนุญาตมาก) มีความหลากหลายมากโดยปกติแล้วจะมีการอัปเดตและรองรับภาษาได้มากกว่าในบางครั้ง แต่ดูไซต์ของพวกเขา (OSS Nokalva, Marben เป็นต้น)
เป็นเรื่องง่ายมากที่จะระบุอินเทอร์เฟซระหว่างฝ่ายต่างๆของวัฒนธรรมการเขียนโปรแกรมที่แตกต่างกันโดยสิ้นเชิง (เช่น "คนฝัง" และ "เซิร์ฟเวอร์เกษตรกร") โดยใช้เทคนิคนี้: ไฟล์ asn 1, กฎการเข้ารหัสเช่น BER และเช่นแผนภาพการโต้ตอบ UML . ไม่ต้องกังวลว่าจะใช้งานอย่างไรขอให้ทุกคนใช้ "สิ่งของ"! สำหรับฉันมันได้ผลดีมาก Btw: ที่เว็บไซต์ของ OSS Nokalva คุณอาจพบหนังสือดาวน์โหลดฟรีเกี่ยวกับ ASN.1 อย่างน้อยสองเล่ม (เล่มหนึ่งโดย Larmouth อีกเล่มโดย Dubuisson)
IMHO ผลิตภัณฑ์อื่น ๆ ส่วนใหญ่พยายามที่จะเป็นเครื่องกำเนิดไฟฟ้าอีกตัวหนึ่งของ RPC เท่านั้นโดยสูบอากาศจำนวนมากเข้าสู่ปัญหาการทำให้เป็นอนุกรม ถ้าใครต้องการสิ่งนั้นก็อาจจะดี แต่สำหรับฉันแล้วพวกเขาดูเหมือนการสร้างสรรค์ใหม่ของ Sun-RPC (จากปลายยุค 80) แต่เดี๋ยวก่อนก็ใช้ได้ดีเช่นกัน
พันธบัตรของ Microsoft ( https://github.com/Microsoft/bond ) นั้นน่าประทับใจมากในด้านประสิทธิภาพฟังก์ชันการทำงานและเอกสาร อย่างไรก็ตามมันไม่รองรับแพลตฟอร์มเป้าหมายจำนวนมาก ณ ตอนนี้ (13 ก.พ. 2015) ฉันสามารถสันนิษฐานได้ว่าเป็นเพราะมันใหม่มาก ปัจจุบันรองรับ python, c # และ c ++ มันถูกใช้โดย MS ทุกที่ ฉันลองแล้วสำหรับฉันในฐานะนักพัฒนา ac # ที่ใช้ bond นั้นดีกว่าการใช้ protobuf แต่ฉันก็ใช้ความประหยัดเช่นกันปัญหาเดียวที่ฉันประสบคือเอกสารประกอบฉันต้องลองหลาย ๆ อย่างเพื่อทำความเข้าใจว่าสิ่งต่างๆเสร็จสิ้นอย่างไร
แหล่งข้อมูลเพียงไม่กี่อย่างบน Bond มีดังนี้ ( https://news.ycombinator.com/item?id=8866694 , https://news.ycombinator.com/item?id=8866848 , https://microsoft.github.io/ พันธบัตร / why_bond.html )
สำหรับประสิทธิภาพจุดข้อมูลหนึ่งคือjvm-serializersเกณฑ์มาตรฐานซึ่งเป็นข้อความขนาดเล็กที่เฉพาะเจาะจง แต่อาจช่วยได้หากคุณอยู่บนแพลตฟอร์ม Java ฉันคิดว่าประสิทธิภาพโดยทั่วไปมักจะไม่ใช่ความแตกต่างที่สำคัญที่สุด นอกจากนี้: อย่าถือเอาคำพูดของผู้เขียนเป็นพระกิตติคุณ การอ้างสิทธิ์โฆษณาจำนวนมากเป็นของปลอม (ตัวอย่างเช่นไซต์ msgpack มีการอ้างสิทธิ์ที่น่าสงสัยอาจเร็ว แต่ข้อมูลเป็นภาพร่างมากกรณีใช้งานไม่เป็นจริง)
ความแตกต่างที่สำคัญอย่างหนึ่งคือต้องใช้สคีมา (PB, อย่างน้อย Thrift; Avro อาจเป็นทางเลือก ASN.1 ฉันคิดเช่นกัน MsgPack ไม่จำเป็น)
นอกจากนี้: ในความคิดของฉันเป็นเรื่องดีที่สามารถใช้การออกแบบแบบแยกส่วนแบบเลเยอร์ได้ นั่นคือเลเยอร์ RPC ไม่ควรกำหนดรูปแบบข้อมูลการทำให้เป็นอนุกรม น่าเสียดายที่ผู้สมัครส่วนใหญ่รวบรวมสิ่งเหล่านี้ไว้อย่างแน่นหนา
สุดท้ายเมื่อเลือกรูปแบบข้อมูลประสิทธิภาพในปัจจุบันไม่ได้กีดกันการใช้รูปแบบข้อความ มีตัวแยกวิเคราะห์ JSON ที่รวดเร็วอย่างเห็นได้ชัด (และตัวแยกวิเคราะห์ xml แบบสตรีมมิ่งที่ค่อนข้างเร็ว); และเมื่อพิจารณาถึงความสามารถในการทำงานร่วมกันจากภาษาสคริปต์และความสะดวกในการใช้งานรูปแบบไบนารีและโปรโตคอลอาจไม่ใช่ทางเลือกที่ดีที่สุด