เริ่มเบราว์เซอร์ใน Firecracker VM บน EC2 ได้ภายในไม่ถึง 1 วินาที
(browser-use.com)- Browser Use Cloud ใช้ Firecracker VM แยกต่อหนึ่งเซสชันเบราว์เซอร์ พร้อมลดเวลาเริ่มเซสชันใหม่ให้ต่ำกว่า 1 วินาที และลดต้นทุนจาก $0.06 ต่อชั่วโมงเบราว์เซอร์เหลือ $0.02
- สถาปัตยกรรมเดิมที่ใช้ Unikraft เหมาะกับต้นทุนขณะ idle แต่เมื่อทราฟฟิกพุ่งต้องให้คนมาปรับขนาดความจุเอง ทำให้ระหว่างการทดสอบโหลด โปรดักชัน ล่มนาน 45 นาที
- สถาปัตยกรรมใหม่มี control plane ของตัวเอง คอยเฝ้าดูฝูงเบราว์เซอร์แบบเรียลไทม์ เพื่อตัดสินใจเรื่องการจัดวางโฮสต์ EC2, การขยายระบบ และการระบายเครื่อง ได้ละเอียดกว่า CloudWatch
- แทนที่จะใช้
.metalได้เลือกใช้ nested virtualization โดยรัน Firecracker บน EC2 ปกติ แล้วลดคอขวดด้วยหน้าเมมโมรี 2MB,userfaultfd, การตรึง vCPU, real-time priority และการแพตช์ headless Chromium - VM cold start ต่ำกว่า 400ms และในการทดสอบแบบ stress test 10,000 เซสชัน ค่าหน่วงในการสร้างเบราว์เซอร์ตาม API สาธารณะอยู่ที่ p50 825ms และ p99 1.35 วินาที โดยเบราว์เซอร์ทั้งหมดเริ่มทำงานสำเร็จ
คลาวด์เบราว์เซอร์ที่เร็ว แยกขาด และประหยัด
- เป้าหมายของ Browser Use Cloud คือทำให้เบราว์เซอร์ เริ่มได้เร็ว พร้อมแยกสถานะระหว่างเซสชัน และลดต้นทุน
- หนึ่งเซสชันประกอบด้วย Chromium, ระบบไฟล์, คุกกี้, แคช, การตั้งค่า proxy, ไฟล์ดาวน์โหลด และบางครั้งรวมถึงเซสชันลูกค้าที่ล็อกอินอยู่
- ถ้าเบราว์เซอร์หนึ่งอ่านสถานะของอีกเบราว์เซอร์ได้ จะกลายเป็นปัญหาด้านความปลอดภัย ดังนั้นแต่ละเซสชันต้องถูกแยกออกจากโฮสต์และจากเซสชันอื่น
- วิธีแก้ทั่วไปคือใช้ VM ที่มี CPU, หน่วยความจำ, ดิสก์ และอุปกรณ์เครือข่ายของตัวเอง แต่สำหรับสภาพแวดล้อมคลาวด์เบราว์เซอร์ที่ต้องสร้างแล้วทิ้งเมื่อเซสชันจบ วิธีนี้หนักและแพงเกินไป
- สถาปัตยกรรมใหม่รันทุกเซสชันของ Browser Use Cloud ใน Firecracker VM ขนาดเล็ก หนึ่งตัว และรัน VM เหล่านี้บน Amazon EC2
เหตุผลที่เลิกใช้ Unikraft
- สถาปัตยกรรมก่อนหน้านี้รันคลาวด์เบราว์เซอร์ด้วย Unikraft
- Unikraft โหลด unikernel ซึ่งเป็นอิมเมจขนาดเล็กที่สร้างมาเฉพาะงาน แทนการบูต Linux ทั้งระบบ
- unikernel เริ่มทำงานได้เร็ว และสามารถปิดลงเมื่อไม่มีผู้ใช้ ทำให้ต้นทุนขณะ idle ต่ำ
- คอขวดคือการเพิ่มความจุของเบราว์เซอร์อย่างรวดเร็วเมื่อทราฟฟิกพุ่ง
- Unikraft ไม่มี autoscaling ในตัวที่ดีพอ
- วิศวกรต้องปรับค่าตัวแปรและเพิ่มอินสแตนซ์ด้วยมือ
- การทดสอบโหลดครั้งหนึ่งทำให้โปรดักชัน ล่มนาน 45 นาที
- หลังจากสร้างใหม่จึงเปลี่ยนมาใช้ Firecracker
- Firecracker มีชั้นสำหรับสร้าง เฝ้าดู และรัน VM
- มอบ CPU, หน่วยความจำ, ดิสก์ และอุปกรณ์เครือข่ายให้แต่ละ VM พร้อมแยกออกจากโฮสต์และ VM อื่น
ทำ autoscaling ของเบราว์เซอร์ด้วย control plane ของตัวเอง
- Firecracker สามารถให้ VM แยกแก่แต่ละเบราว์เซอร์ได้ แต่ไม่ได้ตัดสินใจอัตโนมัติว่าจะมี VM กี่ตัว วางไว้ที่ไหน หรือควรขยายเมื่อใด
- Browser Use จึงสร้าง control plane ของตัวเองเพื่อตรวจดูฝูงเบราว์เซอร์และตัดสินใจ scale up/down
- เมื่อผู้ใช้ร้องขอเบราว์เซอร์ control plane จะเลือกเครื่องที่ยังมีทรัพยากรว่าง
- เมื่อทราฟฟิกเพิ่มก็จะเริ่มเครื่องเพิ่ม และเมื่อทราฟฟิกลดก็จะไม่ส่งเบราว์เซอร์ใหม่ไปยังเครื่องที่กำลังจะถูกถอดออก
- control plane ตรวจดูทั้งฝูงแบบ เรียลไทม์
- CloudWatch ซึ่งเป็นบริการมอนิเตอร์ของ AWS มักตอบสนองในช่วงหน้าต่าง 1 นาที
- control plane รู้ข้อมูลที่ไม่มีในเมตริกทั่วไป เช่น เบราว์เซอร์ที่กำลังเริ่มอยู่ เครื่องที่กำลังถูกถอดออก หรือเครื่องที่ไม่ควรรับเซสชันใหม่
- คำขอจากผู้ใช้จะถูกส่งผ่าน stateless edge router ไปยัง control plane และ control plane จะเลือกโฮสต์ EC2 ที่ยังมีทรัพยากรว่าง
เหตุผลที่รัน Firecracker บน EC2 ปกติ
- วิธีทั่วไปในการรัน Firecracker บน AWS คือใช้อินสแตนซ์
.metal.metalคือโครงสร้างที่เช่าฟิสิคัลเซิร์ฟเวอร์ทั้งเครื่องเพื่อให้ Firecracker รันได้โดยตรง
- Browser Use เลือกใช้ EC2 ปกติ
- จัดหาเครื่อง EC2 ปกติได้เร็วกว่า
- มีต้นทุนการดูแลต่ำกว่า
- โฮสต์บูตจากอิมเมจที่เตรียมไว้ล่วงหน้า และหลังเริ่มทำงานประมาณ 30 วินาที ก็พร้อมให้บริการเบราว์เซอร์
- ยิ่งเพิ่มโฮสต์ได้เร็ว ก็ยิ่งลดความจุสำรองที่ต้องจ่ายเงินไว้ล่วงหน้า และลดต้นทุนที่ต้องส่งต่อให้ลูกค้า
- สิ่งที่ต้องแลกคือโครงสร้างแบบ VM ซ้อนใน VM
- EC2 ปกติเองก็รันอยู่ภายในชั้นแยกของ AWS อยู่แล้ว
- ภายในนั้นยังต้องรันเบราว์เซอร์ VM ซ้ำอีกชั้น
- เมื่อเบราว์เซอร์ VM ขอความช่วยเหลือจากโฮสต์ ต้องผ่าน VM สองชั้น ทำให้เกิด latency เพิ่ม
- Browser Use ยอมรับ trade-off นี้เพื่อให้ scale up ได้เร็วขึ้นและต้นทุนต่ำลง พร้อมโฟกัสกับการเร่งเส้นทางการรัน Firecracker ให้เร็วที่สุด
เส้นทางตั้งแต่คำขอจนถึงเบราว์เซอร์พร้อมใช้งาน
- เมื่อผู้ใช้ร้องขอเบราว์เซอร์ control plane จะเลือกเครื่องที่ยังมีทรัพยากรว่าง
- เครื่องนั้นจะกู้คืน browser VM ที่บันทึกไว้ แล้วเริ่ม Chromium ภายใน VM
- เมื่อ Chromium อยู่ในสถานะที่ควบคุมได้ ระบบจะส่งคืน URL สำหรับเชื่อมต่อ
- เอเจนต์ของผู้ใช้จะเชื่อมต่อผ่าน URL นี้
- Browser Use ควบคุม Chromium ผ่าน Chrome DevTools Protocol(CDP) บน WebSocket
- CDP คือ API สำหรับควบคุม Chrome ระยะไกล เช่น กดปุ่ม ป้อนข้อความ อ่านหน้าเว็บ และจับภาพหน้าจอ
- คอขวดหลักที่สร้าง latency มีอยู่ 3 จุด
- การกู้คืนหน่วยความจำของ VM
- การเริ่ม Chromium
- การคงความ stealth เพื่อไม่ให้ถูกระบบ anti-bot ตรวจจับ
คอขวดแรก: การกู้คืนหน่วยความจำ
- เบราว์เซอร์ในโปรดักชันไม่ได้บูตใหม่จากศูนย์ แต่ resume จาก snapshot
- snapshot คือ VM ที่บูตเสร็จแล้วและถูกหยุดไว้ก่อนเริ่ม Chromium
- การ resume VM เร็วกว่าการบูตใหม่ แต่ในการ cold start ช่วงแรก page fault คิดเป็น 72% ของ VM exit ทั้งหมด
- ช่วงเวลาตั้งแต่ resume VM จนได้เบราว์เซอร์ที่พร้อมใช้ CDP เดิมกินเวลา 9.8 วินาที
- สาเหตุที่ช้าคือเมื่อ VM ที่กู้คืนแล้วแตะหน่วยความจำครั้งแรก โฮสต์ต้องทำการแมปหน่วยความจำนั้นใหม่
- เหตุการณ์นี้เรียกว่า page fault
- ใน VM แบบซ้อน page fault อาจต้องผ่าน VM สองชั้น จึงมีต้นทุนสูง
- วิธีแก้คือแมปหน่วยความจำเป็นก้อนใหญ่ขึ้น
- เดิมกู้คืนด้วยหน้า 4KB
- ตอนนี้ใช้หน้า 2MB
- แต่ละหน้าครอบคลุมหน่วยความจำมากขึ้น 512 เท่า จึงลด page fault อย่างมากระหว่างที่เบราว์เซอร์ตื่นขึ้นมา
- ยังเพิ่ม custom handler ให้กับ
userfaultfdซึ่งเป็น API ของ Linux สำหรับจัดการหน้าเมมโมรีที่หายไป- โหลดหน่วยความจำที่ Chromium น่าจะเข้าถึงก่อนตั้งแต่ก่อน VM เริ่มรัน
- ป้องกัน page fault ถล่มตอนเริ่ม Chromium
- การเปลี่ยนแปลงนี้ลดเวลาจาก resume VM จนถึงเบราว์เซอร์ที่รับคำสั่งได้ จาก 9.8 วินาทีเหลือ 3.1 วินาที
- จำนวนครั้งที่ browser VM ต้องหยุดแล้วร้องขอโฮสต์เพื่อจัดการเมมโมรีที่หายไประหว่างการ resume ลดจากประมาณ 100,000 ครั้งเหลือประมาณ 1,100 ครั้ง หรือลดลงราว 91 เท่า
- การปรับแต่งเล็ก ๆ ก็สะสมผลได้เช่นกัน
- ปิดการตรวจสอบ 500ms ที่เคยเสียเวลาไปกับการหาแป้นพิมพ์ PS/2 รุ่นเก่าที่ไม่มีอยู่จริง
- เปลี่ยนการเช็กสถานะพร้อมจาก HTTP polling เป็นการอ่านล็อกผ่าน
vsock - เมื่อ browser driver เขียนข้อความ ready ลงในล็อก โฮสต์จะอ่านผ่าน
vsockและตรวจพบข้อความ ready ได้ในเวลาไม่ถึง 1ms
คอขวดที่สอง: การเริ่ม Chromium และการจัดวาง CPU
- ตอนเริ่ม Chromium จะมีการสร้าง renderer, compositor และ V8 isolate พร้อมกัน ทำให้ใช้ CPU สูง
- หลังจากเริ่มเสร็จ งาน automation ของเบราว์เซอร์จะค่อนข้างเงียบกว่า
- เอเจนต์จะคลิก รอ อ่าน แล้วค่อยคลิกอีกครั้ง
- เบราว์เซอร์ส่วนใหญ่จึงรอหน้าเว็บ รอการตอบสนองจากเครือข่าย และรอการทำงานถัดไปจากเอเจนต์
- ด้วยลักษณะนี้จึงสามารถ packing เบราว์เซอร์จำนวนมากไว้บนโฮสต์เดียวได้
- การรับมือกับ CPU burst ตอนเริ่มทำเป็นสองช่วง
- ระหว่างที่เบราว์เซอร์ resume และ Chromium กำลังเริ่ม vCPU จะยังไม่ถูก pin ไว้
- Linux จึงสามารถกระจายงาน CPU ของเบราว์เซอร์ไปทั่วทั้งโฮสต์ได้ แทนที่จะผูกไว้กับคอร์ตายตัว
- เมื่อเบราว์เซอร์รายงานว่า ready แล้ว จึงค่อย pin vCPU ไปยังคอร์ที่เสถียร
- ถ้า pin ตั้งแต่ต้น เมื่อหลายเบราว์เซอร์เริ่มพร้อมกันจะไปกองบน hot core เดียวกัน ทำให้บางการเปิดล้มเหลว
- ยังมีการปรับการจัดการ hyperthread ด้วย
- CPU คอร์จริงหนึ่งคอร์มักมองเห็นเป็น logical CPU สองตัวที่เรียกว่า sibling thread
- ถ้า browser VM สองตัวได้ sibling คนละตัว ก็จะต้องแย่งคอร์จริงเดียวกัน
- ในสภาพแวดล้อมแบบซ้อน การแย่งกันนี้แสดงออกมาเป็นการเปิดเบราว์เซอร์ล้มเหลว
- ตอนนี้แต่ละเบราว์เซอร์จะได้ sibling thread ทั้งสองของคอร์จริงที่ใช้งาน
- แต่ละเธรดของ vCPU ที่ถูก pin จะได้รับ real-time priority
- ทำให้ Linux รัน VM ทันที แทนที่จะปล่อยให้รออยู่หลังงานที่สำคัญน้อยกว่า
- ก่อนเปลี่ยนแปลง ในการทดสอบ 1,000 เบราว์เซอร์ มีเซสชันหายไป 17% หลังถูกสร้างไม่นาน
- หลังเปลี่ยนแปลง การทดสอบเดียวกันมีการสูญหาย 0%
stealth browser แบบไม่มีหน้าจอ
- เบราว์เซอร์แบบ headless รันโดยไม่มีหน้าต่างให้เห็น ส่วน headful รันเหมือนเบราว์เซอร์บนโน้ตบุ๊กที่มีหน้าต่าง กราฟิก และเฟรมการเรนเดอร์
- Chromium แบบ headless ธรรมดาถูกตรวจจับได้ง่ายบนเว็บไซต์ที่มีมาตรการ anti-bot
- ตาม stealth benchmark ของ Browser Use, Chromium แบบ headless ธรรมดามีอัตราหลบการบล็อกได้เพียง 2%
- ถ้ารัน Chromium เดียวกันในโหมด headful ที่มีหน้าต่างให้เห็น เพียงแค่ลักษณะการเรนเดอร์ก็ทำให้อัตราหลบการบล็อกเป็น 50%
- นี่คือเหตุผลที่ผู้ให้บริการหลายรายรันเบราว์เซอร์แบบ headful และยอมจ่ายต้นทุนของ display server, GPU และ compositor แม้จะไม่มีใครมองหน้าจอจริง ๆ
- Browser Use เลือกแก้ที่ตัวเบราว์เซอร์เอง เพื่อคงการรันแบบ headless อย่างสมบูรณ์
- องค์ประกอบแรกคือ Chromium fork
- เครื่องมือ stealth จำนวนมากซ่อน automation โดยฉีด JavaScript ลงทุกหน้า หลังจากเบราว์เซอร์เริ่มแล้ว
- ตัวอย่างเช่น เขียนทับค่า
navigator.webdriverเพื่อให้เว็บไซต์เห็นfalseแทนtrue - เว็บไซต์สามารถตรวจจับได้ว่าค่าพวกนี้ถูกเขียนทับ
- Browser Use แพตช์ระดับล่างของ Chromium เพื่อไม่ให้ค่าพวกนี้ถูกเปิดเผยตั้งแต่แรก
- องค์ประกอบที่สองคือ fingerprinting
- browser fingerprint คือชุดข้อมูลของเบราว์เซอร์และเครื่องที่เว็บไซต์อ่านได้
- มีรายละเอียดหลายร้อยอย่าง เช่น ระบบปฏิบัติการ ขนาดหน้าจอ ฟอนต์ เอาต์พุตกราฟิก เสียง เขตเวลา ภาษา เป็นต้น
- Browser Use ใช้ fingerprint จริงหลายหมื่นรายการจาก macOS, Windows และ Linux
- เบราว์เซอร์เหล่านี้ทำคะแนนหลบการบล็อกได้ 81% ใน stealth benchmark และ 84.8% ใน Halluminate BrowserBench
- เพราะไม่มีหน้าจอ ต้นทุนในการรันเบราว์เซอร์จึงต่ำกว่า และขยายระบบได้ง่ายกว่า
การเชื่อมต่อไปยังเบราว์เซอร์ที่ถูกต้อง
- เมื่อเบราว์เซอร์พร้อมแล้ว ผู้ใช้จะเชื่อมต่อผ่าน CDP
- URL สาธารณะคือ WebSocket URL
- ด้านหน้าฝูงเบราว์เซอร์มี edge router แบบเรียบง่ายอยู่หลายตัว
- router จะรับการเชื่อมต่อ WebSocket ไปถาม control plane ว่าเบราว์เซอร์นั้นอยู่ที่ไหน แล้วส่ง raw CDP bytes ไปยัง VM ที่ถูกต้อง
- router ไม่ได้เป็นผู้ตัดสินใจว่าเบราว์เซอร์จะรันที่ใด
- แม้ router ตัวหนึ่งล่ม router ตัวอื่นก็ยังรับการเชื่อมต่อใหม่ได้
- การจัดวางเป็นหน้าที่ของ control plane ส่วน router มีหน้าที่แค่ส่งผ่านไบต์
ผลลัพธ์และขั้นถัดไป
- ปัจจุบันแต่ละเซสชันเบราว์เซอร์ resume จาก snapshot ของ VM ขนาดเล็กที่รันอยู่ภายใน EC2 ปกติ และรัน headless Chromium อยู่ภายในนั้น
- VM cold start ต่ำกว่า 400ms
- ค่าหน่วงในการสร้างเบราว์เซอร์ตาม API สาธารณะคือ p50 825ms และ p99 1.35 วินาที
- ตัวเลขนี้วัดจาก stress test 10,000 เซสชัน ที่เบราว์เซอร์ทั้งหมดเริ่มทำงานสำเร็จ
- leaderboard อิสระของ BrowserArena จัดให้ Browser Use อยู่อันดับ 1 ด้วยราคา $0.02/hr และ reliability 100%
- ต้นทุนที่ยังใหญ่ที่สุดในโครงสร้างนี้คือตัว Chromium เอง
- หลัง resume แล้ว การเริ่ม Chromium ยังใช้เวลาประมาณ 545ms ที่ p50
- ปัจจุบัน snapshot ถูกสร้างไว้ก่อนถึงจุดเริ่ม Chromium
- ทุกเบราว์เซอร์จึงตื่นขึ้นมาจากจุดที่เหมือนกันและสะอาด แล้วค่อยเริ่ม Chromium ของตัวเอง
- ขั้นถัดไปคือสร้าง snapshot หลังจากที่ Chromium รันอยู่แล้ว
- เซสชันใหม่จะได้ตื่นขึ้นมาพร้อมเบราว์เซอร์ที่มีชีวิตอยู่แล้ว โดยไม่ต้องเริ่มเบราว์เซอร์ใหม่
- งานนี้ซับซ้อน
- เบราว์เซอร์ที่กำลังรันมีอุปกรณ์ที่เปิดอยู่ ตัวจับเวลา สถานะกราฟิก สถานะเครือข่าย และสถานะ fingerprint
- ต้องทำให้สถานะเหล่านี้ปลอดภัยก่อน freeze
- หลัง restore แล้ว แต่ละเบราว์เซอร์ต้องดูเป็นเบราว์เซอร์ของตัวเอง ไม่ใช่สำเนาของเบราว์เซอร์ก่อนหน้า
- ตอนนี้ Browser Use Cloud ใช้งานได้ที่ cloud.browser-use.com
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
การยก การหลบเลี่ยงแอนติบอต มาเป็นตัวชี้วัดประสิทธิภาพดูค่อนข้างไม่จริยธรรม เพราะจุดประสงค์ของแอนติบอตคือการกันบอตที่ไม่พึงประสงค์ออกไป แต่บริการแบบนี้สุดท้ายจะยิ่งทำให้เว็บไม่เป็นมิตรกับมนุษย์และแพงขึ้น
เว็บไซต์ต่าง ๆ จะพยายามบล็อกการเข้าถึงแบบอัตโนมัติต่อไป และกำแพงการเข้าถึงคอนเทนต์ก็จะยิ่งเพิ่มขึ้น เหตุผลที่การเรียกร้อง การยืนยันตัวตน บนเว็บเพิ่มมากขึ้นก็ดูจะไม่ได้มีแค่เรื่องจำกัดอายุหรือ “ปกป้องเด็ก” แต่ยังรวมถึงผลพวงระดับบนอย่างการป้องกันบอตและการคุ้มครองรายได้จากโฆษณาด้วย
สำหรับเว็บไซต์ที่ไม่มี API ก็ใช้สแครปเปอร์ด้วย และยังทำดัชนีประวัติการซื้อทั้งหมดลงฐานข้อมูลเพื่อให้วิเคราะห์ได้ด้วย ฉันไม่อยากเสียเวลาเพิ่มไปกับการหลบระบบตรวจจับบอตงี่เง่า และถ้าเป็นข้อมูลที่เข้าถึงด้วยวิธีอื่นไม่ได้ก็ยินดีจ่ายเงินอยู่แล้ว สุดท้ายมันก็เป็นการเผาทรัพยากรไปกับเกมแมวจับหนูที่ฝั่งสแครปเปอร์ยังไงก็ชนะ
แต่การให้บริการ residential proxy นั้นน่าจะไม่จริยธรรมมากกว่า ผู้ให้บริการอินเทอร์เน็ตที่อยู่อาศัยซึ่งถูกนำมาใช้เป็นพร็อกซีแบบนั้นมักไม่รู้ตัวด้วยซ้ำว่าตัวเองถูกดึงเข้าไปอยู่ในบริการลักษณะนี้
ถ้าคุณไม่สามารถนั่งเฝ้าหน้าคอม 24 ชั่วโมงเพื่อหาตั๋วคอนเสิร์ตได้ การใช้บอตส่วนตัวเพื่อซื้อตั๋ววงที่ชอบก็ดูไม่ใช่เรื่องผิดจริยธรรม ในทางกลับกัน ถ้าทำไปเพื่อเก็งกำไรขายตั๋วต่อ ฉันก็เห็นด้วยว่านั่นผิดจริยธรรม แอนติบอตฝั่งตรงข้ามแอนติบอตก็คือการเปิดทางให้ทำสิ่งที่คนอื่นคิดว่าไม่ควรถูกทำให้เป็นอัตโนมัติ และผู้อ่าน Hacker News จำนวนไม่น้อยก็น่าจะเคยทำแบบนี้สักครั้ง ถ้าทำเพื่อกำไรล้วน ๆ ก็คงไม่ดีนัก แต่ถ้าใช้เพื่อให้มีโอกาสสู้กับพวกขายตั๋วต่อก็พอฟังขึ้น
เนื่องจากเป็นแค่หนึ่งในหลาย SaaS tenant จึงไม่ใช่ลูกค้ารายใหญ่พอจะไปเรียกร้องให้ถอด CAPTCHA ได้ ก็เลยแค่หาทางเลี่ยงข้อจำกัดนั้น
สิ่งที่ตกไปตรงนี้คือ ตอนนี้ EC2 ปกติก็รองรับ nested virtualization ได้แล้วตั้งแต่เดือนกุมภาพันธ์ปีนี้ ก่อนหน้านั้นถ้าจะรัน Firecracker VM ต้องใช้ EC2 แบบ metal
ค่อนข้างแปลกใจนิดหน่อยที่ทำมาขนาดนี้แล้วก็ยังยึด Chromium อยู่
เซิร์ฟเวอร์ web-access MCP ของเรา[0] ใช้วิธีที่ง่ายกว่ามาก โดยเปิดเบราว์เซอร์อินสแตนซ์เป็นโปรเซสลูก และการปรับปรุงด้านเสถียรภาพ, CPU, และการใช้หน่วยความจำที่ใหญ่ที่สุดก็คือการเปลี่ยนจาก Chrome ไปเป็น Lightpanda[1] อย่างที่บอกไว้ท้ายบทความ เบราว์เซอร์ที่เปิดได้เร็วกว่าอาจเป็นแค่เบราว์เซอร์ที่จัดสรรหน่วยความจำน้อยกว่าตั้งแต่แรกก็ได้
[0]: https://github.com/EratoLab/web-access-mcp
[1]: https://lightpanda.io
เบราว์เซอร์อย่าง LightPanda ไม่มีความสามารถด้าน stealth เลยและตรวจจับได้ง่ายมาก ถ้าตัดสิ่งที่ไม่จำเป็นออกไปก็ยังมีวิธีทำให้ Chromium เร็วขึ้นได้ โดยไม่จำเป็นต้องสร้างเอนจินใหม่ทั้งก้อนตั้งแต่ต้น ฉันคิดว่า Chromium ไปถึงระดับประสิทธิภาพนั้นได้โดยไม่ต้องเสียสิ่งที่สำคัญที่สุดอย่าง stealth ภาษาไม่ใช่ปัญหา และ C++ ก็มีประสิทธิภาพดีพอ ๆ กับ Zig แต่ก็ยอมรับว่า Chromium นั้นเทอะทะมาก
ฉันทำ Screenshot API ชื่อ ApiFlash และใช้การแพ็ก Chromium ลงในอิมเมจคอนเทนเนอร์ของ AWS Lambda แทน Firecracker บน EC2
AWS Lambda ให้ทั้งการแยกสภาพแวดล้อมและการ autoscale มาเลยฟรี ๆ จึงเหมาะมากกับงานแบบไร้สถานะที่โหลดพุ่งเป็นช่วง ๆ อย่างการจับภาพหน้าจอ ฉันมองว่าได้ข้อดีเกือบทั้งหมดเหมือนโซลูชัน browser-use แต่สถาปัตยกรรมง่ายกว่ามาก ข้อแลกเปลี่ยนคือ cold start ของ AWS Lambda แต่ในทางปฏิบัติระบบจะนำฟังก์ชันที่ยังอุ่นอยู่กลับมาใช้ซ้ำเมื่อมีการเรียกต่อเนื่อง ถ้ามีปริมาณการเรียกมากพอ ช่วงพีกก็จะถูกเกลี่ยและ cold start ก็จะไม่เกิดบ่อยนัก
ปัญหาที่เราเจอบน Lambda คือเวลารันจำกัดที่ 15 นาที, ราคา, การไม่มีเมกานิซึม snapshot, และการขาดการควบคุมโฮสต์รันไทม์ในระดับล่าง เรารองรับได้สูงสุด 4 ชั่วโมงและถ้าจำเป็นก็รันได้นานกว่านั้นอีก ถึงอย่างนั้น สำหรับงานอัตโนมัติบนเว็บทั่วไปส่วนใหญ่ Lambda ก็เกินพออยู่แล้ว
เขาพูดว่า “ถัดไป: ข้ามการสตาร์ต Chromium” เลยทำให้นึกว่า ทำไมไม่เก็บชุดเบราว์เซอร์ที่กำลังรันอยู่ไว้เป็น warm pool แล้วค่อยจัดสรรให้คำขอที่เข้ามา
จากมุมมองผู้ใช้ ความหน่วงก็น่าจะใกล้ศูนย์มาก แน่นอนว่าคงต้องมีตรรกะคาดการณ์เพื่อขยายหรือลด warm pool ตามรูปแบบทราฟฟิก แต่ก็ดูเหมือนเป็นทางแก้ที่ง่ายที่สุด
warm pool นั้นดี แต่สุดท้ายก็ยังกินทรัพยากร และต้องสตาร์ตเบราว์เซอร์อยู่เรื่อย ๆ เพื่อให้พูลอุ่นและรักษาสมดุล เราวางแผนว่าการเปลี่ยนแปลงต่อไปจะยังคงการสตาร์ต Chromium เอาไว้ แต่ทำให้ VM พร้อมใช้งานภายใน 50ms เพื่อเอาชนะ warm pool อย่างสมบูรณ์ ลูกค้าบางรายต้องการพารามิเตอร์และฟีเจอร์พิเศษ ทำให้ความซับซ้อนของ warm pool สูงขึ้น เส้นทางปกติอาจเร็ว แต่เส้นทางข้อยกเว้นอาจช้ามาก เราอยากรับประกันความเร็วได้ไม่ว่าจะต้องใช้ฟีเจอร์อะไรกับเบราว์เซอร์ที่ร้องขอมา
Firecracker เป็นเทคโนโลยีที่ยอดเยี่ยม เราใช้มันในสตาร์ตอัปด้านการสัมภาษณ์งานที่รันรันไทม์แบบแยกสภาพแวดล้อมสำหรับสัมภาษณ์เขียนโค้ดและพื้นที่ทำงานส่วนตัว มันเสถียรมากและเบาอย่างน่าทึ่ง
การเชื่อมต่อผ่าน Go SDK ก็ง่ายมากด้วย
ดีใจที่เห็น userfaultfd ถูกใช้งานมากขึ้น มันเป็น API ที่ทรงพลังจริง ๆ เพราะให้คุณควบคุมได้ทั้งหมดว่าเมื่อเกิด page fault แล้วจะโหลดหน่วยความจำอย่างไรและจากที่ไหน
ก็จริงที่ EC2 ปกติเองก็เป็น VM อยู่แล้ว แต่ฉันเข้าใจว่ามี EC2 บางประเภทที่เปิดให้เข้าถึงไฮเปอร์ไวเซอร์ได้ จึงทำให้รัน Firecracker ได้ ถ้าฉันเข้าใจผิดช่วยแก้ให้ด้วย
[1] https://aws.amazon.com/about-aws/whats-new/2026/02/amazon-ec...
สงสัยว่าทำไมถึงต้องใช้ Firecracker ด้วย รันตรงในคอนเทนเนอร์ไม่ได้หรือ? เข้าใจเรื่องความกังวลด้านการแยกสภาพแวดล้อมนะ แต่ถ้าจับคู่เบราว์เซอร์กับ container escape มันก็น่าจะเป็น CVE มูลค่าพันล้านดอลลาร์ไม่ใช่หรือ?
คอนเทนเนอร์มีพื้นผิวการโจมตีกว้างกว่า VM มาก และเพราะมาตรฐานอุตสาหกรรมก็ไม่ได้มองว่าปลอดภัย จึงมีแนวโน้มว่าทรัพยากรที่ทุ่มให้การจัดการ CVE ของ container escape จะน้อยกว่าของ VM escape ด้วย
ถ้าจะทำสิ่งนี้บนอินสแตนซ์ที่ไม่ใช่
.metalไม่จำเป็นต้องแพตช์เคอร์เนลหรือ? เหมือนว่าจะต้องใช้ PVM patch นะ