1 điểm bởi GN⁺ 2025-11-28 | 1 bình luận | Chia sẻ qua WhatsApp
  • Dự án .NET Unified Build là một hệ thống build mới hợp nhất toàn bộ sản phẩm theo dạng “kho mã nguyên khối ảo (Virtual Monolithic Repository, VMR)” nhằm giảm bớt sự phức tạp và kém hiệu quả của cấu trúc build dựa trên các kho mã phân tán hiện có
  • Cách cấu thành sản phẩm phân tán trước đây có tính độc lập và linh hoạt cao, nhưng gây ra gánh nặng lớn về quản lý phụ thuộc, tính nhất quán khi build và tốc độ
  • Unified Build mở rộng nguyên lý của Source Build dành cho các bản phân phối Linux, đưa vào bố cục mã nguồn đơn nhất và cấu trúc “build dọc (Vertical Build)” để rút ngắn thời gian build và tăng khả năng dự đoán
  • Thông qua luồng mã hai chiều (two-way code flow), kiểm thử theo kịch bản, cùng với cải tiến hạ tầng xác minh và ký tự động, hệ thống này đồng thời nâng cao hiệu quả của lập trình viên và chất lượng sản phẩm
  • Được chính thức áp dụng trong .NET 10, hệ thống này đã đạt được các kết quả thực tế như rút ngắn thời gian build (24 giờ → dưới 7 giờ), giảm chi phí bảo trìnâng cao độ tin cậy khi phát hành

Bối cảnh thay đổi cấu trúc build của .NET

  • Trong quá trình mã nguồn mở hóa giai đoạn 2015~2016, .NET được phát triển tách thành nhiều kho mã như CoreCLR, CoreFX, ASP.NET Core, SDK
  • Mỗi kho mã được build và phát hành độc lập, còn toàn bộ sản phẩm được tổ hợp thông qua đồ thị phụ thuộc
  • Cách này tương tự hệ sinh thái OSS, nhưng khi có bản vá bảo mật hoặc sửa lỗi khẩn cấp, cần nhiều nhóm phối hợp đồng thời nên phát sinh vấn đề không thể dự đoán thời gian
  • Dù có các ưu điểm của phát triển phân tán như phân lớp, tách biệt cộng đồng, phát triển bất đồng bộ..., mô hình này lại kém hiệu quả trong việc đảm bảo tính nhất quán của sản phẩm (coherency)

Độ phức tạp cấu thành sản phẩm và overhead

  • Độ phức tạp (Complexity): được định nghĩa là số bước cần thiết để một thay đổi đến được với khách hàng
    • Càng nhiều kho mã và nút phụ thuộc thì càng cần nhiều thời gian và phối hợp nhân sự để đảm bảo tính nhất quán
  • Overhead: thời gian không trực tiếp tạo ra đầu ra có thể chuyển giao cho khách hàng
    • Ví dụ: tạo PR, chờ phê duyệt, xếp hàng, thiết lập môi trường...
  • Kết quả phân tích build runtime của .NET 8 cho thấy khoảng 38,5% tổng thời gian build là overhead
  • Khi độ phức tạp và overhead kết hợp với nhau, hiệu quả build giảm mạnh và toàn bộ chu kỳ phát hành bị kéo dài

Nguồn gốc của Source Build và Unified Build

  • Source Build là hệ thống được thiết kế để các bản phân phối Linux có thể build .NET offline từ một bộ mã nguồn duy nhất
    • Nguyên tắc một triển khai duy nhất, một nền tảng duy nhất, một môi trường build duy nhất
    • Bộ điều phối build quản lý phụ thuộc và thứ tự build của từng thành phần
  • Source Build có độ phức tạp thấp và overhead thấp, có thể build trong vòng 50 phút
  • Microsoft từng muốn áp dụng khái niệm này vào build nội bộ, nhưng gặp khó khăn do mã nguồn đóng, phụ thuộc legacy, và các join giữa nền tảng
  • Để giải quyết, nhóm đã đưa vào các cách tiếp cận như gói tham chiếu chuyên cho source build (source-build-reference-packages), nguyên tắc một triển khai duy nhấtloại bỏ join

