Slow CORS OPTIONS preflight by long stalling in Chrome
ตอนบ่ายฟ้าครึ้ม ดูแล้วอีกไม่นานฝนน่าจะตก ผมนั่งอยู่ในร้านกาแฟแถวบ้าน สองจิตสองใจระหว่างปิดโน้ตบุ๊คแล้วกลับบ้าน หรือดื่มด่ำบรรยากาศในร้านต่อไป วันนี้มีฟรีแลนซ์มานั่งทำงานประปราย เสียงโทรคุยกับลูกค้าช่วยให้ร้านไม่รู้สึกเงียบเกินไป โต๊ะข้าง ๆ เป็นหนุ่ม(เหลือ)น้อยวัยเกษียณใส่หูฟังดูคลิปจากแท็บเล็ตเงียบ ๆ เขาก็คงเหมือนผมที่ชอบสันโดษท่ามกลางผู้คน
วันนี้ไม่เร่งรีบ เป็นเวลาแห่งการรอปฏิกิริยาจากผู้ใช้ หลังจากที่วันก่อนปรับคอนฟิกโปรแกรม สืบเนื่องจากพบเจออาการสะดุดค้างบางจังหวะ มีเพียงผู้ที่ใช้โปรแกรมทุกวันจึงบอกได้ว่าโปรแกรมไม่ปกติ เหมือนคนขับรถทุกวันบอกได้ว่าเสียงเครื่องไม่เหมือนเดิม
พอย่างเข้าวัยชรา ผมนึกถึงคำบอกเล่าอย่าละเลยสัญญาณเตือนของร่างกาย หากเจ็บอกแปล๊บ หรือปวดหัวจี๊ด ก็ต้องหยุดสังเกต ใส่ใจรับรู้ว่าบ่อยแค่ไหน ทบทวนการใช้ชีวิตของตัวเอง นอนอย่างไร กินอย่างไร ทำอะไรที่ฝืนสังขารหรือเปล่า
เมื่อวานนี้ทีมของเราช่วยกันหาสาเหตุเล็ก ๆ นี้ ย้อนหลังไปสัปดาห์ที่แล้วมีรายงานผู้ใช้อย่างน้อยสองรายที่น่าจะเกี่ยวข้องพ้องกัน เพียงแต่ตอนนั้นเข้าใจว่าเป็นเหตุชั่วคราว เกิดจากระบบอินเตอร์เน็ตไม่เสถียร หรือเป็นจังหวะที่มีผู้ใช้ปริมาณมาก เพราะไม่มีใครแจ้งเพิ่มเติมมาจนมีนัยยะสำคัญ จนกระทั่งไม่กี่วันนี้ ผู้ใช้ท่านหนึ่งส่งคลิปมาใหม่ ชี้ให้เห็นจังหวะที่โปรแกรมช้า เมื่อเราทดลองทำตาม จึงยืนยันได้ว่ามีอะไรบางอย่างผิดปกติจริง
ในโลกอินเตอร์เน็ต อาการช้าอาจเกิดจากความผิดปกติจุดใดจุดหนึ่งของห่วงโซ่บนคลาวด์ที่เชื่อมต่อกันก็ได้ การสืบหาสาเหตุของปัญหาต้องเริ่มจากความเข้าใจความสัมพันธ์ขององค์ประกอบต่าง ๆ ในระดับที่ลึกพอ แล้วช่วยกันกันตัดข้อสมมติฐานที่ไม่ใช่ออกไป
ไม่ได้เป็นปัญหาเฉพาะเครื่องคอมพิวเตอร์ใดเครื่องหนึ่ง หลังจากทดสอบกับหลายเครื่องที่แตกต่างกัน ใช้ OS (Windows) version แตกต่างกัน ก็ยังพบอาการเหมือนกันได้
ไม่ได้เป็นที่ระบบเน็ตเวิร์คในพื้นที่นั้น โดยการทดสอบเรียกโปรแกรมจากหลายสถานที่ทั้งกรุงเทพฯ และต่างจังหวัด ผ่านผู้ให้บริการอินเตอร์เน็ตที่แตกต่างกัน
ข้อสงสัยที่ยังไม่แน่ใจอยู่ที่ผู้ใช้รายอื่นไม่แจ้ง เพราะไม่เจออาการนี้ หรือเพราะไม่รู้สึกว่าเป็นปัญหา ผมจึงให้ทดสอบโปรแกรมที่ใช้กับไซต์อื่นที่ไม่ได้แจ้ง แล้วก็พบว่ามีอาการเหมือนกัน
เมื่อทดลองเปลี่ยนเบราเซอร์ ในที่สุดก็พบว่าปัญหานี้ เกิดขึ้นเฉพาะ Chrome เท่านั้น กับ Firefox ไม่เกิดอาการนี้ ได้มาหนึ่งเงื่อนงำสำคัญ
ขีดวงล้อมปัญหาจนแคบลงมา อาจจะเป็นความผิดปกติของตัวโปรแกรม (หรือสภาพแวดล้อม) ที่ไม่เข้ากับ Chrome ค่อย ๆ ไล่ตรวจสอบว่าช่วงเวลาที่ผ่านมามีการอัพเดทอะไรไปบ้างแล้วเกิดปัญหา (ก่อนหน้านั้นเคยอัพเดท Traefix reverse proxy เป็น version ใหม่แล้วมีปัญหา breaking change) หรือโชคร้ายยังไม่ทันแพทช์แล้วโดนโจมตีอะไรหรือเปล่า (ก่อนหน้านั้นเคยโดน Ahrefs bot ที่เป็น web crawler รบกวน)
ใน network console ของ Chrome Devtools พบว่ามี connection อยู่รายการหนึ่งที่ใช้เวลานานผิดปกติ เป็น preflight OPTIONS ที่เส้นเวลายืดยาวออกมาเห็นได้ชัด
ได้คีย์เวิร์ดของปัญหาที่ชัดเจนมากขึ้น ผมเลือกใช้คำค้น “Chrome slow preflight” เพื่อหาว่า มีใครเคยเจอเคสคล้ายกันนี้บ้างไหม? หากคนอื่นเจอเหมือนกันแสดงว่าโปรแกรมของเราไม่ใช่จำเลยที่หนึ่ง อันดับต่อไปก็ดูว่ามีวิธีแก้ไขอย่างไร? บางทีเครื่องมืออย่าง Google Search และ Stack Overflow ยังมีประโยชน์สำหรับการรวบรวมวิธีแก้ปัญหาจากความเวิ้งว้าง มากกว่าถาม AI
คำตอบที่ได้มีทั้งเคส bug เก่าหลายปีจนถึงปีที่แล้ว ยังไม่เจอเคสปัจจุบัน ประเด็นที่น่าสงสัย่ว่าจะเกี่ยวข้องอยู่ตรงที่การปรับปรุง Chrome security เรื่อง Private Network Access ซึ่งเกินความสามารถที่จะทำความเข้าใจ (อ่านแล้วไม่รู้เรื่อง)
โดยส่วนตัวมีความเห็นว่าไม่น่าเกี่ยวข้องโดยตรงกับเคสของเรา เพราะเซิร์ฟเวอร์ที่ติดต่อจากเบราเซอร์เป็น Public ไม่ใช่ Private Network (ตามความเข้าใจของผม) ยกเว้นจะมีอะไรผิดพลาดสักอย่าง ผมเอนเอียงเชื่อว่าผู้ต้องสงสัยคือ Chrome เพราะเคยมีประวัติแก้ bug ตรงนี้มาหลายรอบ
พฤติกรรมแปลกของ Chrome ที่น่าสังเกตอยู่ที่ waterfall chart ใน devtools ลำดับของ connection ที่เกิดขึ้น จะเห็นว่าไม่มีอะไรค้างอยู่ใน queue ที่จะ block แล้ว แต่ preflight ก็ยังเว้นช่วงรอนานถึง 4 วินาที จึงเริ่มทำการติดต่อหาเซิร์ฟเวอร์ และจุดนี้เองเป็นต้นตอที่ทำให้ผู้ใช้รู้สึกว่าโปรแกรมช้า
เมื่อขยายเข้าไปดู timing breakdown พบว่าสาเหตุที่ช้าอยู่ที่ขั้นตอน stalled ซึ่งเป็นการรออะไรซักอย่าง ไม่ใช่ปัญหา DNS lookup จังไม่น่าเกี่ยวกับ localhost และ resolve IP address ที่เป็นเคสเก่า มีคำอธิบายเกี่ยวกับขั้นตอน Stalled ผมแนบ link อ้างอิงไว้ด้านล่าง แต่ก็ไม่ช่วยอะไรมาก
มีข้อสังเกตต่อไป ในชุด connection นั้น มี preflight OPTIONS ที่ติดต่อไปหาเซิร์ฟเวอร์อื่นด้วย แต่กลับไม่มีอาการค้างรอนาน ดูเหมือนว่าจะมีปัญหาเฉพาะบางเซิร์ฟเวอร์เท่านั้น
ถึงแม้ว่าจะรู้จุดที่เกิดปัญหาแล้ว แต่ก็เกินจากความสามารถที่จะทำความเข้าใจว่าเพราะอะไร และไม่ทราบวิธีแก้ปัญหาที่อธิบายหลักการได้ชัด ๆ เหลือกระบวนท่าสุดท้ายใช้วิชามวยวัดโดยปรับคอนฟิกโปรแกรมลองเปลี่ยนเซิร์ฟเวอร์เอาดื้อๆ
ข่าวดี ล่าสุดผู้ใช้บอกว่า “โปรแกรมใช้งานได้ปกติแล้วค่ะ” โอเค อย่างน้อยปัญหาก็ถูกแก้ไขในการรับรู้ของผู้ใช้
ฝนลงเม็ดแล้ว ผมนึกถึงเพลงฝนเอยทำไมจึงตก ฝนตกเพราะกบมันร้อง กบร้องเพราะปวดท้อง ปวดท้องเพราะกินข้าวดิบ ข้าวดิบเพราะฟืนเปียก ฟืนเปียกเพราะฝนตก ปัญหาในโลกของคลาวด์บางเรื่องเมื่อไล่ไปเรื่อย ๆ ก็ไม่รู้ว่าจะสิ้นสุดที่ใด เพราะสัมพันธ์กับปัจจัยมากมายเกินกว่าที่จะเข้าใจทั้งหมด บางทีการหลบเลี่ยงออกมาก่อน อาจเป็นทางเลือกที่ดีกว่าก็ได้
อ้างอิง
- Chrome Private Network Access Update
https://developer.chrome.com/blog/private-network-access-update/ - Chrome Devtools Timing Explaination
https://developer.chrome.com/docs/devtools/network/reference/?utm_source=devtools#timing-explanation - Super slow preflight OPTIONS in Chrome only
https://stackoverflow.com/q/46218440