0

Git Worktree vào hệ sinh thái Microservices Bài 1: Nỗi ám ảnh "Context Switching" trong hệ thống nhiều Microservices

Trong các dự án Monolith nhỏ lẻ, việc chuyển nhánh (git checkout) diễn ra khá nhẹ nhàng. Tuy nhiên, khi bước vào một hệ sinh thái Microservices quy mô lớn (từ 10 đến hàng chục services cùng hoạt động), mỗi lần phải chuyển ngữ cảnh làm việc (Context Switching) lại trở thành một cơn ác mộng thực sự về mặt thời gian và hiệu suất.

1. Kịch bản thực tế: Một buổi chiều "bão táp" của Backend Developer

Hãy tưởng tượng bạn đang tập trung cao độ để phát triển tính năng Tích điểm thành viên mới (Loyalty V2). Tính năng này khá lớn và đòi hỏi bạn phải sửa code đồng thời trên 3 services:

  1. API-Gateway: Cập nhật route và middleware xác thực mới.

  2. Order-Service: Thay đổi cấu trúc payload bắn qua Kafka sau khi đơn hàng hoàn tất.

  3. Payment-Service: Thêm bảng mới trong Database (đã chạy migrate ở local) và viết dở 500 dòng logic tính toán chiết khấu chưa kịp chạy pass unit test.

Đúng lúc bạn đang ở trạng thái "in the zone", có 2 việc đột xuất ập đến cùng lúc:

  • Việc 1 (Khẩn cấp): Hệ thống Production báo lỗi thanh toán bị treo ở một trường hợp biên (edge-case). Sếp yêu cầu bạn nhảy vào nhánh main/production của Payment-Service để kiểm tra và làm bản Hotfix ngay lập tức.

  • Việc 2: Một đồng nghiệp nhắn tin nhờ bạn pull nhánh feature/refund-flow về chạy thử dưới local để Review PR giúp họ vì tính năng đó sắp phải merge.

Lúc này, với quy trình Git truyền thống, bạn sẽ xử lý như thế nào trên đống code đang viết dở ở cả 3 services?

2. Những cách xử lý truyền thống và "Tác dụng phụ" đi kèm

Khi đối mặt với tình huống trên, đa số lập trình viên sẽ chọn một trong hai cách sau, và cả hai đều mang lại những phiền toái lớn:

Cách 1: Lạm dụng git stash hoặc tạo "WIP Commit"

Để chuyển từ nhánh feature/loyalty-v2 sang nhánh hotfix/payment-stuck, bạn phải cất tạm code đang viết dở đi:

Bash

# Tại Payment-Service
git add .
git stash save "WIP: dang code do loyalty v2"
git checkout main
git checkout -b hotfix/payment-stuck

Vấn đề phát sinh trong Microservices:

  • Lệch pha Database & Migration: Ở nhánh feature/loyalty-v2, bạn đã chạy migration thêm cột mới hoặc sửa kiểu dữ liệu trong MySQL/PostgreSQL. Khi checkout về main để sửa hotfix, code cũ không tương thích với schema DB mới. Bạn buộc phải rollback migration trước khi stash, hoặc chấp nhận lỗi DB liên tục.

  • Lệch pha Dependencies: Nhánh feature vừa cài thêm thư viện mới (cập nhật vendor trong PHP/Laravel, node_modules trong Node.js, hoặc go.mod trong Golang). Khi về main, bạn lại phải chạy lại lệnh cài đặt để đồng bộ phiên bản cũ, gây mất thời gian chờ đợi.

  • Hội chứng "Não cá vàng" với Stash: Khi bạn phải git stash trên cả 3 repo (Gateway, Order, Payment), chỉ sau 1-2 tiếng sửa hotfix căng thẳng, bạn rất dễ quên mất mình đã stash những gì ở repo nào, hoặc git stash pop nhầm nhánh dẫn đến xung đột (conflict) cực kỳ mất công dọn dẹp.

Cách 2: Clone dự án ra nhiều thư mục khác nhau

Để né git stash, nhiều người chọn giải pháp "thô nhưng thật": Clone thêm một bản copy hoàn toàn mới của repo ra ổ cứng.

Plaintext

