Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 35 — Tech debt và legacy modernization

Process Automation and Digital Transformation Bài 35/60

Mở đầu — vì sao bài này quan trọng

Trong hành trình chuyển đổi số, có một sự thật ít người muốn nói thẳng: phần khó nhất không nằm ở việc xây cái mới, mà ở việc gỡ cái cũ. Bạn có thể mua một nền tảng RPA hiện đại, thuê một đội kỹ sư AI giỏi, ký hợp đồng với nhà cung cấp cloud hàng đầu — nhưng nếu hệ thống lõi (core system) của doanh nghiệp vẫn là một khối phần mềm viết cách đây hai mươi năm bằng COBOL, không ai dám đụng vào, không tài liệu, và đang gánh 80% doanh thu, thì mọi sáng kiến số hóa của bạn sẽ va vào bức tường đó.

Đây chính là chủ đề của Bài 35: tech debt (nợ kỹ thuật)legacy modernization (hiện đại hóa hệ thống cũ). Tôi muốn các bạn hiểu rõ ngay từ đầu rằng đây không phải là một bài "kỹ thuật thuần túy" dành riêng cho lập trình viên. Đây là một bài về chiến lược. Một Process Automation Lead hay DT Manager mà không hiểu nợ kỹ thuật và cách xử lý hệ thống legacy thì sẽ liên tục đưa ra những cam kết không thể thực hiện, đốt ngân sách vào những dự án "đập đi xây lại" thất bại, và mất uy tín với ban lãnh đạo.

Hãy hình dung: bạn được giao tự động hóa quy trình phê duyệt khoản vay tại một ngân hàng. Nghe rất "hợp thời". Nhưng khi đào sâu, bạn phát hiện hệ thống core banking đời cũ không có API, dữ liệu khách hàng nằm rải rác ở năm cơ sở dữ liệu khác nhau, và mỗi lần thay đổi một dòng code phải xin phê duyệt của một ủy ban vì rủi ro quá lớn. Bài học này sẽ giúp bạn nhận diện, định lượng và lập kế hoạch xử lý những "khối bê tông" đó một cách thực tế.

Khái niệm cốt lõi

Tech debt là gì — và vì sao nó tích tụ

Tech debt (nợ kỹ thuật) là phép ẩn dụ do Ward Cunningham đặt ra: khi bạn chọn một giải pháp nhanh, dễ, nhưng không tối ưu để kịp tiến độ, bạn đã "vay" một khoản — và sau này phải "trả lãi" dưới dạng bảo trì khó khăn, lỗi phát sinh, và tốc độ phát triển chậm dần.

Nợ kỹ thuật không hẳn là xấu. Vay đúng lúc, có chủ đích, để chiếm thị trường nhanh là hợp lý — giống như doanh nghiệp vay vốn để tăng trưởng. Vấn đề là nợ không có kế hoạch trả (unintentional debt) tích tụ âm thầm qua nhiều năm: lập trình viên cũ nghỉ việc, tài liệu không cập nhật, các bản vá chồng lên nhau. Đến một ngày, không ai dám sửa hệ thống vì "đụng vào là sập".

Có thể phân loại nợ kỹ thuật thành vài nhóm: nợ về code (code rối, lặp lại, không test), nợ về kiến trúc (thiết kế lỗi thời, monolith khổng lồ), nợ về hạ tầng (server cũ, hệ điều hành hết hỗ trợ), và nợ về tri thức (không ai còn hiểu hệ thống vận hành ra sao).

Legacy system — và vì sao hiện đại hóa nó "khó kinh khủng"

Một legacy system là hệ thống cũ vẫn đang vận hành nhưng dựa trên công nghệ lỗi thời. Tại sao gỡ bỏ nó lại khó đến vậy? Có bốn lý do cốt lõi mà tôi muốn bạn ghi nhớ:

Thứ nhất, nó gánh phần lớn doanh thu. Hệ thống core banking COBOL hay SAP R/3 thường xử lý những giao dịch quan trọng nhất, đại diện cho 70–80% doanh thu. Đây không phải một ứng dụng phụ — nó là trái tim đang đập.

Thứ hai, mức chịu rủi ro cực thấp (low risk tolerance). Trong ngân hàng, một lỗi nhỏ có thể khiến hàng triệu giao dịch sai, vi phạm quy định của Ngân hàng Nhà nước, hoặc làm sập hệ thống ATM toàn quốc. Vì vậy mọi thay đổi đều bị soi xét kỹ, làm chậm tốc độ.

Thứ ba, code "spaghetti" (mì sợi rối). Sau hàng chục năm vá víu, logic nghiệp vụ đan xen chằng chịt, không tách bạch được. Sửa một chỗ làm hỏng ba chỗ khác mà không ai lường trước.

