- Browser Use Cloud dùng một Firecracker VM riêng biệt cho mỗi phiên trình duyệt, hạ thời gian khởi động phiên mới xuống dưới 1 giây và giảm chi phí từ $0.06 xuống $0.02 mỗi giờ trình duyệt
- Kiến trúc Unikraft trước đây có lợi về chi phí nhàn rỗi, nhưng khi lưu lượng tăng đột biến thì phải có người tự điều chỉnh dung lượng, khiến production ngừng hoạt động 45 phút trong một bài kiểm thử tải
- Kiến trúc mới dùng control plane tự xây dựng để giám sát fleet trình duyệt theo thời gian thực, quyết định việc phân bổ host EC2, mở rộng và draining chi tiết hơn CloudWatch
- Thay vì dùng
.metal, họ chọn ảo hóa lồng nhau bằng cách chạy Firecracker trên EC2 thông thường, rồi giảm nút thắt bằng trang bộ nhớ 2MB,userfaultfd, cố định vCPU, real-time priority và các bản vá cho Chromium headless - VM cold start dưới 400ms, còn trong bài stress test 10.000 phiên, độ trễ tạo trình duyệt qua API công khai đạt p50 825ms, p99 1,35 giây, và tất cả trình duyệt đều khởi động thành công
Trình duyệt đám mây nhanh, cô lập và rẻ
- Mục tiêu của Browser Use Cloud là khởi động trình duyệt nhanh, đồng thời cô lập trạng thái giữa các phiên và giảm chi phí
- Một phiên có thể bao gồm Chromium, hệ thống tệp, cookie, cache, cấu hình proxy, tệp tải xuống, và đôi khi cả phiên khách hàng đã đăng nhập
- Nếu một trình duyệt có thể đọc trạng thái của trình duyệt khác thì sẽ thành vấn đề bảo mật, nên mỗi phiên phải được tách biệt khỏi host và các phiên khác
- Cách giải phổ biến là dùng VM có CPU, bộ nhớ, đĩa và thiết bị mạng riêng, nhưng với môi trường trình duyệt đám mây nơi VM liên tục được tạo rồi bỏ đi sau khi phiên kết thúc, cách này quá nặng và tốn kém
- Kiến trúc mới chạy mọi phiên Browser Use Cloud trong một Firecracker VM nhỏ, và các VM này chạy trên Amazon EC2
Vì sao rời bỏ Unikraft
- Kiến trúc trước đây chạy trình duyệt đám mây bằng Unikraft
- Unikraft tải một unikernel, tức ảnh nhỏ được tạo riêng cho mục đích cụ thể thay vì khởi động toàn bộ Linux
- Unikernel khởi động nhanh và có thể tắt khi không có người dùng, nên chi phí nhàn rỗi thấp
- Nút thắt nằm ở việc tăng nhanh dung lượng trình duyệt khi lưu lượng tăng đột biến
- Unikraft không có autoscaling tích hợp tốt
- Kỹ sư phải tự thay biến và thêm instance thủ công
- Một bài kiểm thử tải đã khiến production ngừng hoạt động 45 phút
- Sau khi xây dựng lại, họ chuyển sang dùng Firecracker
- Firecracker cung cấp lớp để tạo, giám sát và chạy VM
- Nó cấp CPU, bộ nhớ, đĩa và thiết bị mạng cho từng VM, đồng thời cô lập với host và các VM khác
Tự động hóa mở rộng trình duyệt bằng control plane riêng
- Firecracker có thể cấp một VM cho mỗi trình duyệt, nhưng không tự quyết định số lượng VM, vị trí đặt hay thời điểm scale
- Browser Use đã xây control plane riêng để giám sát fleet trình duyệt và quyết định scale up/down
- Khi người dùng yêu cầu trình duyệt, control plane sẽ chọn một máy còn dư tài nguyên
- Khi lưu lượng tăng, hệ thống khởi động thêm máy; khi giảm, nó không gửi trình duyệt mới tới những máy sắp bị loại bỏ
- Control plane theo dõi fleet theo thời gian thực
- CloudWatch, dịch vụ giám sát của AWS, thường phản ứng theo cửa sổ 1 phút
- Control plane biết những thông tin mà metric thông thường không có, như trình duyệt còn đang khởi động, máy đang bị gỡ bỏ, hay máy không nên nhận phiên mới
- Yêu cầu người dùng đi qua stateless edge router tới control plane, và control plane sẽ chọn host EC2 còn trống
Vì sao chạy Firecracker trên EC2 thông thường
- Cách phổ biến để chạy Firecracker trên AWS là dùng instance
.metal.metallà mô hình thuê trọn máy chủ vật lý để Firecracker chạy trực tiếp
- Browser Use chọn EC2 thông thường
- Máy EC2 thông thường có thể lấy nhanh hơn
- Chi phí duy trì thấp hơn
- Host khởi động từ ảnh dựng sẵn và chỉ mất khoảng 30 giây sau khi start để bắt đầu phục vụ trình duyệt
- Nếu có thể thêm host nhanh hơn thì lượng dung lượng nhàn rỗi phải trả tiền sẽ ít hơn, và chi phí chuyển sang khách hàng cũng thấp hơn
- Cái giá phải trả là cấu trúc VM bên trong VM
- Bản thân EC2 thông thường đã chạy trong lớp cô lập của AWS
- Bên trong đó họ lại chạy thêm VM trình duyệt
- Khi VM trình duyệt cần host trợ giúp, yêu cầu phải đi qua hai lớp VM nên phát sinh thêm độ trễ
- Browser Use chấp nhận đánh đổi này để scale up nhanh hơn và giảm chi phí, rồi tập trung tăng tốc đường chạy Firecracker
Luồng từ yêu cầu đến trình duyệt sẵn sàng dùng
- Khi người dùng yêu cầu trình duyệt, control plane sẽ chọn một máy còn dư tài nguyên
- Máy đó khôi phục một browser VM đã lưu và khởi động Chromium bên trong
- Khi Chromium đạt trạng thái có thể điều khiển được, hệ thống trả về URL kết nối
- Tác nhân của người dùng sẽ kết nối tới URL này
- Browser Use điều khiển Chromium bằng Chrome DevTools Protocol (CDP) qua WebSocket
- CDP là API điều khiển từ xa của Chrome cho các tác vụ như bấm nút, nhập văn bản, đọc trang và chụp ảnh màn hình
- Có ba nút thắt chính gây ra độ trễ
- Khôi phục bộ nhớ VM
- Khởi động Chromium
- Duy trì stealth để không bị hệ thống anti-bot phát hiện
Nút thắt thứ nhất: khôi phục bộ nhớ
- Trình duyệt production không khởi động từ đầu mà resume từ một snapshot
- Snapshot là VM đã khởi động xong và được dừng lại ngay trước khi bắt đầu chạy Chromium
- Resume VM nhanh hơn boot mới, nhưng ở giai đoạn cold start ban đầu, page fault chiếm 72% tổng số VM exit
- Thời gian từ lúc resume VM đến lúc trình duyệt sẵn sàng cho CDP ban đầu là 9,8 giây
- Lý do chậm là khi VM được khôi phục chạm vào bộ nhớ lần đầu, host phải ánh xạ lại phần bộ nhớ đó
- Sự kiện này là page fault
- Trong VM lồng nhau, page fault có thể đi qua hai lớp VM nên rất tốn kém
- Giải pháp là ánh xạ bộ nhớ theo đơn vị lớn hơn
- Trước đây họ khôi phục bằng trang 4KB
- Giờ dùng trang 2MB
- Mỗi trang bao phủ nhiều bộ nhớ hơn 512 lần, nên số page fault khi trình duyệt thức dậy giảm mạnh
- Họ cũng thêm custom handler cho
userfaultfd, API của Linux để xử lý trang bộ nhớ bị thiếu- Trước khi chạy VM, hệ thống nạp trước phần bộ nhớ mà Chromium có khả năng truy cập đầu tiên
- Điều này ngăn cơn bão page fault khi Chromium khởi động
- Thay đổi này giảm thời gian từ lúc resume VM tới lúc trình duyệt nhận lệnh được từ 9,8 giây xuống 3,1 giây
- Số lần browser VM phải dừng lại và nhờ host xử lý bộ nhớ thiếu giảm từ khoảng 100.000 lần xuống còn khoảng 1.100 lần mỗi lần resume, tức giảm khoảng 91 lần
- Các tối ưu nhỏ cũng cộng dồn đáng kể
- Họ tắt bước kiểm tra 500ms vốn dùng để tìm bàn phím PS/2 cũ không hề tồn tại
- Họ chuyển kiểm tra trạng thái sẵn sàng từ HTTP polling sang đọc log qua
vsock - Khi browser driver ghi thông báo ready vào log, host đọc qua
vsockvà xác nhận thông báo ready trong chưa tới 1ms
Nút thắt thứ hai: khởi động Chromium và phân bổ CPU
- Khi Chromium khởi động, mức sử dụng CPU tăng cao vì phải tạo renderer, compositor và V8 isolate cùng lúc
- Sau khi khởi động xong, tự động hóa trình duyệt tương đối yên tĩnh
- Tác nhân sẽ bấm, chờ, đọc rồi lại bấm
- Phần lớn thời gian trình duyệt chờ trang, phản hồi mạng hoặc hành động tiếp theo của tác nhân
- Đặc tính này cho phép packing nhiều trình duyệt trên một host
- Họ xử lý CPU burst lúc khởi động theo hai giai đoạn
- Trong lúc trình duyệt vừa resume và Chromium đang khởi động, vCPU được để ở trạng thái unpinned
- Linux có thể phân tán tải CPU của trình duyệt khắp host thay vì khóa vào core cố định
- Khi trình duyệt báo ready, vCPU mới được pin vào các core ổn định
- Nếu pin ngay từ đầu, nhiều trình duyệt khởi động cùng lúc sẽ dồn lên cùng một hot core và làm một số lần launch thất bại
- Họ cũng điều chỉnh cách xử lý hyperthread
- Một core CPU vật lý thường hiện ra thành hai CPU logic gọi là sibling thread
- Nếu hai browser VM mỗi cái nhận một sibling thì chúng sẽ tranh nhau cùng một core vật lý
- Trong môi trường lồng nhau, sự cạnh tranh này biểu hiện thành lỗi launch
- Hiện tại mỗi trình duyệt nhận cả hai sibling thread của core vật lý mà nó sử dụng
- Mỗi thread vCPU sau khi pin còn được gán real-time priority
- Điều này khiến Linux chạy VM ngay thay vì để nó nằm sau các tác vụ kém quan trọng hơn
- Trước thay đổi này, trong bài test 1.000 trình duyệt, 17% phiên bị mất ngay sau khi tạo
- Sau thay đổi, bài test tương tự không còn mất phiên nào
Trình duyệt stealth không màn hình
- Trình duyệt headless chạy không có cửa sổ hiển thị, còn trình duyệt headful chạy như trình duyệt trên laptop với cửa sổ, đồ họa và khung render
- Chromium headless thuần túy rất dễ bị các website có anti-bot phát hiện
- Theo stealth benchmark của Browser Use, Chromium headless thuần chỉ có tỷ lệ vượt chặn 2%
- Khi chạy cùng Chromium đó ở chế độ headful có cửa sổ hiển thị, chỉ riêng render đã nâng tỷ lệ vượt chặn lên 50%
- Đây là lý do nhiều nhà cung cấp chạy trình duyệt headful và phải trả thêm chi phí cho display server, GPU và compositor dù chẳng có ai nhìn màn hình
- Browser Use thay đổi chính trình duyệt để vẫn giữ được cách chạy headless hoàn toàn
- Thành phần đầu tiên là Chromium fork
- Nhiều công cụ stealth tiêm JavaScript vào mọi trang sau khi trình duyệt khởi động để che giấu tự động hóa
- Ví dụ, chúng ghi đè giá trị
navigator.webdriverđể website thấyfalsethay vìtrue - Website có thể phát hiện rằng những giá trị này đã bị ghi đè
- Browser Use vá ở mức thấp hơn trong Chromium để các giá trị này không bị lộ ra ngay từ đầu
- Thành phần thứ hai là fingerprinting
- Browser fingerprint là tổ hợp thông tin về trình duyệt và máy mà website có thể đọc được
- Nó gồm hàng trăm chi tiết như hệ điều hành, kích thước màn hình, font, đầu ra đồ họa, âm thanh, múi giờ, ngôn ngữ...
- Browser Use dùng hàng chục nghìn fingerprint thực tế trên macOS, Windows và Linux
- Những trình duyệt này đạt tỷ lệ vượt chặn 81% trong stealth benchmark và 84,8% trong Halluminate BrowserBench
- Vì không có màn hình nên chi phí chạy trình duyệt thấp hơn và việc mở rộng cũng dễ hơn
Kết nối đúng tới trình duyệt cần dùng
- Khi trình duyệt đã sẵn sàng, người dùng kết nối bằng CDP
- URL công khai là WebSocket URL
- Trước fleet trình duyệt là các edge router đơn giản
- Router nhận kết nối WebSocket, hỏi control plane vị trí của trình duyệt tương ứng, rồi chuyển tiếp raw CDP byte tới đúng VM
- Router không quyết định trình duyệt sẽ chạy ở đâu
- Nếu một router chết, router khác vẫn có thể nhận kết nối mới
- Việc phân bổ do control plane phụ trách, còn router chỉ làm nhiệm vụ chuyển byte
Kết quả và bước tiếp theo
- Hiện tại, mỗi phiên trình duyệt chạy bằng cách resume từ một snapshot VM nhỏ nằm trong EC2 thông thường, rồi chạy Chromium headless bên trong đó
- VM cold start dưới 400ms
- Độ trễ tạo trình duyệt qua API công khai đạt p50 825ms, p99 1,35 giây
- Các số liệu này được đo trong bài stress test 10.000 phiên nơi mọi trình duyệt đều khởi động thành công
- Bảng xếp hạng độc lập của BrowserArena xếp Browser Use hạng 1 với mức giá $0.02/hr và độ tin cậy 100%
- Chi phí lớn nhất còn lại trong hạ tầng này là chính Chromium
- Sau resume, việc khởi động Chromium vẫn mất khoảng 545ms ở mức p50
- Snapshot hiện được tạo ở thời điểm ngay trước khi Chromium khởi động
- Mọi trình duyệt đều thức dậy từ cùng một điểm sạch giống nhau rồi tự khởi động Chromium riêng
- Bước tiếp theo là tạo snapshot sau khi Chromium đã chạy sẵn
- Khi đó phiên mới có thể thức dậy với một trình duyệt đã sống sẵn thay vì phải tự khởi động trình duyệt
- Việc này phức tạp
- Trình duyệt đang chạy có thiết bị mở, timer, trạng thái đồ họa, trạng thái mạng và trạng thái fingerprint
- Các trạng thái này phải được đưa về mức an toàn trước khi freeze
- Sau khi restore, mỗi trình duyệt phải trông như trình duyệt riêng của nó chứ không phải bản sao của trình duyệt trước đó
- Browser Use Cloud hiện đã có tại cloud.browser-use.com
1 bình luận
Ý kiến trên Hacker News
Có vẻ khá phi đạo đức khi lấy vượt anti-bot làm tiêu chí benchmark. Mục đích của anti-bot là chặn những bot không mong muốn, còn các dịch vụ kiểu này rốt cuộc chỉ khiến web kém thân thiện hơn với con người và đắt đỏ hơn
Các trang sẽ tiếp tục cố chặn truy cập tự động, và rào cản tiếp cận nội dung sẽ còn tăng thêm. Việc yêu cầu xác minh danh tính trên web ngày càng nhiều dường như không chỉ vì giới hạn độ tuổi hay “bảo vệ trẻ em”, mà còn là hệ quả cấp cao hơn của việc phòng thủ bot và bảo vệ doanh thu quảng cáo
Với các trang không có API, tôi cũng dùng scraper, đồng thời lập chỉ mục toàn bộ lịch sử mua hàng vào cơ sở dữ liệu để có thể phân tích. Tôi không muốn tốn thêm thời gian để vượt qua mấy cơ chế phát hiện bot ngớ ngẩn, và nếu đó là dữ liệu không thể tiếp cận bằng cách khác thì tôi cũng sẵn sàng trả tiền. Dù sao đây cũng là kiểu đốt tài nguyên vào một trò mèo vờn chuột mà scraper rốt cuộc vẫn sẽ thắng
Tuy vậy, việc cung cấp proxy dân cư có khả năng là phi đạo đức. Những người cung cấp đường truyền dân cư cho các proxy đó thường không biết rằng họ đã bị đưa vào kiểu dịch vụ này
Khi tôi không thể ngồi trước máy tính 24 giờ để săn một buổi diễn nào đó, thì việc dùng bot cá nhân để mua vé cho ban nhạc mình thích khó có thể xem là phi đạo đức. Ngược lại, nếu mục đích là đầu cơ vé thì tôi đồng ý là phi đạo đức. Anti-bot của anti-bot là để cho phép những việc mà người khác cho rằng không nên tự động hóa, và tôi đoán khá nhiều độc giả Hacker News từng làm chuyện kiểu này ít nhất một lần. Nếu thuần túy vì lợi nhuận thì không hay lắm, nhưng nếu là để có cơ hội đối đầu với phe đầu cơ vé thì có vẻ chấp nhận được
Vì họ chỉ là một tenant trong số nhiều tenant SaaS nên cũng không đủ lớn để yêu cầu gỡ CAPTCHA, thành ra họ cứ tìm cách vượt qua ràng buộc đó
Điểm còn thiếu ở đây là ảo hóa lồng nhau trên các EC2 thông thường đã khả dụng từ tháng 2 năm nay. Trước đó, muốn chạy Firecracker VM thì phải dùng EC2 metal instance
Hơi ngạc nhiên là làm đến mức này mà họ vẫn bám Chromium
Máy chủ MCP web-access của chúng tôi[0] chạy các phiên bản trình duyệt dưới dạng tiến trình con với cấu hình đơn giản hơn nhiều, và cải thiện lớn nhất về độ ổn định, CPU, và mức dùng bộ nhớ là khi chuyển từ Chrome sang Lightpanda[1]. Như câu cuối bài nói, một trình duyệt khởi động nhanh hơn có thể ngay từ đầu đã là một trình duyệt cấp phát ít bộ nhớ hơn
[0]: https://github.com/EratoLab/web-access-mcp
[1]: https://lightpanda.io
Các trình duyệt như LightPanda hoàn toàn không có stealth và rất dễ bị phát hiện. Nếu bỏ đi những phần không cần thiết thì cũng có cách làm Chromium nhanh hơn. Không cần phải xây lại toàn bộ engine từ đầu, tôi tin Chromium vẫn có thể đạt hiệu năng đó mà không mất stealth, vốn là ưu tiên cao nhất. Ngôn ngữ không phải vấn đề, C++ cũng có thể cho hiệu năng tốt như Zig, nhưng tôi đồng ý là sự cồng kềnh của Chromium là rất lớn
Tôi vận hành một API chụp ảnh màn hình tên là ApiFlash, và thay vì Firecracker trên EC2 thì tôi đóng gói Chromium vào container image của AWS Lambda
AWS Lambda cung cấp sẵn khả năng cô lập và tự động mở rộng, nên rất lý tưởng cho các tác vụ stateless có tải tăng vọt như chụp ảnh màn hình. Tôi cho rằng nó mang lại gần như những lợi ích tương tự giải pháp browser-use, trong khi kiến trúc đơn giản hơn nhiều. Đánh đổi là cold start của AWS Lambda, nhưng trên thực tế nó tái sử dụng các hàm đang nóng cho các lần gọi liên tiếp. Nếu lưu lượng đủ lớn thì các đỉnh tải được làm phẳng bớt và cold start cũng không xảy ra thường xuyên đến vậy
Các vấn đề chúng tôi gặp với Lambda là giới hạn thời gian chạy 15 phút, chi phí, thiếu cơ chế snapshot, và thiếu quyền kiểm soát mức thấp với host thực thi. Chúng tôi hỗ trợ tối đa 4 giờ và nếu cần còn có thể chạy lâu hơn. Dù vậy, với phần lớn các trường hợp tự động hóa web thông thường thì Lambda là quá đủ
Họ nói “Tiếp theo: bỏ qua việc khởi động Chromium”, nhưng tôi tự hỏi sao không giữ sẵn một cụm trình duyệt đang chạy dưới dạng warm pool rồi gán cho các request đi vào
Từ góc độ người dùng thì độ trễ sẽ gần như bằng 0. Tùy theo mẫu lưu lượng có lẽ vẫn cần logic dự đoán để tăng hoặc giảm warm pool, nhưng đây có vẻ là lời giải dễ nhất
Warm pool thì tốt, nhưng rốt cuộc vẫn tiêu tốn tài nguyên, và để luôn giữ pool ở trạng thái nóng cũng như cân bằng nó, bạn vẫn phải liên tục khởi động trình duyệt. Với các thay đổi sắp tới, chúng tôi định giữ nguyên việc khởi động Chromium nhưng làm cho VM sẵn sàng trong vòng 50ms để hoàn toàn vượt qua warm pool. Một số khách hàng cần tham số và tính năng đặc thù, khiến độ phức tạp của warm pool tăng lên. Đường đi phổ biến có thể nhanh, nhưng các đường ngoại lệ lại có thể rất chậm; chúng tôi muốn đảm bảo tốc độ nhanh bất kể trình duyệt được yêu cầu cần tính năng gì
Firecracker là công nghệ tuyệt vời. Tôi đang dùng nó ở một startup phỏng vấn để chạy runtime cô lập cho phỏng vấn lập trình và không gian làm việc cá nhân, nó rất ổn định và nhẹ đến mức đáng kinh ngạc
Việc tích hợp bằng Go SDK cũng rất dễ
Thật hay khi thấy userfaultfd được dùng nhiều hơn. Đây là API cực kỳ mạnh vì nó cho phép kiểm soát hoàn toàn cách và nơi nạp bộ nhớ khi xảy ra page fault
Đúng là EC2 thường bản thân nó đã là VM, nhưng tôi hiểu là có những loại EC2 nhất định cung cấp quyền truy cập hypervisor để Firecracker cũng chạy được. Nếu tôi sai thì mong được sửa
[1] https://aws.amazon.com/about-aws/whats-new/2026/02/amazon-ec...
Tôi thắc mắc tại sao lại cần Firecracker. Không thể cứ chạy trực tiếp trong container sao? Tôi hiểu lo ngại về cô lập, nhưng kết hợp trình duyệt với container escape chẳng phải là một CVE trị giá cả tỷ đô sao?
Container có bề mặt tấn công rộng hơn VM rất nhiều, và vì không được coi là an toàn theo chuẩn chung của ngành, nên có khả năng nguồn lực dành cho việc xử lý CVE container escape cũng ít hơn so với VM escape
Muốn làm điều này trên instance không phải
.metalthì chẳng phải cần patch kernel sao? Có vẻ cần PVM patch