พูดตามฉัน:
เหตุการณ์ REST และ asynchronous ไม่ใช่ทางเลือก มันเป็นฉากฉากหลังอย่างสมบูรณ์
คุณสามารถมีหนึ่งหรืออื่น ๆ หรือทั้งสองอย่างหรือไม่ เป็นเครื่องมือที่แตกต่างกันโดยสิ้นเชิงสำหรับโดเมนปัญหาที่แตกต่างกันโดยสิ้นเชิง ในความเป็นจริงอเนกประสงค์สื่อสารตอบสนองการร้องขอเป็นอย่างที่มีความสามารถของการเป็นตรงกันเหตุการณ์ที่ขับเคลื่อนด้วยและใจกว้างความผิด
เป็นตัวอย่างเล็ก ๆ น้อย ๆ โปรโตคอล AMQP ส่งข้อความผ่านการเชื่อมต่อ TCP ใน TCP, ทุกแพ็คเก็ตจะต้องได้รับการยอมรับโดยรับ หากผู้ส่งแพ็คเก็ตไม่ได้รับ ACK สำหรับแพ็คเก็ตนั้นมันจะส่งแพ็กเก็ตนั้นไปเรื่อย ๆ จนกว่าจะเป็น ACK'd หรือจนกว่าเลเยอร์ของแอปพลิเคชันจะ "ยอมแพ้" และยกเลิกการเชื่อมต่อ นี่เป็นรูปแบบคำขอการตอบสนองที่ไม่ผิดพลาดอย่างเห็นได้ชัดเพราะ "คำขอส่งแพ็คเก็ต" ทุกคนต้องมี "ตอบรับการตอบรับแพ็กเก็ต" ที่แนบมาด้วยและความล้มเหลวในการตอบสนองผลลัพธ์ในการเชื่อมต่อทั้งหมดล้มเหลว แต่ AMQP ซึ่งเป็นโปรโตคอลที่ได้มาตรฐานและนำมาใช้กันอย่างแพร่หลายสำหรับการรับส่งข้อความข้อความผิดพลาดแบบอะซิงโครนัสมีการสื่อสารผ่าน TCP! สิ่งที่ช่วยให้?
แนวคิดหลักในการเล่นที่นี่เป็นที่ที่ปรับขนาดได้อย่างอิสระคู่ส่งข้อความความผิดพลาดจะถูกกำหนดโดยข้อความสิ่งที่คุณส่งไม่ว่าคุณจะส่งพวกเขา ในคำอื่น ๆcoupling หลวมถูกกำหนดไว้ที่ชั้นสมัคร
ลองดูที่ทั้งสองฝ่ายสื่อสารกันโดยตรงกับ RESTful HTTP หรือทางอ้อมกับนายหน้าข้อความ AMQP สมมติว่าปาร์ตี้ A ประสงค์จะอัปโหลดภาพ JPEG ไปยังปาร์ตี้ B ที่จะลับคมบีบอัดหรือปรับปรุงภาพ ปาร์ตี้ A ไม่ต้องการรูปภาพที่ถูกประมวลผลในทันที แต่จะต้องมีการอ้างอิงเพื่อใช้และเรียกคืนในอนาคต นี่เป็นวิธีหนึ่งที่อาจเป็นไปได้ในส่วนที่เหลือ:
- ปาร์ตี้ A ส่ง
POST
ข้อความร้องขอHTTP ไปยังปาร์ตี้ B ด้วยContent-Type: image/jpeg
- ปาร์ตี้ B ประมวลภาพ (เป็นเวลานานถ้ามันใหญ่) ในขณะที่ปาร์ตี้ A รออยู่อาจทำสิ่งอื่น ๆ
- ปาร์ตี้ B ส่ง
201 Created
ข้อความตอบกลับHTTP ไปยังปาร์ตี้ A พร้อมContent-Location: <url>
ส่วนหัวที่เชื่อมโยงไปยังอิมเมจที่ประมวลผล
- ปาร์ตี้ A พิจารณางานที่ทำเนื่องจากตอนนี้มีการอ้างอิงถึงอิมเมจที่ประมวลผลแล้ว
- ในอนาคตเมื่อปาร์ตี้ A ต้องการภาพที่ดำเนินการแล้วจะได้รับโดยใช้ลิงก์จาก
Content-Location
ส่วนหัวก่อนหน้า
201 Created
รหัสการตอบสนองลูกค้าบอกว่าไม่เพียง แต่ได้รับคำขอของพวกเขาประสบความสำเร็จก็ยังสร้างทรัพยากรใหม่ ในการตอบกลับ 201 Content-Location
ส่วนหัวเป็นลิงก์ไปยังทรัพยากรที่สร้างขึ้น ระบุไว้ใน RFC 7231 ส่วน 6.3.2 และ 3.1.4.2
ตอนนี้มาดูกันว่าการโต้ตอบนี้ทำงานอย่างไรกับโปรโตคอล RPC ที่ตั้งอยู่บน AMQP:
- ปาร์ตี้ A ส่งนายหน้าข้อความ AMQP (เรียกว่า Messenger) ข้อความที่มีรูปภาพและคำแนะนำในการจัดเส้นทางไปยังปาร์ตี้ B สำหรับการประมวลผลจากนั้นตอบกลับไปยังปาร์ตี้ A พร้อมที่อยู่บางประเภทสำหรับรูปภาพ
- ปาร์ตี้ A กำลังรออาจทำสิ่งอื่น ๆ
- Messenger ส่งข้อความต้นฉบับของ Party A ไปยัง Party B
- ปาร์ตี้ B ประมวลผลข้อความ
- ปาร์ตี้ B ส่งข้อความที่มีที่อยู่สำหรับประมวลภาพและคำแนะนำเพื่อส่งข้อความไปยังปาร์ตี้ A
- Messenger ส่งปาร์ตี้ A ข้อความจากปาร์ตี้ B ที่มีที่อยู่รูปภาพที่ถูกประมวลผล
- ปาร์ตี้ A พิจารณางานที่ทำเนื่องจากตอนนี้มีการอ้างอิงถึงอิมเมจที่ประมวลผลแล้ว
- บางครั้งในอนาคตเมื่อ Party A ต้องการภาพมันจะดึงภาพโดยใช้ที่อยู่ (อาจส่งข้อความถึงบุคคลอื่น ๆ )
คุณเห็นปัญหาที่นี่หรือไม่ ในทั้งสองกรณีพรรคไม่สามารถได้รับที่อยู่ภาพจนกระทั่งหลังจากที่พรรค B ประมวลผลภาพ แต่ปาร์ตี้ A ไม่ต้องการรูปภาพในทันทีและโดยสิทธิ์ทั้งหมดก็ไม่ต้องสนใจน้อยหากการประมวลผลเสร็จสิ้น!
เราสามารถแก้ไขปัญหานี้ได้อย่างง่ายดายในกรณี AMQP โดยให้ฝ่าย B บอกว่า B ยอมรับภาพสำหรับการประมวลผลโดยให้ที่อยู่ A สำหรับภาพที่จะประมวลผลหลังจากเสร็จสิ้น จากนั้นปาร์ตี้ B สามารถส่งข้อความในอนาคตเพื่อระบุว่าการประมวลผลภาพเสร็จสิ้นแล้ว AMQP ส่งข้อความเพื่อช่วยเหลือ!
ยกเว้นสิ่งที่เดาได้: คุณสามารถทำสิ่งเดียวกันกับ RESTได้ ในตัวอย่าง AMQP เราเปลี่ยนข้อความ "นี่คือรูปภาพที่ประมวลผล" เป็น "รูปภาพกำลังประมวลผลคุณสามารถรับได้ในภายหลัง" ในการทำเช่นนั้นใน RESTful HTTP เราจะใช้202 Accepted
รหัสและContent-Location
อีกครั้ง:
- ปาร์ตี้ A ส่ง
POST
ข้อความHTTP ไปยังปาร์ตี้ B ด้วยContent-Type: image/jpeg
- ฝ่าย B ส่งการ
202 Accepted
ตอบกลับทันทีซึ่งมีเนื้อหา "การดำเนินการแบบอะซิงโครนัส" ซึ่งจะอธิบายว่าการประมวลผลนั้นเสร็จสิ้นแล้วหรือไม่ รวมทั้งยังเป็นContent-Location: <link>
ส่วนหัวซึ่งในการ202 Accepted
ตอบสนองเป็นลิงค์ไปยังทรัพยากรที่แสดงโดยสิ่งที่ร่างกายตอบสนองคืออะไร ในกรณีนี้นั่นหมายความว่ามันเป็นลิงค์ไปสู่การทำงานแบบอะซิงโครนัสของเรา!
- ปาร์ตี้ A พิจารณางานที่ทำเนื่องจากตอนนี้มีการอ้างอิงถึงอิมเมจที่ประมวลผลแล้ว
- บางครั้งในอนาคตเมื่อปาร์ตี้ A ต้องการอิมเมจที่ประมวลผลอันดับแรกจะรับรีซอร์สการดำเนินการ async ที่เชื่อมโยงกับ
Content-Location
ส่วนหัวเพื่อพิจารณาว่าการประมวลผลเสร็จสิ้นหรือไม่ ถ้าเป็นเช่นนั้น Party A จะใช้ลิงก์ในการดำเนินการ async เพื่อรับอิมเมจที่ประมวลผล
ข้อแตกต่างเพียงอย่างเดียวคือในรุ่น AMQP ปาร์ตี้ B จะบอกฝ่าย A เมื่อทำการประมวลผลภาพ แต่ในรุ่น REST Party A จะตรวจสอบว่าการประมวลผลเสร็จสิ้นก่อนที่จะต้องการภาพหรือไม่ วิธีการเหล่านี้สามารถปรับขนาดได้อย่างเท่าเทียมกัน เมื่อระบบมีขนาดใหญ่ขึ้นจำนวนข้อความที่ส่งทั้งใน async AMQP และกลยุทธ์ async REST จะเพิ่มขึ้นตามความซับซ้อนของ asymptotic ข้อแตกต่างเพียงอย่างเดียวคือไคลเอนต์กำลังส่งข้อความพิเศษแทนเซิร์ฟเวอร์
แต่วิธีที่เหลือมีเทคนิคอีกไม่กี่ขึ้นที่แขน: การค้นพบแบบไดนามิกและการเจรจาต่อรองโปรโตคอล พิจารณาว่าการโต้ตอบและการซิงค์ REST ของ async เริ่มต้นอย่างไร ปาร์ตี้ A ส่งคำขอเดียวกันไปยังปาร์ตี้ B โดยมีความแตกต่างเพียงอย่างเดียวคือข้อความแห่งความสำเร็จที่ Party B ตอบกลับมา จะเกิดอะไรขึ้นถ้าพรรค A ต้องการเลือกว่าการประมวลผลภาพแบบซิงโครนัสหรือแบบอะซิงโครนัส? จะเกิดอะไรขึ้นถ้า Party A ไม่รู้ว่า Party B นั้นมีความสามารถในการประมวลผลแบบซิงค์หรือไม่?
HTTP จริง ๆ แล้วมีโปรโตคอลมาตรฐานสำหรับสิ่งนี้อยู่แล้ว! มันเรียกว่าการตั้งค่า HTTP โดยเฉพาะการrespond-async
ตั้งค่าของ RFC 7240 มาตรา 4.1 หากปาร์ตี้ A ต้องการการตอบสนองแบบอะซิงโครนัสก็จะรวมPrefer: respond-async
ส่วนหัวด้วยคำขอ POST เริ่มต้น หากพรรค B ตัดสินใจที่จะให้เกียรติคำขอนี้ก็จะส่งกลับการตอบสนองที่มี202 Accepted
Preference-Applied: respond-async
มิฉะนั้น Party B จะละเว้นPrefer
ส่วนหัวและส่งกลับ201 Created
ตามปกติ
สิ่งนี้ทำให้ฝ่าย A สามารถเจรจากับเซิร์ฟเวอร์ปรับตัวเข้ากับการปรับใช้การประมวลผลภาพแบบไดนามิกได้ นอกจากนี้การใช้ลิงก์ที่ชัดเจนหมายถึงปาร์ตี้ A ไม่จำเป็นต้องรู้เกี่ยวกับบุคคลอื่นนอกเหนือจาก B: ไม่มีนายหน้าข้อความ AMQP และไม่มีพรรคลึกลับ C ที่รู้วิธีเปลี่ยนที่อยู่ของรูปภาพให้เป็นข้อมูลภาพไม่ใช่ B-Async ที่สอง ปาร์ตี้หากต้องการคำขอทั้งแบบซิงโครนัสและแบบอะซิงโครนัส ฯลฯ เพียงอธิบายสิ่งที่ต้องการสิ่งที่ต้องการเลือกแล้วตอบสนองต่อรหัสสถานะเนื้อหาการตอบสนองและลิงก์ เพิ่มในCache-Control
ส่วนหัวสำหรับคำแนะนำที่ชัดเจนเกี่ยวกับเวลาที่จะเก็บสำเนาของข้อมูลในเครื่องและในขณะนี้เซิร์ฟเวอร์สามารถเจรจากับลูกค้าซึ่งทรัพยากรของลูกค้าอาจเก็บสำเนาของเครื่อง (หรือออฟไลน์!) นี่คือวิธีที่คุณสร้างไมโครไซต์ที่รองรับข้อผิดพลาดแบบหลวม ๆ ใน REST