Sổ tay Kiến trúc Phần mềm
01 Phần I · Nền tảng Chương 1 & 2

Tư duy kiến trúc

Architectural Thinking

Kiến trúc là thứ bạn không Google được — mọi câu trả lời đều là "còn tùy". Nghề này không có đúng/sai, chỉ có những đánh đổi và lựa chọn "ít tệ nhất".

01 Kiến trúc phần mềm là gì?

Không chỉ là "bản vẽ" hay "lộ trình". Theo Richards & Ford, kiến trúc phần mềm là sự kết hợp của 4 thành phần — nói mỗi cấu trúc thì chưa mô tả được kiến trúc.

Cấu trúc

Structure

Phong cách kiến trúc hệ thống đang dùng (microservices, layered, microkernel…).

Đặc tính kiến trúc

Architecture Characteristics

Tiêu chí thành công, thường không thuộc nghiệp vụ — các "-ilities": khả dụng, mở rộng, hiệu năng.

Quyết định kiến trúc

Architecture Decisions

Quy tắc cứng khi xây hệ thống. Vd: lớp giao diện không được gọi thẳng cơ sở dữ liệu.

Nguyên lý thiết kế

Design Principles

Hướng dẫn mềm (khuyến khích, không bắt buộc). Vd: nên nhắn tin bất đồng bộ giữa các service.

Quyết định = luật, Nguyên lý = hướng dẫn. Quyết định ràng buộc "được/không được"; nguyên lý chỉ ra hướng ưu tiên nhưng để dev tự chọn cách phù hợp tình huống.

02 Kiến trúc vs Thiết kế

Kiến trúc kết thúc ở đâu và thiết kế bắt đầu ở đâu? Không có ranh giới đó — cả hai cùng một vòng đời và phải luôn đồng bộ.

Richards & Ford

Ranh giới giữa hai vai trò là mờ. Vấn đề nằm ở mô hình cũ — và cách sửa nó:

Mô hình một chiều (hỏng)

  • KTS vẽ xong "ném qua tường" cho dev.
  • Quyết định của KTS không tới được đội code; thay đổi của dev không quay lại KTS.
  • KTS tách rời thực tế → kiến trúc không còn đúng mục đích.

Cộng tác hai chiều (đúng)

  • KTS & dev cùng một đội ảo, trao đổi liên tục.
  • Kiến trúc tiến hóa mỗi vòng lặp, luôn đồng bộ với code.
  • KTS kèm cặp (mentoring) đội phát triển ngay trong quá trình.

03 Bề rộng vs Bề sâu kỹ thuật

Khi chuyển từ dev sang KTS, giá trị dịch chuyển từ biết sâu một thứ sang biết rộng nhiều thứ — để chọn đúng giải pháp theo ràng buộc.

Kim tự tháp kiến thức

Điều bạn BIẾT stuff you know Biết mình KHÔNG biết know you don't know KHÔNG biết mình không biết don't know you don't know phạm vi (breadth) tăng
Bề sâu (depth) = bạn biết kỹ tới đâu (đỉnh tháp). Bề rộng (breadth) = bạn biết nhiều tới đâu (cả tháp). KTS nên hi sinh bớt bề sâu để mở rộng "ống tên" giải pháp — tầng đáy (không biết mình không biết) mới là nơi ẩn giải pháp tốt nhất.

Hai cái bẫy của tư duy

Frozen Caveman

người hang động đóng băng

Luôn lôi một nỗi sợ phi lý trong quá khứ ra áp cho mọi kiến trúc ("nhỡ mất kết nối Ý thì sao?"). Phải phân biệt rủi ro thật với rủi ro tưởng tượng.

Stale Expertise

chuyên môn lỗi thời

Tưởng kiến thức cũ của mình vẫn đỉnh, ra quyết định theo tiêu chí đã lạc hậu.

RAG  Bề rộng cho RAG: giá trị của KTS không phải rành một vector store, mà biết đủ rộng — pgvector vs Qdrant vs Pinecone, OpenAI vs embedding chạy nội bộ — để chọn theo ràng buộc (chi phí, quy mô, riêng tư), không phải vì "quen tay".

04 Hai định luật kiến trúc

Mọi thứ trong kiến trúc phần mềm đều là đánh đổi. Nếu thấy thứ gì không phải đánh đổi, nhiều khả năng bạn chưa nhận ra nó thôi.

Định luật 1 · First Law of Software Architecture

"Lập trình viên biết ưu điểm của mọi thứ và đánh đổi của không gì cả. KTS phải hiểu cả hai." Ví dụ kinh điển — hệ đấu giá gửi bid: dùng Topic (pub-sub) hay Queue (điểm-điểm)?