Thứ tư, mất tri thức và phụ thuộc nhân lực hiếm. Lập trình viên COBOL ngày nay thường đã ngoài 55–60 tuổi. Khi họ nghỉ hưu, tri thức về hệ thống ra đi cùng họ. Tại Việt Nam, tìm một kỹ sư COBOL giỏi còn khó hơn tìm kỹ sư AI.

Các chiến lược hiện đại hóa — mô hình 7R của Gartner

Khi đối mặt với một hệ thống legacy, bạn không chỉ có hai lựa chọn "giữ" hay "đập bỏ". Gartner đưa ra khung 7R rất hữu ích để cân nhắc:

  • Retain (Giữ lại): chưa động đến, vì chưa đáng hoặc chưa đến lúc.
  • Retire (Khai tử): loại bỏ hệ thống không còn giá trị.
  • Rehost ("Lift and shift"): chuyển nguyên trạng lên hạ tầng mới (thường là cloud) mà không đổi code. Nhanh, rẻ, nhưng không giải quyết nợ gốc.
  • Replatform: chuyển nền tảng kèm vài điều chỉnh nhỏ để tận dụng hạ tầng mới (ví dụ đổi database).
  • Refactor/Rearchitect: viết lại, tái cấu trúc code và kiến trúc — ví dụ tách monolith thành microservices.
  • Rebuild: xây lại từ đầu trên nền tảng mới nhưng giữ phạm vi nghiệp vụ.
  • Replace: thay bằng một sản phẩm thương mại (SaaS, ERP mới).
Không có lựa chọn nào "đúng tuyệt đối". Nghệ thuật của một DT Lead là chọn đúng R cho đúng hệ thống, dựa trên giá trị nghiệp vụ và mức độ rủi ro.

Strangler Fig Pattern — chiến lược "bóp nghẹt" thông minh

Đây là khái niệm quan trọng nhất bạn cần nhớ trong bài này. Strangler Fig Pattern (do Martin Fowler đặt tên, lấy cảm hứng từ cây đa bóp nghẹt) là cách hiện đại hóa dần dần thay vì "big bang" (đập bỏ và thay thế toàn bộ một lần).

Ý tưởng: bạn đặt một lớp trung gian (thường là API gateway) trước hệ thống cũ. Mỗi lần bạn xây xong một chức năng mới hiện đại, bạn định tuyến (route) phần lưu lượng đó sang hệ thống mới, còn lại vẫn đi qua hệ thống cũ. Dần dần, hệ thống mới "bao trùm và bóp nghẹt" hệ thống cũ cho đến khi cái cũ không còn xử lý gì nữa và có thể khai tử an toàn. Cách này giảm rủi ro mạnh vì bạn không bao giờ phải "cắt chuyển" toàn bộ trong một đêm.

Tình huống thực tế

Ví dụ 1: Ngân hàng Việt Nam và core banking 18 năm tuổi

Hãy lấy bối cảnh một ngân hàng tầm trung tại Việt Nam — tôi gọi là "Ngân hàng Phương Đông giả định". Họ chạy một hệ thống core banking triển khai từ 2007, viết phần lớn bằng các module độc quyền của nhà cung cấp, không có API mở. Hệ thống này xử lý khoảng 12 triệu tài khoản và 78% doanh thu giao dịch.

Bối cảnh: Ban lãnh đạo muốn ra mắt app mobile banking mới, tích hợp eKYC và phê duyệt vay nhanh trong 5 phút. Đội số hóa hào hứng, nhưng vướng ngay: core không trả dữ liệu real-time, mỗi truy vấn số dư phải qua một batch job chạy ban đêm.

Diễn giải: Thay vì đề xuất thay core (một dự án 3–5 năm, chi phí hàng chục triệu USD, rủi ro cực cao), CTO chọn Strangler Fig. Họ xây một lớp API middleware đứng trước core, cache dữ liệu nóng (số dư, lịch sử giao dịch gần đây) và đẩy lên thời gian thực qua cơ chế đồng bộ tăng dần. App mobile gọi vào lớp API mới này, không bao giờ chạm trực tiếp vào core. Từng nghiệp vụ — tra cứu số dư, chuyển khoản, mở tài khoản — được "bóc" dần ra ngoài lớp API trong vòng 18 tháng.

Bài học rút ra: Không cần thay tim để cứu bệnh nhân. Một lớp trung gian (anti-corruption layer) cho phép bạn hiện đại hóa trải nghiệm khách hàng mà không động đến core đầy rủi ro. Đây gần như luôn là lựa chọn an toàn hơn so với "big bang replacement".

Ví dụ 2: Cú "big bang" thất bại — bài học từ TSB Bank (Anh)