workspace/
├── payment-service/             (Đang ở nhánh feature/loyalty-v2)
├── payment-service-hotfix/      (Clone mới để sửa hotfix)
└── payment-service-review-pr/   (Clone mới để review code)

Vấn đề phát sinh trong Microservices:

  • Lãng phí dung lượng và băng thông: Với những dự án lâu năm có lịch sử commit dày đặc, mỗi thư mục .git có thể nặng từ vài trăm MB đến vài GB. Nhân lên với 10-20 services, ổ cứng của bạn sẽ nhanh chóng bị lấp đầy bởi những dữ liệu trùng lặp.

  • Bất đồng bộ lịch sử Git (Local Objects): Khi bạn git fetch ở thư mục payment-service, thư mục payment-service-hotfix hoàn toàn không biết gì về các nhánh hay commit mới đó. Bạn phải lặp lại thao tác fetch/pull ở từng thư mục độc lập.

3. Bảng so sánh chi phí khi Context Switching

Để thấy rõ sự khác biệt, hãy đặt hai phương pháp truyền thống lên bàn cân với giải pháp mà chúng ta sẽ hướng tới trong Series này — Git Worktree:

Tiêu chí Dùng git stash & checkout git clone nhiều thư mục Dùng Git Worktree
Thời gian chuyển ngữ cảnh Chậm (Phải stash, đổi nhánh, cài lại lib, rollback DB) Trung bình (Mất thời gian clone ban đầu) Tức thì (Chỉ cần mở cửa sổ IDE/Terminal ở thư mục khác)
Dung lượng ổ cứng (.git) Tối ưu (Chỉ 1 thư mục .git) Rất tốn kém (Nhân bản .git ở mỗi nơi) Tối ưu (Dùng chung duy nhất 1 thư mục .git gốc)
Đồng bộ lịch sử Git (fetch) Tự động dùng chung Phải fetch thủ công ở từng thư mục Tự động dùng chung toàn bộ lịch sử và commit
Giữ nguyên trạng thái đang chạy Không (Phải dừng server/debug đang chạy) Có Có (Code feature vẫn giữ nguyên 100% trạng thái)
Độ an toàn (Tránh nhầm nhánh) Thấp (Dễ pop stash nhầm nhánh) Trung bình Rất cao (Git cấm mở trùng 1 nhánh trên 2 worktree)
  1. Tư duy mới: "Mỗi tác vụ là một không gian vật lý độc lập" Thay vì ép bộ não và chiếc máy tính của bạn phải liên tục "xóa đi viết lại" trên cùng một thư mục làm việc duy nhất, Git Worktree cho phép bạn biến một Repository duy nhất thành nhiều không gian làm việc vật lý (Working Directories) hoàn toàn tách biệt nhưng vẫn dùng chung một "bộ não" .git ở bên dưới.

Lúc này, khi có yêu cầu Hotfix ập đến:

Bạn giữ nguyên cửa sổ VS Code / Cursor đang code dở nhánh feature/loyalty-v2 (không cần lưu, không cần stash, không cần tắt terminal đang chạy).

Chỉ với 1 dòng lệnh mất chưa tới 2 giây, bạn tạo ra một thư mục worktree mới tinh dành riêng cho nhánh hotfix.

Mở một cửa sổ IDE mới vào thư mục hotfix, sửa lỗi, test, push code lên, sau đó xóa thư mục hotfix đi và quay lại cửa sổ feature code tiếp đúng dòng code đang gõ dở!

Tóm tắt Bài 1 & Chuẩn bị cho Bài 2 Qua bài đầu tiên, chúng ta đã thấy rõ "nỗi đau" khi phải xử lý đa tác vụ trong kiến trúc Microservices và lý do vì sao git stash hay git clone không còn đủ tốt khi hệ thống phình to.

Ở Bài 2: Giải phẫu Git Worktree: Một thư mục .git, đa không gian làm việc, chúng ta sẽ đi sâu vào bên dưới nắp capo để xem Git thực sự liên kết các thư mục này như thế nào thông qua HEAD, index và con trỏ file, giúp bạn nắm vững bản chất trước khi gõ những dòng lệnh đầu tiên.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí