ความตายจากไมโครเซอร์วิสพันตัว
(renegadeotter.com)- วัฒนธรรมที่นำไมโครเซอร์วิสมาใช้ราวกับเป็นค่าเริ่มต้น ถูกวิจารณ์ว่าเพิ่มต้นทุนและความซับซ้อนเพื่อแก้ ปัญหาที่ไม่มีอยู่จริง มากกว่าจะเป็นปัญหาเรื่องสเกลที่เกิดขึ้นจริง
- ความปิดกั้นของ ecosystem JavaScript/Node.js, แนวปฏิบัติแบบ FAANG และเงินทุนเวนเจอร์ที่ไหลเข้ามามาก ประกอบกันจนเกิดบรรยากาศที่แม้แต่สตาร์ตอัปก็พยายามเลียนแบบ สถาปัตยกรรมระดับ web-scale
- ต่อให้มี Docker และ Kubernetes ความยากของ ระบบกระจาย อย่างการพัฒนา ดีบัก ดีพลอย ทดสอบ และทำให้ระบบทนทาน ก็ไม่ได้หายไป
- Dropbox, Twitter, Netflix, Facebook, GitHub, Instagram, Shopify, StackOverflow, WhatsApp ฯลฯ เริ่มต้นด้วยโค้ดเบสแบบโมโนลิทิก หรือจนถึงตอนนี้ก็ยังมี โมโนลิธ เป็นแกนหลัก
- บริษัทส่วนใหญ่ไม่ได้เติบโตถึงระดับที่ต้องใช้ระบบกระจายจริง ๆ ดังนั้นการแยกออกเป็นบริการควรทำเมื่อมีภาระงานที่ต้องแยกและสเกลอย่างชัดเจนเท่านั้น ซึ่งเป็นทางเลือกที่สมจริงกว่า
วัฒนธรรมที่บูชาความซับซ้อน
- การเสียดสีที่อธิบายเขาวงกตไมโครเซอร์วิสอันซับซ้อนเพื่อดึงข้อมูลวันเกิดของผู้ใช้เพียงหนึ่งค่าแต่ก็ยังล้มเหลว กำลังพุ่งเป้าไปที่การออกแบบเกินความจำเป็นในวัฒนธรรมเทคโนโลยีปัจจุบัน
- ปัญหาคือเป้าหมายได้เปลี่ยนจากการแก้โจทย์ตรงหน้า ไปเป็นการเผาเงินเพื่อแก้ ปัญหาที่ไม่มีอยู่จริง
- คำวิจารณ์ต่อ JavaScript และ Node.js ไม่ได้เป็นปัญหาของเทคโนโลยีเฉพาะตัวเท่านั้น แต่เชื่อมโยงกับความเสี่ยงของ ecosystem ซอฟต์แวร์ที่ปิดกั้น ซึ่งทำให้ต้องกลับไปเรียนบทเรียนเดิมซ้ำอีก
- ในอดีตอุตสาหกรรมก็เคยชนกำแพงความซับซ้อนอย่าง CORBA และ SOAP มาก่อน แล้วสุดท้ายก็ต้องย้อนกลับมาปรับทิศทาง
เงื่อนไขที่ทำให้ไมโครเซอร์วิสกลายเป็นกระแส
- นักพัฒนาที่ใช้ JavaScript ฝั่งเบราว์เซอร์เริ่มเรียกตัวเองว่า “full-stack” แล้วขยับเข้าสู่การพัฒนาเซิร์ฟเวอร์และโค้ดอะซิงก์ โดย Node ยุคแรกใกล้เคียงกับโปรเจกต์เรียนรู้ส่วนบุคคล และ JavaScript ยุคแรกก็เป็นตัวเลือกที่มีปัญหามากสำหรับงานเซิร์ฟเวอร์
- เมื่อโลกภายนอก Node ถูกมองราวกับว่าแทบไม่มีอยู่จริง จึงเกิด ความคิดแบบสุดโต่ง ที่เชื่อว่าวิธีแบบ Node คือวิธีเดียว
- ต่อมาคนจาก FAANG เข้าสู่สตาร์ตอัปและเผยแพร่วิธี “ที่ Google ทำ” ราวกับเป็นคำตอบที่ถูกต้อง โดยไม่สนบริบทหรือขนาด
- ตัวอย่างชัด ๆ คือแรงกดดันแนวว่า หากไม่มี
User Preferences Serviceแยกต่างหาก ระบบจะสเกลไม่ได้
- ตัวอย่างชัด ๆ คือแรงกดดันแนวว่า หากไม่มี
- ในช่วงที่เงินทุนเวนเจอร์ล้นเหลือ สิ่งสำคัญกว่ารายได้คือการแสดงการเติบโตแบบระเบิดต่อหน้านักลงทุน บริษัทจึงเร่งจ้างวิศวกรซอฟต์แวร์ราคาแพงให้มาทำ “อะไรสักอย่าง” อย่างรวดเร็ว
ระบบกระจายยังคงยากเหมือนเดิม
- ไมโครเซอร์วิสถูกห่อหุ้มให้ดูเหมือน “วิธีใหม่ในการใช้ซอฟต์แวร์ที่สเกลได้” แต่แก่นแท้แล้วมันเชื่อมตรงกับปัญหา ระบบกระจาย ที่มีมานานแล้ว
- ระบบกระจายในอดีตถูกมองว่าเป็นเครื่องมือที่ยากและเสี่ยง โดยเฉพาะเป็นทางเลือกสุดท้ายสำหรับโจทย์ที่ยากจริง ๆ
- ในระบบกระจาย งานต่อไปนี้ล้วนยากขึ้นและใช้เวลานานขึ้น
- การพัฒนา
- การดีบัก
- การดีพลอย
- การทดสอบ
- การทำให้ระบบทนทานต่อความล้มเหลว
- การพัฒนาแบบไมโครเซอร์วิสไม่มีเครื่องมือมาตรฐานหรือเฟรมเวิร์กร่วมที่ชัดเจน และแม้ในยุค 2020 งานด้านระบบกระจายก็เพียงแค่ง่ายขึ้นเล็กน้อยเท่านั้น
- Docker และ Kubernetes ไม่สามารถลบ ความซับซ้อนโดยเนื้อแท้ ของการตั้งค่าระบบกระจายได้อย่างน่าอัศจรรย์
กรณีที่ความเรียบง่ายให้ผลลัพธ์ดีกว่า
- บทสรุปจากการตรวจสอบโค้ดสตาร์ตอัปตลอด 5 ปี สรุปว่า สตาร์ตอัปที่ทำได้ดีมักใช้แนวทาง Keep It Simple แบบเรียบง่ายจนแทบจะหน้าด้าน
- การเปลี่ยนไปใช้ไมโครเซอร์วิสเร็วเกินไป สถาปัตยกรรมที่พึ่งพาการประมวลผลแบบกระจาย และการออกแบบที่ยึดการส่งข้อความเป็นศูนย์กลาง เป็นกับดักหลักที่ทำหลายบริษัทลำบาก
- สตาร์ตอัปจำนวนมากสร้างระบบที่เรียบง่ายและมีประสิทธิภาพได้ แต่กลับรู้สึก ด้อยค่าแบบปลอม ๆ ที่ไม่ได้ทำไมโครเซอร์วิสตั้งแต่วันแรก
- คำถามว่า “มีแค่ Django monolith ที่ทีมวิศวกรไม่กี่คนดูแล กับ MySQL instance หนึ่งตัว แล้วมันผิดตรงไหน” คำตอบแทบจะตลอดเวลาคือ “ไม่ได้ผิดอะไรเลย”
- แม้แต่วิศวกรที่มีประสบการณ์ก็อาจรู้สึกไม่เหมาะสมกับวัฒนธรรมเทคโนโลยีทุกวันนี้ แต่ปัญหาจริงอาจเป็นสภาพแวดล้อมที่ผสมทั้งความมั่นใจเกินเหตุ ความสิ้นเปลือง และ Dunning-Kruger
บริษัทที่เติบโตได้ด้วยโมโนลิธ
- ความคิดที่ว่าไม่มีโมโนลิธแล้วจะโตไม่ได้ ใกล้เคียงกับเป็นตำนานมากกว่า
- Dropbox, Twitter, Netflix, Facebook, GitHub, Instagram, Shopify, StackOverflow ฯลฯ เริ่มต้นด้วย โค้ดเบสแบบโมโนลิทิก และบางแห่งก็ยังคงมีโมโนลิธเป็นแกนหลักจนถึงปัจจุบัน
- StackOverflow ถึงกับใช้ หน้าประสิทธิภาพ มาอวดว่าเว็บไซต์ขนาดใหญ่ของตนทำงานได้ด้วยฮาร์ดแวร์ไม่มาก
- Shopify ยังคงใช้ Rails monolith และใช้ Resque ที่ผ่านการพิสูจน์แล้วเพื่อประมวลผล งานหลายพันล้านรายการ
- WhatsApp เติบโตอย่างมากด้วย Erlang monolith และวิศวกรราว 50 คน
- รักษาขนาดองค์กรวิศวกรรมไว้เล็ก ๆ ที่ประมาณ 50 คน
- แต่ละทีมมีขนาด 1–3 คน และมีอิสระสูง
- นิยมใช้เซิร์ฟเวอร์จำนวนน้อย และขยายแต่ละเครื่องในแนวตั้งให้มากที่สุดเท่าที่ทำได้
- Instagram ถูกซื้อกิจการด้วยมูลค่าหลายพันล้านดอลลาร์ในขณะที่มีทีมเพียง 12 คน และ Threads ก็เดินตามโมเดลของ Instagram
อย่าแก้ปัญหาที่ไม่มีอยู่จริง
- คำถามสำคัญคือ “กำลังแก้ปัญหาอะไรอยู่”
- หากปัญหาคือเรื่องสเกล ก็ต้องมี ข้อมูล ที่แสดงให้เห็นว่าทำไมและอะไรที่ควรแยกออกเป็นบริการต่างหาก
- ระบบกระจายถูกสร้างขึ้นเพื่อรองรับสเกลและความทนทาน แต่ก็ต้องคำนึงถึงสถานการณ์ที่เมื่อบริการหนึ่งช้าหรือล่ม ทราฟฟิกจะไหลทะลักไปยังบริการอื่นด้วย
- สิ่งที่ต้องพิจารณาจะแตกต่างกันไปตามรูปแบบการใช้งานและลักษณะโหลดของระบบ
- backpressure
- circuit breaker
- queue
- jitter
- timeout ที่สมเหตุสมผลสำหรับทุก endpoint
- กลไกป้องกันไม่ให้การเปลี่ยนแปลงเล็กน้อยกลายเป็นความล้มเหลวทั้งระบบ
- บริษัทส่วนใหญ่ไปไม่ถึงขนาดมหึมาที่จำเป็นต้องใช้ระบบกระจายจริง ๆ
- หากไม่มีขนาด ความเชี่ยวชาญ และทรัพยากรแบบ Amazon หรือ Google การเลียนแบบวิธีของพวกเขามักทำให้เสียทั้งเวลาและเงิน
- ยังมีคำเตือนทิ้งท้ายไว้ว่า ระบบกระจายที่แย่ อาจรับมือยากกว่าระบบกระจายเสียอีก
อุดมคติกับความจริงของบริการแยกตามทีมและ API
- ความพยายามจะทำให้ topology แบบกระจายสอดคล้องกับโครงสร้างบริษัท เริ่มต้นจากความคิดที่ว่า หากแบ่งปัญหาออกเป็นชิ้นเล็ก ๆ มันจะง่ายขึ้น
- ไมโครเซอร์วิสในอุดมคติคือสิ่งที่ทีมเฉพาะดูแลอย่างเคร่งครัด ซ่อนอยู่หลัง API ที่สวยงาม มีเวอร์ชันแบบ backward compatible และแทบไม่ต้องสื่อสารกับทีมอื่นเลย
- แต่ในความเป็นจริง ช่อง Slack มักเต็มไปด้วยข้อความเรื่องรีลีส บั๊ก การเปลี่ยนค่า config การเปลี่ยนที่ทำของพัง และประกาศต่าง ๆ
- ทุกคนต้องรับรู้ทุกสถานการณ์อยู่ตลอด และทีมที่ก็ยุ่งอยู่แล้วก็มักต้องมารับผิดชอบไมโครเซอร์วิสหลายตัวแบบครึ่ง ๆ กลาง ๆ
- เมื่อคนย้ายทีม ความเป็นเจ้าของบริการก็เปลี่ยนตามไปด้วย สุดท้ายกลายเป็นการสร้างรถกอล์ฟห่วย ๆ หลายคัน แทนที่จะได้รถแข่งดี ๆ คันเดียว
สิ่งที่ไมโครเซอร์วิสทำให้สูญเสีย
-
DRY ที่อ่อนแรงลง
- ไมโครเซอร์วิสโดยพื้นฐานแล้วไม่ DRY และแต่ละบริการจะมี boilerplate ที่ซ้ำกัน
- ในไมโครเซอร์วิสขนาดเล็ก สัดส่วนของโค้ดงานระบบจะยิ่งสูง จน service instance โดยเฉลี่ยอาจใกล้เคียงกับโค้ด “service” มากกว่าโค้ดผลิตภัณฑ์
- ต่อให้พยายามแยกโค้ดร่วมออกมา ตัวเลือกทั้งหมดก็ล้วนมาพร้อมความเจ็บปวด
- หากสร้างไลบรารีร่วม ก็ต้องกำหนดเวอร์ชันและกลยุทธ์การอัปเดต
- อาจต้องสร้าง pull request เป็นประจำในทุก repository เพื่อบังคับอัปเดต
- หากรวมเป็น monorepo ก็จะเกิดปัญหาในแบบของมันเอง
- หรือไม่ก็ต้องยอมให้มีโค้ดซ้ำบางส่วน หรือปล่อยให้แต่ละทีมประดิษฐ์ล้อใหม่ซ้ำแล้วซ้ำอีก
-
ประสบการณ์นักพัฒนาที่แย่ลง
- ประสบการณ์นักพัฒนาคือขนาดของ แรงเสียดทานและความพยายาม ที่ต้องใช้ในการพัฒนาฟีเจอร์ใหม่หรือแก้บั๊ก
- ในสภาพแวดล้อมแบบไมโครเซอร์วิส จำเป็นต้องมีแผนที่ทางความคิดของทั้งระบบ เพื่อรู้ว่างานหนึ่ง ๆ ต้องเปิดบริการใด ต้องคุยกับทีมไหน และต้องถามใครเรื่องอะไร
- Spotify ถึงกับสร้าง Backstage เพื่อทำรายการระบบและบริการจำนวนมหาศาล ซึ่งเป็นเบาะแสว่าต้นทุนของเกมนี้สูงมาก
- บริษัทที่ไม่ใช่ Spotify จึงมักต้องทำโซลูชันเฉพาะกิจขึ้นมาเอง และยากจะคาดหวังทั้งความแข็งแรงและการย้ายไปใช้ที่อื่นได้ง่าย
- เมื่อต้องเริ่มบริการใหม่ ก็ยังมีรายการที่ต้องทำให้เป็นอัตโนมัติอีกมาก
- สิทธิ์นักพัฒนาบน GitHub/GitLab
- environment variable และการตั้งค่าพื้นฐาน
- CI/CD
- การตรวจสอบคุณภาพโค้ด
- การตั้งค่าการรีวิวโค้ด
- กฎและการป้องกันของ branch
- monitoring และ observability
- test harness
- infrastructure as code
- หากใช้หลายภาษาโปรแกรม รายการนี้ก็จะคูณเพิ่มตามจำนวนภาษา
- การขัดเกลา automation เหล่านี้อาจใช้เวลาหลายเดือน และทำให้ต้องเลือกระหว่างการสร้างผลิตภัณฑ์กับการสร้างเครื่องมือ
-
ความยากของการทดสอบแบบรวมระบบ
- แม้การทดสอบบริการเดี่ยวและ unit test จะผ่าน ก็ยังเป็นคนละเรื่องกับการยืนยันว่าเส้นทางหลักของระบบยังทำงานได้หลังทุก commit
- การทดสอบแบบรวมระบบในสภาพแวดล้อมกระจายถูกมองว่าเป็นปัญหาที่แทบเป็นไปไม่ได้ และหลายคนเห็นว่า observability ได้เข้ามาแทนที่ตรงนั้นแล้ว
- observability กลายเป็นอุตสาหกรรมใหม่ที่ไม่เพียงต้องใช้เงิน แต่ยังต้องกินเวลาของนักพัฒนาด้วย
- observability ไม่ได้ทำงานได้ทันทีเหมือนปลั๊กอิน แต่ต้องเข้าใจและลงมือทำสิ่งต่าง ๆ อย่าง canary release และ feature flag
- การแยกปัญหาออกเป็นชิ้น ๆ ไม่ได้ทำให้แก้ง่ายขึ้น แต่กลับได้ชุดปัญหาที่ยากกว่าเดิม
โมโนลิธไม่ได้แปลว่าโค้ดดีโดยอัตโนมัติ
- การสนับสนุนโมโนลิธไม่ได้หมายความว่า “โมโนลิธคือโค้ดดี และไมโครเซอร์วิสคือโค้ดแย่”
- ในโลกจริงมี โมโนลิธธรรมดา ๆ มากมายที่สร้างโดยทีมที่รีบเกินไปหรือทีมระดับกลาง ๆ
- เพียงแต่ระบบกระจายจะโหดกว่ามากกับส่วนที่ทำแบบลวก ๆ การตัดสินใจที่แย่ และรูปแบบความล้มเหลวที่มองข้ามไป
- หากไม่ได้ดำเนินงานในระดับสูงอย่างสม่ำเสมอ ก็ต้องจ่ายราคาในโลกของระบบกระจาย
ไม่จำเป็นต้อง micro แค่เป็น service ก็อาจพอ
- บริการไม่จำเป็นต้อง “micro” เสมอไป และในหลายกรณี เป็นแค่ service ธรรมดา ก็เพียงพอแล้ว
- สตาร์ตอัปบางแห่งไปไกลถึงขั้น สร้างบริการแยกต่อหนึ่งฟังก์ชัน ซึ่งแสดงให้เห็นว่าคาร์โก้คัลต์ที่ยังไม่ผ่านการพิสูจน์ไปได้ไกลแค่ไหน
- การ เริ่มต้นด้วยโมโนลิธ เป็นตัวเลือกที่ชัดเจน
- แพตเทิร์น “trunk & branches” ก็อาจเหมาะกับหลายกรณี
- ฟังก์ชันหลักรับผิดชอบโดยโมโนลิธหลักที่เป็นเหมือน “เนื้อกับมันฝรั่ง”
- ภาระงานที่ระบุได้ชัดและต้องสเกลแยกต่างหาก ให้ branch service รับผิดชอบ
Image-Resizing Serviceที่ใช้ CPU สูง ย่อมสมเหตุสมผลกว่าที่จะแยกเป็นบริการต่างหากเมื่อเทียบกับUser Registration Service- คำถามว่ามีการสมัครใช้งานต่อวินาทีมากพอจนต้องสเกลแนวนอนแบบอิสระหรือไม่ คือเกณฑ์สำหรับตัดสินใจเรื่องการแยกบริการ
กระแสที่ถอยกลับและทางเลือกที่สมจริง
- ดูเหมือนกระแสไมโครเซอร์วิสที่ร้อนแรงเกินไปกำลังเย็นลง และเมื่อกระแสเงินทุนเวนเจอร์ตึงตัวขึ้น ตลาดก็เริ่มบีบให้บริษัทตัดสินใจอย่างมีเหตุผลมากขึ้น
- วิธีใช้เงินไปกับ สถาปัตยกรรมระดับ web-scale ทั้งที่ไม่มีปัญหาแบบ web-scale นั้นไม่ยั่งยืน
- หากคุณต้องเดินทางจากนิวยอร์กไปฟิลาเดลเฟีย วิธีแก้ปัญหาที่เหมาะสมกว่าคือซื้อตั๋วรถไฟ Amtrak 90 นาที แทนที่จะสร้างยานอวกาศที่ซับซ้อน
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ผมเป็นคนหนึ่งที่สนับสนุน ไมโครเซอร์วิส อย่างแข็งขัน เคยช่วยสร้างแพลตฟอร์มของ Netflix และเดินทางไปทั่วโลกเพื่อบอกเล่าข้อดีของมัน แต่เวลาจะแนะนำสตาร์ทอัพ ผมแทบจะบอกเสมอว่าให้เริ่มจาก โมโนลิธ
การมีโค้ดเบสและฐานข้อมูลเป็นอันเดียวกันนั้นง่ายกว่ามาก และยังสเกลต่อไปได้อีกนานพอสมควร ถ้าใช้ที่เก็บข้อมูลแบบคีย์/ค่าอย่าง DynamoDB แม้จะเสียฟีเจอร์เชิงสัมพันธ์บางส่วนไป แต่ก็ยื้อไปได้ไกลขึ้น
โมโนลิธก็สามารถดีพลอยบน Lambda ได้ และได้ประโยชน์ของ Lambda โดยไม่ต้องแยกบริการ
หลังจากเติบโตแล้ว ค่อยแยกส่วนที่ต้องสเกลอย่างอิสระหรือจำเป็นต้องดีพลอยแยกออกมาเป็นไมโครเซอร์วิสที่มีที่เก็บข้อมูลของตัวเองก็พอ
ไมโครเซอร์วิสกินเวลาเอนจิเนียริ่งอย่างน้อย 25% ไปกับการดูแลแพลตฟอร์มเพียงอย่างเดียว ดังนั้นถ้าเรียกคืนประสิทธิภาพกลับมาไม่ได้เท่านั้น มันก็ไม่มีคุณค่า
ตอนกำลังเติบโต หรือจริง ๆ แล้วในกรณีส่วนใหญ่ ไม่ทำไมโครเซอร์วิสเลยจะดีกว่า
และขอร้องว่าอย่าแยกข้อมูล ข้อมูลจัดการยากกว่าโค้ดมาก
คุณทำให้มันซับซ้อนกว่าตอนนี้ได้เสมอ จะดึงบางส่วนออกจากโมโนลิธไปเป็นบริการก็ได้ แม้มันจะยาก แต่ก็เทียบไม่ได้กับการเอาความซับซ้อนที่ใส่เข้าไปแล้วออกจากระบบ
คนที่เคยย้ายไมโครเซอร์วิสหลายตัวกลับมาเป็นโมโนลิธจะรู้ว่า โดยปกติงานมันใกล้เคียงกับการสร้างใหม่ตั้งแต่ต้น
ผลิตภัณฑ์แบบนี้ ถ้าต้องการ จริง ๆ ก็อาจรันสภาพแวดล้อมโปรดักชันบนแล็ปท็อปได้เลย
ที่ทำงานก่อนหน้านี้ทำงานแบบจัดเต็มไมโครเซอร์วิสเพื่อลูกค้า 300 ราย ทั้งที่เป็นธุรกิจที่มีลูกค้าหลักพันก็ถือว่าสำเร็จ และหลักหมื่นก็สำเร็จมากแล้ว
ปกติแล้วไม่ได้ใช้เวลาเอนจิเนียริ่ง 25% ไปกับการดูแลแพลตฟอร์ม สุดท้ายเลยรันในเครื่องก็ไม่ได้ และสภาพแวดล้อมโปรดักชันก็เหมือนถูกแปะไว้ด้วยเทปกาวอย่างทุลักทุเล
ในการสัมภาษณ์งานล่าสุด ผมถูกถามให้ออกแบบระบบสำหรับ “ผู้ใช้งานพร้อมกัน 500 ล้านคน” ทั้งที่บริษัทนั้นโดยทั่วไปเป็นแบบลูกค้าน้อยแต่รายได้ต่อรายสูง
ผมยังไม่รู้เลยว่านั่นเป็นการทดสอบว่าผมจะชี้ได้ไหมว่า 500 ล้านเป็นตัวเลขไร้เหตุผล เพราะเท่ากับประมาณ 10% ของประชากรโลกที่เชื่อมต่ออินเทอร์เน็ต หรือเขาเชื่อจริง ๆ ว่าสตาร์ทอัพจะไปถึงแบบนั้นได้
ผมตอบว่าจะโฟกัสสิ่งที่เรียบง่ายที่สุด คือสร้างโมโนลิธ แล้วตรวจสอบฟีเจอร์และดูว่ามันเป็นผลิตภัณฑ์ที่ผู้คนต้องการหรือไม่ และผมก็ไม่ได้งาน
ผมกำลังทำงานกับ โมโนลิธ ขนาดมหึมาที่มีผู้ร่วมพัฒนาประมาณ 800 คน แม้แต่งานเพิ่มฟิลด์ง่าย ๆ อย่างวันเกิดผู้ใช้ก็ซับซ้อนพอ ๆ กัน แต่ความซับซ้อนไม่ได้เป็นเรื่องเทคนิคทั้งหมด เพราะมันไปแตะโค้ดของทุกคน จึงต้องมี “การจัดแนวในองค์กร”
การออกแบบกับการรีวิววนซ้ำไม่รู้จบ ต้องได้รับการอนุมัติจากสถาปนิกอย่างน้อย 2 คน และถูกใส่เข้าไปในหลายรอบการวางแผน โค้ดจริงใช้เวลาไม่ถึงครึ่งวัน
ใน code review ต้องทำให้ test coverage ถึง 90% แต่เทสต์มีมากเกินไป PR เดียวเลยใหญ่เกิน ต้องแตกเป็นหลาย PR และค่อย ๆ เข้าไปในรีลีสรายสัปดาห์หลายรอบ
จึงต้องซ่อนไว้หลัง feature flag ซึ่งตอนนี้มี feature flag อยู่ 13,000 รายการ
พอขึ้นโปรดักชันแล้วมีแดชบอร์ดกับมอนิเตอร์ริ่งประกบ ก็เปิด ๆ ปิด ๆ ไปมา ไม่แน่ใจว่าฟีเจอร์วันเกิดไปทำให้บริการคิดเงินพังได้อย่างไร แต่ดูเหมือนจะเป็นสาเหตุ จึงต้องใช้เวลาวิเคราะห์หลายสัปดาห์
สุดท้ายหนึ่งปีให้หลัง วิศวกรที่รับผิดชอบงานนั้นอาจได้ผลประเมินดีและมีสิทธิ์ถูกพิจารณาเลื่อนตำแหน่ง แล้วก็ถูกส่งต่อทันทีไปยังอีกโปรเจกต์พัง ๆ ในปีที่สามของการพัฒนา นั่นคือการให้ผู้ใช้ตั้งค่าเขตเวลาได้
ทั้งไมโครเซอร์วิสและโมโนลิธไม่ใช่ค้อนสารพัดประโยชน์หรือกระสุนเงิน และในทางกลับกันก็ไม่ใช่ความชั่วร้ายในตัวเอง ทั้งคู่เป็นเครื่องมือที่มี trade-off และถูกผูกเข้ากับ trade-off ตามบริบทที่ต่างกันของแต่ละองค์กร
ปัญหาคือวิศวกรหลงใหลในความซับซ้อน สับสนระหว่าง “ความเรียบง่าย” กับ “ทางแก้ชั่วคราว” และองค์กรลอกเลียนเครื่องมือกับแพตเทิร์นสถาปัตยกรรมอย่างมืดบอด
การเชื่อว่าพอใช้สถาปัตยกรรมหรือ design pattern แล้วจะได้ประโยชน์โดยอัตโนมัติ แล้วนำไปใช้อย่างไร้เดียงสา มันไม่ได้ทำให้สิ่งนั้นเกิดขึ้น
ผมพยายามย้ำกับตัวเองว่า software engineering คือการต่อสู้กับความซับซ้อนอย่างไม่รู้จบ ซึ่งก็มีทั้งครั้งที่สำเร็จและล้มเหลว
การต่อสู้นี้ต้องทำเสมอและต้องเป็นคุณค่าสูงสุด ไม่อย่างนั้นเรื่องแบบนี้จะเกิดขึ้น
ไม่มีสถาปัตยกรรมหรืออุดมการณ์ไหนที่จะยุติสงครามนี้ให้ได้ มันเป็นแก่นแท้ของอาชีพนี้
ในสภาพแวดล้อมโปรดักชัน เราไม่ให้เปิด release flag พวกนี้ได้ และนักพัฒนาต้องลบโค้ด flag ออกก่อนการทดสอบขั้นสุดท้ายและก่อนรีลีส
มันเพิ่มงานเล็กน้อยให้กับแต่ละฟีเจอร์ที่ต้องใช้ flag แต่พอผ่านไปไม่กี่เดือน ผลตอบแทนจากการลดความซับซ้อนของโค้ดเบสกลับมาชัดเจนมาก
ไมโครเซอร์วิสไม่ใช่วิธีแก้ปัญหาทางเทคนิค แต่เป็นวิธีแก้ปัญหาทางสังคม
ทีมที่มีวิศวกร N คนต้องการการประสานงานระดับ N² ทีมใหญ่จะจมอยู่กับการประชุม อีเมล และการรีวิวแบบออกแบบไม่รู้จบ ส่วนทีมเล็กทำงานได้มีประสิทธิภาพกว่า แต่ลำบากในการดูแลระบบขนาดใหญ่
การแบ่งระบบออกเป็นระบบย่อยช่วยให้แต่ละทีมโฟกัสกับชิ้นส่วนปริศนาของตัวเอง และลดการประสานงานระหว่างคนลงได้
จริงอยู่ว่าไมโครเซอร์วิสเพิ่มความซับซ้อนและโอเวอร์เฮด แต่แนวทางนี้ทำให้องค์กรขนาดใหญ่สร้างและปรับปรุงระบบขนาดใหญ่ได้อย่างรวดเร็ว
ตอนนี้แทนที่จะเชื่อมต่อกันโดยตรง กลับต้องมีการประชุมแบบ “cross-functional” ระหว่างทีมและเลเยอร์การสื่อสารที่ซับซ้อน
ถ้าคุณพบการแยกส่วนที่แทบไม่ต้องมีการเชื่อมโยงระหว่างระบบย่อย ความเชื่อมโยงนั้นก็คงไม่มีอยู่ในระบบเดิมตั้งแต่แรก และปัญหา N² ก็จะไม่มีด้วย
สิ่งที่เห็นซ้ำ ๆ คือทีมยักษ์ทีมเดียวที่ “ทุกคนรับผิดชอบทุกไมโครเซอร์วิส” และสุดท้ายก็กลายเป็นว่าไม่มีใครรับผิดชอบอะไรเลย
พยายามจะแก้ “ปัญหาคน” แต่กลับเปลี่ยนปัญหาเทคนิคเล็ก ๆ น้อย ๆ ให้กลายเป็นปัญหาระบบกระจายที่ซับซ้อน
ทีนี้ปัญหาจริงก็เกิดขึ้นแล้ว
รองรับฐานข้อมูลสองประเภท และยังมีตัวรันงานที่ขยายแนวนอนได้ด้วย
ครั้งหนึ่งเคยมี 35 คน แต่เพราะการเลย์ออฟเหลือ 7 คน และตอนนั้นกลับเริ่มทำงานได้มากขึ้นมาก เพราะเวลาที่ใช้ในการจัดให้ทุกคนลงตัวลดลงอย่างมาก
การประชุม การอนุมัติ การรีวิว การวางแผน การ retrospective และการประชุมฝ่ายบริหารลดลงมาก ดุลยพินิจของนักพัฒนาก็มากขึ้น จึงแค่ลงมือทำงานให้เสร็จ
ฟีเจอร์ทำเสร็จได้ง่าย ๆ ด้วยเวลาครึ่งเดียว และใช้อีก 50% ที่เหลือไปชำระหนี้ทางเทคนิค เพราะลดความซับซ้อนอย่างไม่ปรานี ความเร็วในการเพิ่มฟีเจอร์ใหม่จึงเพิ่มขึ้นด้วย
บางโปรเจกต์อาจต้องใช้คนมากกว่านั้น แต่ผมคิดว่าความซับซ้อนที่สามารถเพิ่มเข้าไปในระบบภายในช่วงเวลาหนึ่งมีเพดานอยู่
ถ้าเพิ่มนักพัฒนาเกินจุดวิกฤต จำนวนฟีเจอร์ต่อสัปดาห์จะเท่าเดิม แต่ทุกคนทำงานน้อยลงนิดหน่อยและใช้เวลากับการสื่อสารมากขึ้น
ทำกระบวนการนี้ซ้ำไปจนถึงระดับหลายพันคน การเพิ่มฟิลด์เดียวก็จะใช้เวลาหลายเดือน
สงสัยว่าเคยคิดวิธีย้ายไปคนละโฟลเดอร์กันบ้างไหม
ไม่จำเป็นต้องทำให้เป็นโมดูลด้วย repo ใหม่ การตั้งค่า Docker ใหม่ แค่ใช้โฟลเดอร์ก็พอ
รูปแบบที่เห็นบ่อยคือแบบนี้ CTO หรือ VP คนปัจจุบันเป็นคนสร้างโมโนลิธเดิม หรือมีส่วนร่วมในการสร้างมัน
ไม่มีใครอยากบอก CTO ว่าโค้ดนั้นแย่มาก หรือไม่ก็เป็นแค่โค้ดที่ถึงยุคสมัยเปลี่ยนไปจนต้องยกเครื่องใหม่ทั้งหมด ซึ่งไม่เกี่ยวกับข้อเท็จจริงที่ว่ามันเป็นโมโนลิธ
CTO ยุ่งกับการตลาดหรือการระดมทุนจนตัดสินใจไม่ได้ว่าจะใช้ไมโครเซอร์วิสหรือโมโนลิธ สถาปนิกที่เพิ่งจ้างเข้ามาจึงเป็นคนตัดสินใจ
ทุกคนเชียร์ไมโครเซอร์วิส เพราะมันเข้ากับเรื่องเล่าของบริษัทเทคโนโลยีจริงจังที่กำลังเติบโตอย่างรวดเร็ว และไม่มีใครอยากเป็นคนค้านคนเดียวหรือวิจารณ์ CTO
แทบไม่มีกรณีที่แนะนำไมโครเซอร์วิสเพราะเชื่อจริง ๆ ว่าเป็น trade-off ที่ดีที่สุด แต่เพราะคนชอบงานของตัวเอง ชอบจ้างคนเพิ่ม และมันเข้ากับเรื่องเล่าของบริษัทได้ดี
ระหว่างการยกเครื่องใหญ่ สามารถเขียนโค้ดจำนวนมากใหม่และปรับปรุงได้ แล้วก็แค่เรียกสิ่งนั้นว่าการย้ายไปไมโครเซอร์วิส
สุดท้ายมันจึงกลายเป็นวิธีเขียนโค้ดเก่าแย่ ๆ จำนวนมากขึ้นใหม่ โดยไม่ทำร้ายความรู้สึกของ CTO เดินตามฝูงชน และอ้างเหตุผลที่แทบทุกคนสนับสนุน
ไม่ว่าจะเป็น lead engineer รายบุคคล หรือ CTO/ผู้ก่อตั้ง สุดท้ายเมื่อมองย้อนกลับไปก็จะสรุปได้ว่าทำได้ดีกว่านี้ และจะได้เห็นทั้งข้อดีและข้อเสียของแพตเทิร์นและกระบวนการที่ทีมทำตามมาอย่างซื่อสัตย์ ทั้งด้วยความดีใจและความหวาดกลัว
ชอบเป็นพิเศษเพราะเป็นบทความที่ช่วยยืนยันอคติของผม
ผมพูดมาหลายปีแล้วว่า กระแสคลั่งไมโครเซอร์วิส นั้นใกล้เคียงกับข้ออ้างให้วิศวกรธรรมดา ๆ รักษาดีมานด์ของตัวเองไว้มากกว่า ความธรรมดานี่แหละที่คอยเติมเชื้อให้มัน และในขณะเดียวกันก็ทำให้บริษัทเทคโนโลยีจำนวนมากยังเดินหน้าต่อไปได้
วิศวกรที่มีความสามารถพอจะใช้ UNIX ได้อย่างถูกต้อง และสร้างระบบมินิมอลที่งดงามอย่าง StackOverflow ได้นั้นมีไม่พอ
ดังนั้นไมโครเซอร์วิสในฐานะฉากควันบังความธรรมดาจะยังคงอยู่ต่อไป ยิ่งไปกว่านั้นเพราะผู้ให้บริการคลาวด์อย่าง AWS โปรโมตตัวเองผ่านทุกช่องทางที่เป็นไปได้ และทำให้ผู้มีอำนาจตัดสินใจเลือกเส้นทางนั้น
ถ้าไม่พูดถึงคลาวด์ ไมโครเซอร์วิส หรือเฟรมเวิร์กล่าสุดที่ยังไม่ได้พิสูจน์ ก็จะถูกมองว่าเป็นคนแก่ตกยุค
ทั้งที่ระบบแบบนั้นแทบไม่ค่อยเป็นตัวเลือกที่มีประสิทธิภาพที่สุด ทรงพลังที่สุด หรือปลอดภัยที่สุดเลย
บริษัทที่ผมอยู่ตอนนี้ทำซอฟต์แวร์สำหรับใช้ภายในบริษัทอื่น ๆ มีผู้ใช้พร้อมกันมากสุดก็ 200 คน และไม่มีการพุ่งขึ้นของปริมาณการใช้งาน
มันเป็นสภาพแวดล้อมที่เหมาะสุด ๆ สำหรับเว็บเซิร์ฟเวอร์ธรรมดา และไม่น่ามีปัญหาการสเกลแบบไม่คาดคิด แต่ทุกคนก็อยากย้ายไปคลาวด์
ผมมองว่าเหตุผลคือผู้บริหาร โปรแกรมเมอร์ และแม้แต่ลูกค้าต่างก็ถูก การตลาดคลาวด์ โน้มน้าวจนเชื่อว่าคลาวด์นั้นเท่
บริษัทไม่ได้ส่งออกแค่ผังองค์กร แต่ยังส่งความผิดปกติในการทำงานและภาระทางประวัติศาสตร์ทั้งหมดลงไปในผลิตภัณฑ์ด้วย
เมื่อ 5 ปีก่อนมันอาจเป็นแพลตฟอร์มที่สวยงาม มีโมเดลข้อมูลและ API ที่มีประสิทธิภาพและออกแบบดี มีโค้ดที่เขียนดีและผ่านการทดสอบ แต่หลังจาก CEO เปลี่ยนทิศทางซ้ำแล้วซ้ำเล่า คำขอลูกค้าในนาทีสุดท้ายที่ทีมขายดันเข้ามา ผู้จัดการผลิตภัณฑ์เพิ่มฟีเจอร์ที่ไม่ได้จำเป็นและไม่มีใครขอ รวมถึงกำลังคนและเวลาที่ไม่พอ ผ่านไป 5 ปีมันก็อาจกลายเป็นความเละเทะโดยสิ้นเชิงได้
วันหนึ่งคุณจะพบว่าตัวเองยืนอยู่หน้ากอง หนี้ทางเทคนิค มหึมา การแก้บั๊กและเพิ่มฟีเจอร์ใช้เวลานานเกินจำเป็น และไมโครเซอร์วิสก็ฟังดูเหมือนเสียงเพลงไซเรนที่กระซิบบอกว่าไม่ต้องเผาทุกอย่างทิ้งแล้วเริ่มใหม่ตั้งแต่ศูนย์ก็ได้
อาจดูเหมือนจับผิดเล็ก ๆ น้อย ๆ แต่มีประเด็นใหญ่กว่านั้นคือ การเลือกเทคโนโลยีแทบไม่ค่อยเป็นคอขวด
ในทางกลับกัน ไมโครเซอร์วิสซับซ้อนกว่ามาก เพราะมีชิ้นส่วนที่เคลื่อนไหวและโหมดความล้มเหลวมากกว่า ดังนั้นวิศวกรธรรมดา รวมถึงวิศวกรเก่ง ๆ จำนวนมากด้วย จึงมีโอกาสสร้างปัญหาได้มากกว่าเยอะ
ดูเหมือนว่าเราล้มเหลวในการสอนคนรุ่นปัจจุบันอย่างถูกต้องว่าอะไรสำคัญในงานนี้
เห็นด้วย เพราะทีมเล็ก ๆ ของผมกำลังย้ายไปไมโครเซอร์วิส ปัญหาใหญ่ที่สุดคือ observability
เวลามีปัญหาในการปฏิบัติการ การหาว่าอะไรกันแน่ที่ผิดพลาดกลายเป็นงานจุกจิกมหาศาล
แค่ไล่ดูล็อกของแอปพลิเคชันแบบกระจายตัวตัวเดียวไม่พอ ต้องดูล็อกของหลายแอปพลิเคชันแบบกระจายตัวพร้อมกัน โดยที่ข้อความของแต่ละตัวปะปนกันไปมา
ถ้ามีเครื่องมือช่วยแสดง trace เป็นภาพก็คงโอเค แต่เราเป็นทีมเล็ก แบนด์วิดท์ของคนมีจำกัด และยังไม่มีเครื่องมือแบบนั้น
ตรงกันข้าม โมโนลิธมี NewRelic ผสานอยู่แล้วตั้งแต่หลายปีก่อน มีปัญหาเรื่องประสิทธิภาพบ้าง แต่ส่วนใหญ่แก้ได้ด้วยอินเด็กซ์และ materialized view ไม่กี่ตัว
การหาว่าอะไรผิดพลาดนั้นง่าย และแม้โค้ดจะเก่าและเต็มไปด้วย race condition การแก้ปัญหาเองก็ไม่ยาก
ผมกลัวเวลาที่แต่ละไมโครเซอร์วิสมีอินสแตนซ์ฐานข้อมูลแยกกัน แล้วภายหลังต้องอัปเกรด อยากให้ใช้ฐานข้อมูลหลายตัวบนอินสแตนซ์ฐานข้อมูลเดียว แต่สถาปัตยกรรมนั้นไม่อยู่ในตัวเลือก
การทำ centralized logging และการติดตามการเรียก service/การรันโค้ดไม่ใช่เรื่องใหม่ เพียงแต่มักถูกผัดไปเป็นเรื่องทีหลัง จนตกอยู่ในสถานการณ์ไม่น่าพอใจแบบนี้
เพราะไม่ได้ใส่เครื่องมือที่ถูกต้องตั้งแต่แรก ทีมจึงเล็กลงและถูกจำกัดมากขึ้น เพราะแทบไม่รู้หรือไม่รู้เลยว่า service ต่าง ๆ กำลังทำอะไร
อินสแตนซ์ฐานข้อมูลก็อัปเกรดทีละตัวได้ ถ้าไม่ใช่บั๊กร้ายแรงอย่างด้านความปลอดภัย ก็ไม่จำเป็นต้องรีบเพียงเพราะมันอัปเกรดได้
เวลาอ่านบทความแบบนี้แล้วรู้สึกเหมือนได้รับการเยียวยาอย่างประหลาด เพราะเมื่อ 10 ปีก่อนผมก็ตะโกนเรื่องเดียวกันนี้ดัง ๆ แต่ถูกมองว่าเป็นคนนอกรีตและถูกบอกให้เงียบ
ขออภัยที่พาราไดม์ “ไมโครเซอร์วิส” ทิ้งรสขมไว้ในปากผม ผมเคยเจอกับตัวจริง ๆ ว่าจะเกิดอะไรขึ้นเมื่อรับเทคโนโลยีกระแสล่าสุดมาใช้เต็มตัวโดยไม่เข้าใจ trade-off ของมันอย่างถ่องแท้
นานมาแล้วตอนผมเข้าทำงานที่ StumbleUpon เป็นช่วงที่คนซึ่งถูกมองว่าเป็นดอกเตอร์คอมพิวเตอร์ไซเอนซ์ชั้นนำ กำลังพยายามเปลี่ยน PHP โมโนลิธที่ทำงานได้ดีและทำเงินได้อยู่ ให้กลายเป็น สถาปัตยกรรมไมโครเซอร์วิส บน Scala/Java
ขั้นตอน onboarding พนักงานใหม่ยังมี 1:1 แปลก ๆ กับนักวิทยาการคอมพิวเตอร์บ้าคนนั้นด้วย เขาสาธยายข้อดีของไมโครเซอร์วิสอย่างเร่าร้อน และหลบคำถามอย่าง “ทำไมต้องสร้างบริการแบบกระจายตัวเพื่อบวกรายการตัวเลขเฉย ๆ ด้วยครับ?” ได้อย่างคล่องแคล่วด้วยการโบกมือทำนองว่า “นายไม่มีทางเข้าใจหรอกว่าทำไมมันดีกว่ามาก”
หลังจากจ้างคนใหม่กว่า 30 คน และพัฒนาอย่างเข้มข้นกว่า 4 ปี สิ่งที่เหลือให้บริษัทซึ่งไม่ทำเงินอีกต่อไปคือ นรกแบบกระจายตัว ที่ช้ากว่า เต็มไปด้วยบั๊ก และดีบักไม่ได้
ผู้ออกแบบและสถาปนิกหลักเห็นว่าตอนนั้นเป็นช่วงเหมาะจะไป “sabbatical” และไม่นานหลังจากนั้น เงินลงทุนรอบที่เท่าไรก็ไม่รู้อีกก้อนก็หมดลง ทุกคนจึงต้องไปหางานใหม่
ถ้ายืมอุปมาเรื่อง Amtrak มาใช้ บทความนี้ก็ถือว่าตกรางไปโดยสิ้นเชิง
ผู้เขียนตั้งสมมติฐานว่า ถ้าคุณสร้างไมโครเซอร์วิสที่ห่วย แค่สร้างเป็นโมโนลิธก็จะดีขึ้นอย่างมหัศจรรย์
เหมือนกับว่าต่อให้สร้างไมโครเซอร์วิสขยะ ๆ ด้วยการออกแบบและวิศวกรรมระดับเดียวกัน แต่ถ้าเป้าหมายเป็นโมโนลิธ ผลลัพธ์ก็จะออกมาทองอร่าม
ระหว่างบทความก็มีความพึงพอใจในตัวเองอยู่มาก ความเห็นเกี่ยวกับนักพัฒนา JS แบบฟูลสแตกเป็นตัวอย่างหนึ่ง
แต่เนื้อหาในมุมวิศวกรรมจริง ๆ แทบไม่มีเลย ต่อให้คาดหวังตัวชี้วัดหรือข้อมูล สิ่งที่ได้กลับมาก็มีแต่คำพร่ำยืดยาว
การจัดการความซับซ้อนเพื่อให้ต้นทุนการเปลี่ยนแปลงระบบต่ำอยู่เสมอเป็นเป้าหมายที่ดี แต่สิ่งที่บทความนี้เสนอไม่ใช่แบบนั้น
ถ้ายอมรับประเด็นนี้ หรือยกข้อมูล หรืออย่างน้อยก็เกร็ดประสบการณ์สักเรื่อง บทความคงจะดีกว่านี้
ถ้าเป็นทีมเรา เราจะเลือกนักพัฒนาฟรอนต์เอนด์ที่สดใสและมีไฟ อยากเปิดมุมมองให้กว้างขึ้นและเติบโตเป็น นักพัฒนาฟูลสแตก มากกว่าคนที่เชื่อว่าตัวเองรู้ทุกอย่างแล้วและไม่มีอะไรให้เติบโตอีก
ที่ทำงานปัจจุบันกำลังสู้กับกระแสนี้อยู่ และบางทีมก็ประสบความสำเร็จพอสมควร แต่บางทีมสำเร็จน้อยกว่ามาก ตอนนี้ทีมเหล่านั้นกำลังสู้กับ โมโนลิธแบบกระจายศูนย์ ที่ตัวเองสร้างขึ้น
ที่น่าขันคืออดีตพนักงาน FAANMG ทุกคนล้วนอยู่ฝั่งสนับสนุนโมโนลิธ
ดูเหมือนหลายคนจะพลาดประเด็นว่าไมโครเซอร์วิสเป็นผลลัพธ์ของกระบวนการแบบวนซ้ำ สุดท้ายคือการแยกส่วนที่จำเป็นต้องสเกลออกจากโมโนลิธ
ไมโครเซอร์วิสต้องการโครงสร้างพื้นฐานพื้นฐานจำนวนมากที่คุณคงไม่อยากดูแลถ้าไม่จำเป็นจริง ๆ
บริษัทส่วนใหญ่ก็ไม่มีแพลตฟอร์มที่เหมาะสมเพื่อรองรับรูปแบบนั้นด้วย
เห็นด้วย ที่บริษัทเรา เครื่องมือทำงานไม่ถูกต้องจนอยู่ในสภาพที่ยอมแพ้กับ การดีบัก ไปแล้ว
ถ้าจะรันบริการหนึ่งบนเครื่องโลคัล ก็ต้องปรับให้อีก 9 บริการที่เหลือเชื่อมกับบริการนี้ให้ได้
ถ้าถึงขั้นสร้าง “ฟีเจอร์” ให้ลูกค้า แน่นอนว่าต้องแตะอย่างน้อย 2 บริการพร้อมกัน เพื่อย้ายข้อมูลให้มากขึ้น
ถ้าตั้งเบรกพอยต์ไว้ฝั่งหนึ่ง อีกฝั่งก็จะ timeout
ดังนั้นนักพัฒนาทุกคนจึง deploy release build ลง VM โลคัล แล้วฝัง console.log, System.PrintLines(), _logger โดยไม่มี hot reload จากนั้นก็อ่านไฟล์ log ที่กระจัดกระจาย
แน่นอนว่าฉันเตรียมจะกระโดดลงจากเรือลำนี้แล้ว
ถ้าย้ายทั้งหมดไปเป็น distributed tracing ได้ก็ยิ่งดี แต่การติดตาม request ให้ถูกต้องต้องทำให้ metadata สำหรับ tracing เป็นมาตรฐานเดียวกันทั่วทั้งระบบ จึงต้องลงทุนมากกว่า
มีโอกาสจะช่วยงาน operation มากกว่างานพัฒนา แต่ก็ยังน่าจะช่วยได้อยู่ดี แค่มีข้อมูลช่วงการทำงานที่ถูกต้องก็ให้ insight ได้มากในการทำความเข้าใจความยุ่งเหยิงนี้
ถ้าเบรกพอยต์ฝั่งหนึ่งทำให้อีกฝั่ง timeout ก็สงสัยว่าในโหมดพัฒนามีวิธีเพิ่มหรือปิด timeout ได้ไหม