Đây là một ca thật, rất nổi tiếng trong giới ngân hàng. Năm 2018, ngân hàng TSB tại Anh quyết định di chuyển toàn bộ 5,4 triệu khách hàng từ hệ thống core cũ (thuê của Lloyds) sang nền tảng mới của công ty mẹ Sabadell — trong một lần cắt chuyển duy nhất vào một cuối tuần.

Bối cảnh: Áp lực thoát khỏi hệ thống đi thuê tốn kém khiến TSB chọn cách "big bang" thay vì chuyển dần. Quá trình kiểm thử bị cho là không đủ với khối lượng dữ liệu thật.

Diễn giải: Khi cắt chuyển, hệ thống mới không chịu nổi tải. Gần 2 triệu khách hàng bị khóa khỏi tài khoản, thấy số dư người khác, giao dịch lỗi kéo dài nhiều tuần. Hậu quả: thiệt hại được ước tính khoảng 330 triệu bảng Anh, hàng loạt lãnh đạo từ chức, và uy tín tổn hại nặng nề.

Bài học rút ra: Hiện đại hóa kiểu "đập bỏ toàn bộ và bật cái mới trong một đêm" với hệ thống mission-critical là canh bạc cực kỳ nguy hiểm. Nếu bắt buộc phải làm, kiểm thử với dữ liệu và tải thật, có kế hoạch rollback (quay lui) rõ ràng, và chuyển theo từng nhóm khách hàng (phased rollout) thay vì tất cả cùng lúc.

Ví dụ 3: FPT/doanh nghiệp sản xuất và "ERP rối như mì"

Một doanh nghiệp sản xuất tại Bình Dương (gọi là "Công ty Sao Mai") chạy một hệ thống ERP tự phát triển từ 2010, cộng thêm hàng chục file Excel macro mà các phòng ban tự chế. Khi muốn tự động hóa quy trình mua hàng, đội tư vấn phát hiện không ai trong công ty còn hiểu trọn vẹn luồng dữ liệu.

Bối cảnh: Đây là nợ tri thức điển hình — người viết hệ thống đã nghỉ, không có tài liệu, logic nằm rải rác trong code và cả trong "đầu" vài nhân viên kỳ cựu.

Diễn giải: Trước khi tự động hóa, đội dự án phải làm một bước thường bị bỏ qua: process mining và documentation — dựng lại bản đồ quy trình thực tế từ log hệ thống. Họ phát hiện 40% các bước là thủ công và lặp lại không cần thiết. Sau đó họ áp dụng chiến lược replatform một phần: giữ ERP lõi, nhưng bọc các module mua hàng bằng dịch vụ mới và RPA để cầu nối với những phần chưa thể đụng tới.

Bài học rút ra: Đừng tự động hóa một mớ hỗn loạn — bạn chỉ tạo ra "mớ hỗn loạn tự động hóa nhanh hơn". Phải hiểu và làm sạch quy trình (cùng với việc trả nợ tri thức) trước khi phủ công nghệ lên trên.

Hướng dẫn từng bước

Đây là quy trình thực dụng để bạn tiếp cận một bài toán legacy modernization trong thực tế:

Bước 1 — Lập bản đồ và đánh giá (Assess). Liệt kê toàn bộ hệ thống legacy. Với mỗi cái, ghi rõ: nó gánh bao nhiêu % doanh thu/giao dịch, công nghệ gì, ai còn hiểu nó, mức độ rủi ro nếu sập, và chi phí bảo trì hằng năm.

Bước 2 — Định lượng nợ kỹ thuật. Đừng nói "code tệ lắm". Hãy đo: số sự cố/tháng, thời gian trung bình để thêm một tính năng mới, chi phí bảo trì so với chi phí phát triển mới. Khi bạn đưa ban lãnh đạo con số "mỗi năm tốn 8 tỷ chỉ để giữ hệ thống sống", họ mới hành động.

Bước 3 — Vẽ ma trận giá trị – rủi ro. Đặt mỗi hệ thống vào ma trận 2 chiều: giá trị nghiệp vụ (cao/thấp) và độ khó/rủi ro thay đổi (cao/thấp). Hệ thống giá trị thấp, rủi ro thấp → Retire ngay. Giá trị cao, rủi ro cao (như core banking) → Strangler Fig dần dần.

Bước 4 — Chọn chiến lược R phù hợp. Áp khung 7R cho từng hệ thống. Đa số trường hợp mission-critical, câu trả lời an toàn là Rehost trước để lên cloud, rồi Refactor dần qua Strangler Fig, chứ không Rebuild ngay.

