- Phân phối công cụ dưới dạng nhị phân tĩnh độc lập cho phép người dùng sử dụng ngay mà không cần cài thêm môi trường phát triển hay toolchain
- Quá trình biên dịch đóng vai trò như một lớp bảo vệ bổ sung giúp giảm khả năng phát hành mã hoạt động bất thường
- Các công cụ dựa trên ngôn ngữ thông dịch tạo ra gánh nặng bảo trì lớn do phải cài nhiều phụ thuộc và lãng phí dung lượng đĩa, cũng như phải cài lại lặp đi lặp lại khi nâng cấp
- Càng nhiều phụ thuộc thì lỗ hổng bảo mật và bề mặt tấn công càng lớn, khiến rủi ro bị tấn công hoặc phát sinh vấn đề bảo trì cao hơn
- Nhị phân tĩnh dựa trên ngôn ngữ biên dịch không bị ảnh hưởng bởi thay đổi của môi trường bên ngoài, nên vẫn đảm bảo tính ổn định khi sử dụng sau khi phát hành
Ưu điểm của việc phân phối nhị phân tĩnh độc lập
Có thể dùng ngay mà không cần cài đặt
- Giống như trường hợp Open AI xây dựng lại Codex bằng Rust và từ bỏ TypeScript, nếu phân phối một nhị phân đơn được viết bằng ngôn ngữ biên dịch thì người dùng có thể chạy ngay mà không cần cài thêm toolchain
- Ưu điểm lớn nhất không nằm ở tốc độ hay hiệu suất, mà ở chỗ có thể dùng công cụ ngay lập tức mà không cần cài đặt
Trình biên dịch như một lớp an toàn bổ sung
- Việc kiểm tra ở giai đoạn biên dịch giúp giảm khả năng mã lỗi được phát hành
- Ví dụ, Google Cloud CLI từng nhiều lần được phát hành trong trạng thái không thể chạy do dựa trên Python
- Ngay cả các đội ngũ lớn cũng khó tránh khỏi vấn đề này; với đội ngũ nhỏ, việc phát hành ổn định công cụ dựa trên ngôn ngữ thông dịch còn khó hơn
Không cần phụ thuộc vào toolchain
- Công cụ viết bằng ngôn ngữ biên dịch chỉ cần phân phối một tệp nhị phân duy nhất, trong khi các công cụ viết bằng ngôn ngữ thông dịch như Python, Ruby, TypeScript bắt buộc phải có môi trường phát triển tương ứng
- Giống như mdl (markdown linter) được viết bằng Ruby, mỗi khi môi trường phát triển (Ruby) được nâng cấp thì lại cần cài đặt lại
- Khi dùng markdownlint dựa trên JavaScript, cần cài npm cùng hơn 44 phụ thuộc
Vấn đề lãng phí dung lượng đĩa
- Trợ lý lập trình FOSS phổ biến aider được viết bằng Python, và khi cài qua Homebrew sẽ cài thêm 51 gói
- Dung lượng đĩa thực tế tăng hơn 3GiB, lớn hơn cả dung lượng của phần lớn bản phân phối Linux
- Trong khi đó, trình quản lý gói uv viết bằng Rust chỉ cần một nhị phân đơn 35MiB, không cần cài Rust hay rustup
Gia tăng lỗ hổng bảo mật
- Càng nhiều phụ thuộc thì bề mặt tấn công càng mở rộng và khả năng lộ ra lỗ hổng bảo mật càng tăng
- Gói Codex của OpenAI có 24 phụ thuộc trực tiếp và 184 phụ thuộc gián tiếp
- Dù OpenAI có kiểm toán toàn bộ phụ thuộc, do phiên bản phụ thuộc không được cố định nên các bản cập nhật sau này vẫn có thể gây ra các vấn đề như lỗ hổng, gói độc hại hoặc ngừng hoạt động
Dễ bảo trì hơn
- Các công cụ dựa trên ngôn ngữ thông dịch như JavaScript, TypeScript, Python sẽ không thể hoạt động nếu phụ thuộc bị gỡ bỏ
- Như sự cố left-pad, chỉ một gói bị xóa cũng có thể làm tê liệt hàng loạt dịch vụ và công cụ
- Ngôn ngữ biên dịch chỉ cần phụ thuộc ở thời điểm build, nên ngay cả khi kho lưu trữ bên ngoài biến mất thì công cụ vẫn tiếp tục hoạt động bình thường
Kinh nghiệm của tác giả
- Tác giả từng tạo công cụ bằng Python như adb-enhanced, sau đó open source nhiều công cụ khác bằng Go như gabo, wp2hugo
- Không còn cân nhắc phát triển công cụ độc lập bằng Python hay TypeScript nữa
- Khuyến nghị nên viết bằng ngôn ngữ có thể phân phối nhị phân liên kết tĩnh như Rust, Go, C++
Kết luận
- Công cụ độc lập nên được phát triển bằng các ngôn ngữ biên dịch như Rust, Go, C++
- Nên phân phối dưới dạng nhị phân tĩnh với số lượng phụ thuộc bên ngoài ở mức tối thiểu
3 bình luận
Tôi cũng khá đồng cảm với vấn đề
lãng phí dung lượng ổ đĩa...Tôi vận hành AKS nên mỗi lần nhìn thấy app Python với image container vượt quá 1GB là lại đau đầu.
Giờ thì tôi cứ lấy Dockerfile về rồi tự tối ưu lại dung lượng và đẩy lên, nếu không giảm xuống dưới 500MB được thì đành bỏ cuộc luôn haha
Có những gói chỉ khác nhau ở phiên bản trong phần phụ thuộc
pytorch+cuda... đúng là một cảnh tượng khó tin.Chẳng có mấy chức năng gì, vậy mà mỗi daemon nhỏ lại phải cài phụ thuộc gần 2 GB..
Nếu chỉ là runtime CPU dùng cho suy luận đơn giản thì tình hình còn đỡ hơn một chút, nhưng vì các dịch vụ LLM được yêu cầu dạo này nên traffic cứ tăng theo kiểu traffic, dung lượng cũng tăng theo kiểu dung lượng, đến lúc tính chi phí thì chỉ biết chửi thề thôi ha ha ha