Mục tiêu và thiết kế của Unified Build

  • Có thể build toàn bộ sản phẩm .NET bằng một commit duy nhất
  • Tạo mọi bản phân phối theo nền tảng trong một môi trường duy nhất
  • Có thể build và xác minh độc lập cả bên ngoài Microsoft
  • Tự động đồng bộ thay đổi giữa VMR và từng kho mã thành phần thông qua luồng mã hai chiều
  • Thực hiện xác minh chức năng ở cấp toàn bộ sản phẩm thông qua kiểm thử theo kịch bản
  • Song song hóa build theo nền tảng bằng cấu trúc build dọc (Vertical Build)
    • Gồm khoảng 35~40 trục build dọc (short/tall stack)

Các giai đoạn triển khai Unified Build

  • .NET 7: thiết kế và phê duyệt khái niệm
  • .NET 8: cải tiến hạ tầng Source Build và xây dựng nền tảng
  • .NET 9: thử nghiệm build dọc và luồng mã
  • .NET 10: chính thức sản phẩm hóa và phản ánh vào RTM
    • Giới thiệu quy trình build mới ở Preview 4, chuyển đổi hoàn toàn từ Preview 5

Các thành phần chính

Virtual Monolithic Repository (VMR)

  • Kho mã dotnet/dotnet đóng vai trò bố cục mã nguồn đơn nhất cho mọi thành phần
  • Lập trình viên có thể làm việc ở từng kho mã riêng lẻ hoặc trong VMR, qua đó đồng thời đạt được sự linh hoạt của mô hình phân tán và tính nhất quán của mô hình đơn nhất

Vertical Build

  • Thực hiện build độc lập cho từng nền tảng và runtime
  • Sau khi build song song, kết quả được hợp nhất; một số join được xử lý bằng thêm các lượt build bổ sung

Code Flow

  • Đồng bộ mã hai chiều: kho mã thành phần → VMR, VMR → kho mã thành phần
  • Ghi lại trạng thái luồng mã gần nhất trong eng/Version.Details.xml
  • Tạo thay đổi dưới dạng file patch để tự động tạo PR
  • Tích hợp sẵn logic xử lý xung đột và khôi phục lỗi

Scenario Test Validation

  • Ngoài các unit test hiện có, bổ sung kiểm thử theo kịch bản để xác minh chức năng của toàn bộ sản phẩm
  • Được chạy dựa trên các đầu ra build nhằm tăng cường chống hồi quy và đảm bảo chất lượng

Thành quả và hiệu quả

  • Rút ngắn thời gian build: hơn 24 giờ → dưới 7 giờ (bao gồm ký)
  • Tăng tính linh hoạt: rút ngắn chu kỳ build và phát hành, dễ phản ánh các bản sửa khẩn cấp
  • Đảm bảo khả năng dự đoán: xác định rõ thời điểm hoàn tất build sau khi có thay đổi
  • Cải thiện hạ tầng: công cụ ký, log, build song song, tự động hóa luồng phụ thuộc...
  • Source Build cho các bản phân phối Linux cũng luôn được giữ ở trạng thái sạch trước khi build

Định hướng tiếp theo

  • Trong .NET 11, dự kiến đưa vào tự động hóa luồng mã và agent giám sát dựa trên AI
    • Tự động hóa việc theo dõi lỗi trong quá trình từ PR đến khi phản ánh vào sản phẩm
  • Về dài hạn, thúc đẩy đơn giản hóa build và tăng tốc bằng cách loại bỏ các điểm join
    • Mục tiêu: build hoàn chỉnh trong vòng 4 giờ

Kết luận

  • Unified Build, giải pháp vượt qua các giới hạn của mô hình build phân tán, đã cải thiện tận gốc hiệu quả build và phát hành của .NET
  • Đã đạt được bước tiến thực chất trên ba trục: giảm độ phức tạp và overhead, tăng tính nhất quán, tốc độ và chất lượng
  • Hệ thống này đã được áp dụng toàn diện từ .NET 10 RTM và sẽ tiếp tục được cải tiến trong các phiên bản tới