Bước 5 — Xây lớp chống ăn mòn (Anti-Corruption Layer). Đặt API gateway / middleware giữa cái mới và cái cũ, để hai thế giới giao tiếp mà không "lây nhiễm" thiết kế lỗi thời của legacy sang hệ thống mới.

Bước 6 — Triển khai tăng dần, đo liên tục. Bóc từng nghiệp vụ ra. Sau mỗi đợt, đo lại: tốc độ, lỗi, sự hài lòng. Luôn giữ khả năng rollback.

Bước 7 — Khai tử khi đã an toàn. Khi không còn lưu lượng nào đi qua module cũ, mới tắt nó. Đừng vội tắt.

Lỗi thường gặp & mẹo

Lỗi 1 — Mê tín "big bang rewrite". Đội kỹ thuật thường muốn "viết lại từ đầu cho sạch". Nhưng các dự án rewrite toàn bộ có tỷ lệ thất bại rất cao. Mẹo: mặc định ưu tiên cách tăng dần (Strangler Fig), chỉ rewrite khi hệ thống đủ nhỏ và rủi ro thấp.

Lỗi 2 — Tự động hóa quy trình hỏng. Phủ RPA lên một quy trình rối rắm chỉ làm cái rối chạy nhanh hơn. Mẹo: làm sạch và chuẩn hóa quy trình trước, tự động hóa sau.

Lỗi 3 — Không định lượng nợ, nên không được duyệt ngân sách. Ban lãnh đạo không tài trợ cho thứ mơ hồ. Mẹo: luôn quy nợ kỹ thuật ra tiền và rủi ro kinh doanh cụ thể.

Lỗi 4 — Bỏ qua nợ tri thức. Bạn tập trung vào công nghệ mà quên rằng người hiểu hệ thống sắp nghỉ. Mẹo: ưu tiên ghi lại tài liệu, dùng process mining để dựng lại quy trình từ dữ liệu thực trước khi quá muộn.

Lỗi 5 — Không có kế hoạch rollback. Như TSB, cắt chuyển mà không thể quay lui là tự sát. Mẹo: mọi bước chuyển đổi phải có nút "undo" và chạy song song (parallel run) một thời gian.

Mẹo vàng: Hãy coi hiện đại hóa là một hành trình liên tục, không phải dự án có điểm kết. Phân bổ đều đặn khoảng 15–20% năng lực đội ngũ cho việc "trả nợ kỹ thuật" mỗi sprint, để nợ không tích tụ lại từ đầu.

Bài tập thực hành

  • Lập bản đồ nợ: Chọn một hệ thống bạn biết (tại nơi làm việc hoặc một ví dụ giả định). Liệt kê 5 khoản nợ kỹ thuật của nó, phân loại theo 4 nhóm (code, kiến trúc, hạ tầng, tri thức).
  • Định lượng: Với một trong các khoản nợ đó, hãy ước tính chi phí "trả lãi" hằng năm bằng tiền (giờ công bảo trì, số sự cố, tốc độ chậm lại). Viết một câu thuyết phục ban lãnh đạo duyệt ngân sách.
  • Chọn chiến lược R: Cho ba hệ thống giả định — (a) app chấm công nội bộ ít người dùng, (b) core banking gánh 80% doanh thu, (c) website tin tức cũ — hãy chọn một trong 7R cho mỗi cái và giải thích lý do.
  • Thiết kế Strangler Fig: Vẽ sơ đồ cách bạn sẽ đặt một API middleware trước một hệ thống core cũ để bóc dần nghiệp vụ "tra cứu số dư" ra ngoài. Chỉ rõ điểm route lưu lượng và kế hoạch rollback.

Tóm tắt

Hiện đại hóa hệ thống legacy là phần khó nhất, nhưng cũng quyết định nhất của chuyển đổi số. Hãy nhớ những điều cốt lõi: nợ kỹ thuật tích tụ âm thầm và phải được định lượng ra tiền thì mới xử lý được. Hệ thống legacy mission-critical khó thay vì nó gánh phần lớn doanh thu, mức chịu rủi ro thấp, code rối như mì, và tri thức về nó đang mai một. Đừng mơ "big bang rewrite" — bài học TSB cho thấy cái giá có thể lên đến hàng trăm triệu USD. Thay vào đó, dùng khung 7R để chọn đúng chiến lược cho từng hệ thống, và ưu tiên Strangler Fig Pattern cùng lớp chống ăn mòn để hiện đại hóa dần dần, an toàn, có thể rollback. Và trên hết: đừng tự động hóa một quy trình hỗn loạn — hãy làm sạch nó trước. Một DT Lead giỏi không phải người đập bỏ nhanh nhất, mà là người gỡ nợ một cách điềm tĩnh, có chiến lược, và không làm sập trái tim đang đập của doanh nghiệp.