Khía cạnhTopic (pub-sub)Queue (point-to-point)
Ưu điểmMở rộng kiến trúc (extensibility); service tách rời (decoupling).Bảo mật tốt hơn; hợp đồng dữ liệu riêng từng consumer; dễ giám sát tải.
Nhược điểmKhó kiểm soát truy cập & bảo mật dữ liệu; chỉ hợp đồng đồng nhất; khó giám sát/auto-scale.Gắn kết (coupling) cao hơn; khó thêm chức năng mới.

Cái nào tốt hơn? Còn tùy. Tư duy kiến trúc = soi cả ưu lẫn nhược rồi hỏi "cái nào quan trọng hơn với bối cảnh này: mở rộng hay bảo mật?".

RAG  Đúng định luật 1 — nạp tài liệu (ingest): PHP gọi Python đồng bộ hay bất đồng bộ?

Đồng bộ

  • Đơn giản; biết ngay kết quả/lỗi.
  • Nhược: PHP bị block lâu (embed chậm), dễ timeout, kém chịu tải.

Bất đồng bộ

  • PHP trả lời ngay; chịu tải; co giãn worker.
  • Nhược: phức tạp hơn; phải theo dõi trạng thái job; khó báo lỗi tức thì.
PHP · hai cách gọi ingest
// Đồng bộ — chờ tới khi index xong (đơn giản, nhưng block & dễ timeout)
$res = $http->post('/ingest', ['doc_id' => $id]);   // chờ 30s…

// Bất đồng bộ — đẩy job, trả lời ngay (chịu tải, nhưng phải theo dõi trạng thái)
$queue->push(new IngestJob($id));                    // Python worker xử lý nền
return response()->json(['status' => 'queued']);

Tại sao (Why) quan trọng hơn Như thế nào (How).

Định luật 2 · Second Law of Software Architecture

Nhìn một hệ thống lạ, ta dễ thấy nó hoạt động thế nào; nhưng khó biết vì sao chọn vậy. Ghi lại cái "vì sao" mới là cốt lõi của tài liệu kiến trúc.

ADR · ghi lại WHY (cho RAG)
# ADR-007: Chọn pgvector thay vì Pinecone
WHY: dữ liệu nội bộ + đã có Postgres → giảm hạ tầng & chi phí;
     quy mô < 5M vector, độ trễ chấp nhận được.
# Không ghi WHY → một năm sau không ai biết vì sao, sửa mù quáng.

05 Tám kỳ vọng với kiến trúc sư

Bất kể chức danh — đây là 8 điều cốt lõi mà một KTS hiệu quả cần làm được. Nửa số đó là kỹ năng con người, không phải kỹ thuật.

Ra quyết định

make decisions

Định ra quyết định & nguyên lý để dẫn dắt lựa chọn công nghệ, không chỉ định cứng.

Liên tục phân tích

analyze continually

Đánh giá "sức sống" kiến trúc trước thay đổi của nghiệp vụ & công nghệ, chống phân rã cấu trúc.

Cập nhật xu hướng

keep current

Quyết định của KTS khó đổi & lâu dài → phải bám xu hướng để chọn đúng.

Đảm bảo tuân thủ

ensure compliance

Xác minh đội phát triển đi đúng các quyết định & nguyên lý đã định.

Trải nghiệm đa dạng

diverse exposure

Quen nhiều nền tảng/ngôn ngữ (bề rộng) — vd biết 10 sản phẩm cache hơn là rành đúng 1.

Hiểu nghiệp vụ

business domain

Không có kiến thức domain thì khó giao tiếp với stakeholder & thiết kế sát thực tế.

Kỹ năng con người

interpersonal skills

Lãnh đạo, làm việc nhóm, điều phối — "luôn là vấn đề con người".

Điều hướng chính trị

navigate politics

Gần như mọi quyết định sẽ bị thách thức → cần thương lượng để đạt đồng thuận.

06 Ghi nhớ nhanh

Kiến trúc là thứ không Google được — câu trả lời luôn là "còn tùy" vào ngữ cảnh.

Không có đúng/sai, chỉ có đánh đổi — đừng nhắm kiến trúc "tốt nhất", hãy nhắm "ít tệ nhất" (least worst).

Đừng làm KTS "tháp ngà" — vẫn lập trình (POC, nợ kỹ thuật, sửa lỗi) để giữ kết nối thực tế & bề sâu.

Bề rộng là "ống tên" của KTS — càng nhiều mũi tên (giải pháp) càng linh hoạt khi gặp vấn đề.

Why > How — ghi lại vì sao quyết định (ADR) quan trọng hơn mô tả cách hệ thống chạy.

NguồnChương 1 (Introduction) & Chương 2 (Architectural Thinking), Fundamentals of Software Architecture — Mark Richards & Neal Ford, O'Reilly 2020.