Streaming
transport เดียว 4 รูปแบบ
หัวข้อที่มีชื่อว่า “transport เดียว 4 รูปแบบ”ทุก gRPC call วิ่งบน HTTP/2 stream เส้นเดียว และเพราะ stream นั้นส่ง message เป็น ลำดับ ได้ทั้งสองทิศทาง gRPC จึงมี call ให้เลือก 4 แบบ — ไม่ใช่ transport 4 อัน แค่รูปแบบการใช้ stream เดียวกัน 4 แบบ
flowchart TB
subgraph u["Unary"]
direction LR
uc["client"] -- "1 request" --> us["server"]
us -- "1 response" --> uc
end
subgraph ss["Server streaming"]
direction LR
sc["client"] -- "1 request" --> sss["server"]
sss -- "many responses" --> sc
end
subgraph cs["Client streaming"]
direction LR
csc["client"] -- "many requests" --> css["server"]
css -- "1 response" --> csc
end
subgraph bd["Bidirectional"]
direction LR
bc["client"] <-- "many both ways" --> bs["server"]
end unary คุณรู้จักอยู่แล้ว — 1 request 1 response คือ RPC ที่ใช้ทุกวัน โมดูลนี้ครอบคลุมอีก 3 แบบที่เหลือ พร้อม flow control ที่ทำให้ stream ทำงานได้ราบรื่น
โมดูลนี้ครอบคลุมอะไรบ้าง
หัวข้อที่มีชื่อว่า “โมดูลนี้ครอบคลุมอะไรบ้าง”| บทเรียน | รูปแบบ | เหมาะกับ |
|---|---|---|
| Server streaming | 1 request → N responses | live feed, result set ขนาดใหญ่, progress update |
| Client streaming | N requests → 1 response | upload, batching, การรับ metric |
| Bidirectional streaming | N ↔ N | chat, multiplayer, session แบบโต้ตอบ |
| Flow control & backpressure | — | กัน producer ที่เร็วไม่ให้ท่วม consumer ที่ช้า |
เมื่อไร stream ดีกว่า unary หลาย ๆ call
หัวข้อที่มีชื่อว่า “เมื่อไร stream ดีกว่า unary หลาย ๆ call”ใช้ streaming เมื่อ:
- result set ใหญ่หรือไม่จำกัด — ส่ง 10,000 row เป็น stream เดียวช่วยไม่ต้อง buffer ทั้งหมดไว้ใน memory และ client เริ่มประมวลผล row แรกได้ก่อนที่ row สุดท้ายจะถูกสร้าง
- data ทยอยมาตามเวลา — price, event, log สั่งให้ server push แต่ละ item ทันทีที่เกิด แทนที่ client จะ poll
- อยากได้ call ยาว 1 call แทนการ setup หลายครั้ง — stream เฉลี่ย overhead ต่อ call ไปกับ message จำนวนมาก
เมื่อไรไม่ควร stream
หัวข้อที่มีชื่อว่า “เมื่อไรไม่ควร stream”streaming ไม่ฟรี และการหยิบมาใช้แบบอัตโนมัติเป็นความผิดพลาดที่พบบ่อย:
- request/response เดียวเรียบง่ายกว่า ถ้ามี input เดียว output เดียว ใช้ unary เถอะ stream เพิ่ม lifecycle, การ handle error ที่เกิดได้ทุกจุด และ retry ที่ยากขึ้น
- stream มี state และอยู่ยาว ซึ่งทำให้ load balancing ยุ่งยาก — stream ถูกผูกกับ backend เดียวตลอดอายุของตัวเอง rebalance กลางทางไม่ได้
- retry ยากขึ้น unary call retry ง่ายมาก แต่ stream ที่บริโภคไปครึ่งทางแล้ว retry ไม่ได้ง่าย ๆ