System Design .NET A -> Z: Series này dạy gì cho bạn
Giới thiệu series 26 chương về thiết kế hệ thống cho lập trình viên .NET. Bao gồm cấu trúc 7 câu hỏi mỗi chương, stack .NET 10, và cách đọc.
Mục lục
Bạn có thể viết C# sạch suốt mười năm và vẫn đứng hình khi ai đó hỏi "thiết kế Twitter đi". Không phải vì bài toán khó, mà vì thiết kế hệ thống là một kỹ năng khác với viết code. Kỹ năng ấy là chọn - chọn database nào, cache nào, queue nào, lỗi nào nuốt và lỗi nào trả về. Series này dạy kỹ năng chọn đó qua hai mươi sáu chương, mỗi chương kết thúc bằng một bản triển khai .NET 10 chạy được, không dừng ở sơ đồ trên bảng trắng.
Thiết kế hệ thống là gì và vì sao quan trọng với .NET engineer?
Thiết kế hệ thống là việc bạn làm trước commit đầu tiên trên một
service mới: chọn data store, kiểu giao tiếp, cache, queue, hình thức
deploy. Quyết định ở giai đoạn này là quyết định đắt nhất khi muốn đảo
ngược sáu tháng sau. Đổi một List<T> sang HashSet<T> mất 15
phút; đổi PostgreSQL sang Cassandra mất một quý.
Riêng với .NET engineer, kỹ năng này quan trọng vì hệ sinh thái .NET giấu rất nhiều quyết định thiết kế sau những default hợp lý - EF Core mặc định cho bạn relational database, ASP.NET Core mặc định cho HTTP, MediatR mặc định cho messaging trong process. Những default ấy đúng phần lớn thời gian. Các chương trong series này nói về phần thời gian không đúng: khi tải đọc đòi cache, khi tải ghi đòi queue, khi mô hình nhất quán đòi outbox.
System design khác gì so với design pattern?
Design pattern hoạt động bên trong một process. Singleton, Decorator, Mediator - đó là quyết định về class và method. System design hoạt động giữa các process: một service nói chuyện với service khác qua mạng, một database shard ra nhiều node, một queue làm bộ đệm cho biến động giữa producer và consumer. Hai kỹ năng xếp tầng.
flowchart TB
subgraph SD["System design - giữa các process"]
Svc[Service A] -->|HTTP / gRPC| SvcB[Service B]
Svc --> Q[(Queue)]
Svc --> Cache[(Cache)]
Svc --> DB[(Database)]
end
subgraph DP["Design pattern - bên trong một process"]
Ctrl[Controller] --> Med[Mediator]
Med --> Hdl[Handler]
Hdl --> Repo[Repository]
Repo --> Dec[Decorator: Logging+Retry]
end
SD -.dùng.-> DP
Bên trong Service A, bạn có thể dùng Mediator + Decorator +
Repository. Giữa Service A và Service B, bạn chọn REST hay gRPC,
đồng bộ hay queue, nhất quán mạnh hay nhất quán cuối cùng. Cả hai
tầng đều có mặt trong mọi ứng dụng .NET thật; series này lấp khoảng
trống ở tầng trên design pattern.
Bảy câu hỏi mỗi chương trả lời là gì?
Series dùng cùng một khuôn để bạn lướt một chương trong sáu mươi giây. Mỗi bài đi qua bảy câu hỏi:
- Khi nào bài toán này thật sự xuất hiện? - triệu chứng thật ở production, không phải định nghĩa giáo khoa.
- Các con số ước lượng nhanh là bao nhiêu? - QPS, dung lượng, băng thông, ngân sách độ trễ. Số cụ thể, không phải "nhiều".
- Kiến trúc tối thiểu một node trông thế nào? - bản đơn giản nhất chạy được, trước khi nói chuyện scale.
- Bản scale-out trông thế nào và đánh đổi gì? - bảng trade-off thường xuất hiện trong phỏng vấn.
- Phần triển khai .NET 10 cụ thể ra sao? - thư viện, đoạn cấu
hình
Program.cs, code EF Core / Redis / RabbitMQ. - Failure mode nào và quan sát ra sao? - cái gì hỏng trước, metric nào bắt được.
- Khi nào không nên dùng? - dấu hiệu over-engineer, trường hợp giữ nguyên đơn giản là đúng.
H2 kết thúc bằng ? vì đó là pattern mà các engine AI và search
engine match cho khối "answer". Format này còn là kỷ luật - nếu bạn
không đặt được tiêu đề thành câu hỏi, có lẽ đoạn đó không nói gì cả.
Series dạy bạn giải những bài toán nào?
Hai mươi sáu chương chia thành sáu nhóm. Đọc mục dưới để thấy mỗi chương xử lý gì:
- Foundations (3 bài) - từ vựng về scale, số học ước lượng nhanh, CAP và mô hình nhất quán. Những thứ này xuất hiện trong mọi chương khác.
- Building blocks (6 bài) - các công cụ .NET cụ thể bạn với tay vào: Redis cache, chọn SQL hay NoSQL, message queue, REST vs gRPC vs GraphQL, tích hợp Elasticsearch, và JWT vs cookie.
- Reliability (3 bài) - idempotency và outbox pattern, circuit breaker với Polly, và saga cho transaction phân tán.
- Observability & ops (2 bài) - OpenTelemetry trong .NET và rate limit bằng middleware có sẵn.
- Case studies (9 bài) - thiết kế đầu cuối cho URL shortener, rate limiter, news feed, chat realtime, notification, upload file, typeahead, thanh toán, và pipeline event analytics.
- Wrap-up (2 bài) - cách trả lời phỏng vấn system design và bài tổng kết chứa các bài học còn lại sau mọi chương.
Case study là phần dễ trùng nguyên văn với câu hỏi phỏng vấn nhất. Chúng được viết để bạn dùng theo cả hai cách: đọc kiến trúc cho phỏng vấn, đọc phần .NET cho dự án thứ hai sau đó.
Đọc theo bài toán hay đọc tuần tự?
Hai lối đọc, đều hợp lệ.
Theo bài toán - mở chương gọi đúng triệu chứng bạn có hôm nay. Nếu cache invalidation đang giết bạn, vào thẳng caching. Nếu webhook Stripe trừ tiền hai lần, vào idempotency. Mỗi chương tự đứng được và có link tới và lui đến những chương cung cấp ý tưởng nó dựa vào.
Tuần tự - đọc 00 đến 25. Thứ tự này có chủ đích: nền tảng đặt trước vì các chương sau đều dẫn lại số liệu của nó, building blocks tiếp theo vì case study lắp ghép từ chúng, rồi case study như bài test tích hợp cho mọi thứ trước đó. Toàn series mất khoảng một tuần buổi tối; phần thưởng là nhận ra cùng một thành phần được tái sử dụng trong chín bối cảnh khác nhau.
// Ví dụ một building block tái dùng nhiều case study:
// AddRedisCaching dây cùng IDistributedCache cho URL shortener,
// rate limiter và news feed.
builder.Services.AddStackExchangeRedisCache(opt =>
{
opt.Configuration = builder.Configuration.GetConnectionString("Redis");
opt.InstanceName = "anhtu-dev:";
});
Cùng năm dòng đăng ký này xuất hiện ở ba chương case study. Đó chính là điểm cốt - series dạy bạn một bảng chữ cái nhỏ, rồi cho thấy chín câu khác nhau bạn ghép được từ bảng chữ cái ấy.
Series giả định stack .NET 10 nào?
Mọi chương dùng cùng baseline để bạn copy code giữa các chương mà không phải chuyển đổi. Stack gồm:
- .NET 10 với ASP.NET Core, mặc định Minimal API, dùng Razor hoặc controller khi chương cần.
- EF Core 10 cho dữ liệu quan hệ, dùng PostgreSQL làm database tham chiếu (cú pháp SQL đủ chung để chạy trên SQL Server hay MySQL).
- StackExchange.Redis bọc qua
IDistributedCachecho cache. - MassTransit trên RabbitMQ cho queue; Azure Service Bus xuất hiện khi chương nói riêng về queue cloud quản lý.
- Polly cho retry và circuit breaker, ngày càng dùng qua bộ
Microsoft.Extensions.Http.Resiliencecó sẵn. - OpenTelemetry cho trace, metric, log; Serilog cho log sink, Prometheus hoặc Azure Monitor cho metric.
- MediatR khi chương cần pub-sub trong process; còn lại dùng DI trần.
Series không giả định cloud cụ thể. Khi công cụ riêng của Azure (Service Bus, Cosmos DB) hữu ích, các lựa chọn AWS hoặc self-host cũng được liệt kê.
Bạn nên bắt đầu từ đâu vào ngày mai?
Có mười phút thì đọc scale vocabulary - đó là từ điển mà mọi chương sau dùng tới. Có một giờ thì đọc thêm back-of-envelope và chọn một case study trùng dự án bạn đang làm. Có một tuần thì đọc 00 đến 14 - đoạn đó đi hết mọi building block và reliability pattern, sau đó case study đọc nhanh hơn nhiều.
Series không phải sách giáo khoa cần đọc xong; nó là tài liệu tham chiếu cần để mở. Các pattern sẽ xuất hiện trong code review, phỏng vấn và post-mortem incident của bạn. Biết tên cho phép bạn mô tả thiết kế trong một đoạn văn thay vì năm file mã nguồn.
Chào mừng bạn lên tàu.