1 bình luận

 
GN⁺ 2025-11-28
Ý kiến trên Hacker News
  • Tôi thật sự rất kính trọng đội ngũ .NET
    Họ thường xuyên xuất bản các bài viết kỹ thuật rất sâu, và sự ám ảnh của họ với tối ưu hiệu năng là đáng nể (ví dụ: sự phát triển của Kestrel, Entity Framework)
    ASP.NET là một trong số ít dự án lớn sống sót qua một thay đổi lớn cỡ Python 2→3
    Trước đây nó dựa vào những tính năng gần như phép thuật để đồng bộ session, nhưng giờ đã hoạt động theo một cách hoàn toàn khác
    Thật dễ chịu khi biết một công ty trị giá 3 nghìn tỷ đô đang nghiêm túc cố gắng cải thiện stack mà tôi đang dùng

    • Tôi từng dùng Entity Framework và nó quá chậm
      Vì vậy tôi thay nó bằng Dapper và một hệ thống migration tự viết, kết quả là thời gian kiểm tra DB và seeding lúc khởi động giảm từ 10 giây xuống dưới 2 giây (trong môi trường phần cứng yếu + SQLite)
      Các truy vấn do Entity tạo ra có quá nhiều phép join lồng nhau không cần thiết
      Dạo này tôi đang chuyển sang backend Go đơn giản hơn, còn .NET chỉ dùng cho các giải pháp khác
      Các framework như WPF có quá nhiều vấn đề đến mức phải hack Win32
      Ví dụ, mãi tới .NET 9 nó mới trả về đúng tất cả network interface. Các runtime trước đó chỉ lộ ra các NIC đang hoạt động
      Tôi vẫn còn những dự án phải tiếp tục hỗ trợ Windows 7
    • Tôi nghĩ nhiều dự án đã bị bỏ lại và không thể chuyển sang .NET Core
      Ngay cả với dự án mới, vẫn có trường hợp phải dùng .NET 4.8. Ví dụ, khi build công thức Excel thì phát sinh vấn đề deadlock với async/await
      Ngoài ra, các tính năng tích hợp Windows cũng bị hỏng, nên cùng một lời gọi mạng thì trên 4.8 được xác thực còn trên Core lại thất bại
      Việc migration không hề dễ do sự đổ vỡ tương thích ngược của vô số thư viện
      Hiệu năng đã tốt hơn, nhưng về mặt tính năng thì .NET Framework có cảm giác như đã hóa thạch
      Phải mất 15 năm mới có JSON serializer trong thư viện chuẩn, và cũng không có hỗ trợ cho các định dạng ảnh hiện đại như webp hay heic
      Visual Studio gần như ngày nào cũng hiện thông báo crash
      Tôi từng là fan .NET cuồng nhiệt, nhưng giờ lại nhớ sự dẫn dắt của Anders
  • Trong một side project gần đây, tôi phát triển backend C# REST API bằng VSCode trên macOS và đã deploy lên Linux suốt 3 năm
    Dùng SQLite, EFCore, Minimal API, và trải nghiệm dễ chịu hơn nhiều so với frontend (NextJS/React/MaterialUI, hơn 50 gói npm)

    • Nếu API bắt đầu phức tạp hơn một chút, tôi khuyên dùng thư viện FastEndpoints
      Đây là framework API tôi thích nhất
      Lựa chọn kế tiếp là tổ hợp TS + Hono + Zod-OpenApi + SwaggerUI, nhưng phần thiết lập type context hơi phiền
  • Điều gây ấn tượng với tôi là nền tảng cho việc mã nguồn mở hóa và đa nền tảng hóa của .NET lại là hệ thống build của các bản phân phối Linux

    • Để tôi, với tư cách tác giả bài viết, giải thích trực tiếp: để các maintainer bản phân phối có thể đưa .NET vào native package feed, họ phải tự build nó
      Vì vậy cần một hệ thống build đáp ứng được yêu cầu của họ, và cuối cùng hướng duy nhất là hợp nhất theo mô hình bản phân phối Linux
      Mô hình này đơn giản nhưng hiệu năng kém hơn. Một hệ thống build phân tán có cache sẽ nhanh hơn, nhưng lại không khớp với workflow của maintainer
      Chúng tôi cho rằng tối ưu cho sự đơn giản sẽ tốt hơn trong việc khuyến khích cộng đồng tham gia
      Mục tiêu là để cộng đồng có thể tự build và phát hành trên nhiều nền tảng khác nhau như BSD, S390x
    • Tôi nghĩ .NET giờ đã qua cái giai đoạn có thể hối hận vì chuyển sang mã nguồn mở rồi
      Lượng pull request và các kết quả tích cực trong 10 năm qua thật đáng kinh ngạc
  • Đây là bài viết về kỹ thuật phần mềm gây ấn tượng nhất tôi đọc trong năm nay, và tôi không ngờ nó lại đến từ Microsoft
    Tôi thích các phiên bản .NET gần đây, nhưng từng nghĩ độ vững chắc của nó chỉ là ngẫu nhiên
    Thế nhưng bài này cho thấy những nỗ lực có hệ thống nhằm nâng cao chất lượng (bao gồm cả sơ đồ và ví dụ sử dụng LLM)
    Kể cả nếu sau này mức đầu tư cho những việc như vậy giảm đi, đây vẫn là một ví dụ tốt về “nên làm như thế nào”

  • Những người tham gia dự án này hẳn đã có một trải nghiệm thực sự tuyệt vời

  • Bài viết hay đấy, nhưng tôi nghĩ đội .NET nên bỏ Azure DevOps
    Thời gian chờ trong hàng đợi là nút thắt lớn nhất. Họ nên chạy máy chủ build bare metal

    • Vấn đề không nằm ở bản thân Azure DevOps. Nó cũng chạy được trên bare metal
      Phần cứng Mac kết nối và khởi động rất nhanh
      Chúng tôi tạo mới VM sạch cho mỗi job để đảm bảo tuân thủ và độ ổn định
      Nếu duy trì sẵn các máy nóng đã chuẩn bị trước thì có thể loại bỏ thời gian chờ, nhưng chi phí lại quá cao
      Việc giữ nhiều SKU khác nhau luôn ở trạng thái chờ là không thực tế, nên chúng tôi chọn phương án dung hòa
  • Tôi thắc mắc vì sao Developer Division của Microsoft lại thuộc hàng giỏi nhất ngành, trong khi các bộ phận khác lại trở thành biểu tượng của sự bất tài và quan liêu

    • Vì lý do chính trị và xu hướng chạy theo các lãnh đạo trong ngành
      Từ sau khi Bill rời đi, văn hóa tự nhìn lại chính mình đã biến mất
  • Tôi nghĩ gốc rễ vấn đề là tư duy lấy trừu tượng làm trung tâm khi cố đơn giản hóa những hệ thống phức tạp
    Thay vì cố giải quyết mọi thứ ở tầng trên, cách tiếp cận xây từ tầng thấp lên có thể loại bỏ nhiều vấn đề tận gốc hơn

  • Khi đọc câu “mỗi tháng build 3~4 phiên bản chính và hàng chục SDK band”, tôi đã tự hỏi vì sao lại có nhiều biến thể như vậy

    • Hiện tại .NET 8 (LTS), .NET 9 (hỗ trợ tiêu chuẩn), và .NET 10 (LTS) đang được duy trì đồng thời
      Ngoài ra, mỗi phiên bản còn được build cho SDK/aspnet/runtime trên nhiều nền tảng như x64/arm32/arm64, Linux/macOS/Windows
  • Trước khi Node thịnh hành, .NET từng là một lựa chọn vững chắc để build backend (hiệu năng cũng tốt hơn Node)
    Sau các cuộc tấn công chuỗi cung ứng gần đây trong hệ sinh thái Node, tôi mong nhiều lập trình viên sẽ quay lại với những nền tảng ổn định hơn

    • Tôi không rõ “churn” ở đây nghĩa là gì. Bài này nói về hệ thống build nội bộ, nên tôi không thấy nó liên quan gì đến sự bất ổn
    • .NET vẫn rất tuyệt và ngày càng tốt hơn qua mỗi bản phát hành
      Thay đổi lớn là việc chuyển sang .NET Core, nhưng chuyện đó giờ cũng gần 10 năm rồi
    • Tổ hợp C# + JetBrains Rider là trải nghiệm phát triển khiến tôi hài lòng nhất trong sự nghiệp
    • Từ sau .NET Core 3, tôi hầu như không gặp vấn đề tương thích lớn nào
      Việc cập nhật framework và dependency có hơi phiền một chút, nhưng vẫn nhẹ nhàng hơn nhiều so với cập nhật project React
      Chu kỳ LTS ngắn giúp việc luôn theo kịp phiên bản mới không quá khó. Với nhịp phát triển nhanh, kiểu bảo trì này là chuyện bình thường
    • Với tư cách một tư vấn viên đa ngôn ngữ, tôi mong có thêm nhiều RFP liên quan đến .NET
      Thực tế thì chủ yếu vẫn là Node.js, Java và low-code (iPaaS)
      Dù vậy, nhờ các vấn đề hiệu năng nên thỉnh thoảng tôi vẫn có cơ hội đề xuất C++ addon