FDE PulseViệc làm FDE đang mở 639Mới trong 7 ngày 49Công ty đang tuyển 98Nhận làm từ xa 24%Lương trung vị (Mỹ) $203kTuyển nhiều nhất Databricks 122
EN

Tờ báo của nghề Forward Deployed Engineer

Bách khoa

Khi kiến trúc sư của khách nói thiết kế sẽ sập: biến cuộc tranh luận thành một bài load test chung

Không ai thắng được bằng lời một cuộc tranh cãi về chuyện chưa xảy ra, nhưng hai bên có thể chốt nó bằng một ngưỡng đạt/trượt cùng ký trước khi bấm chạy.

Các kỹ sư đứng quanh bảng trắng trong phòng họp, cùng phác thảo và thảo luận sơ đồ kiến trúc hệ thống.
Ảnh: Kaleidico / Unsplash
Chia sẻLinkedInFacebookX

Tóm tắt nhanh

  • Đừng tranh luận chuyện hệ thống có sập hay không. Hãy cùng khách viết ra cách đo để biết nó sập ở đâu.
  • Chốt ngưỡng, dùng môi trường giống production và dữ liệu đủ lớn, test từng thành phần rồi mới test toàn hệ thống.
  • Đẩy tải vượt mức kỳ vọng, đo cả khả năng hồi phục, rồi ghi quyết định vào ADR.
Biểu đồ đường số người dùng đồng thời theo thời gian trong kịch bản k6 ba pha: baseline 50 người dùng trong 15 phút với ngưỡng p95 dưới 800 ms, stress tăng lên 200 từ phút 15 đến 30 để tìm điểm gãy, recovery 25 người dùng từ phút 30 đến 40. Điểm gãy được đánh dấu ở khoảng 140 người dùng, nơi p95 vọt lên.
Chỉ pha baseline và recovery có ngưỡng đạt/trượt. Pha stress chạy để tìm ra trần của thiết kế. Nguồn: kịch bản k6 và kết quả giả định trong bài.

Cuộc họp review kiến trúc đã kéo dài 40 phút. Bạn vừa trình bày thiết kế dịch vụ tìm kiếm tài liệu sẽ deploy ở phía khách thì kiến trúc sư trưởng của họ khoanh tay: “Mọi request đều đi đồng bộ qua một database. Giờ cao điểm là sập.”

Bạn tin thiết kế của mình ổn, còn anh ấy tin nó sẽ sập. Hai người đang cãi về một chuyện chưa xảy ra nên không ai thắng được bằng lời, và cãi thêm phút nào thì khách bớt tin bạn phút đó.

Cãi hay hơn không giải quyết được gì. Thay vào đó, bạn mời anh ấy cùng thiết kế chính bài kiểm tra có thể chứng minh anh ấy đúng. Đây là kỹ năng phân biệt một FDE giỏi với người chỉ biết viết code: biến bất đồng thành một thí nghiệm mà hai bên đã thống nhất cách chấm điểm từ trước.

Vì sao một bài test lại hạ nhiệt được cuộc cãi vã?

Vì nó đổi câu hỏi. “Có sập không” là chuyện niềm tin. “Sập ở mức tải nào, thành phần nào gãy trước” là câu hỏi kỹ thuật, và kỹ sư nào cũng muốn biết đáp án.

Với Google, phải biết giới hạn của hệ thống thì mới vận hành nó an toàn được. Sách SRE của họ viết thẳng rằng kỹ sư dùng stress test để tìm giới hạn của một web service, và load test chỉ ra điểm gãy, một kiến thức nền tảng cho capacity planning.

Như vậy, lời cảnh báo của kiến trúc sư không phải là thứ gây phiền. Đó là một yêu cầu kiểm thử chưa ai viết ra.

Khi bạn nói “anh nói đúng, mình chưa biết điểm gãy ở đâu, mình cùng tìm nhé”, anh ấy không còn là người phản biện mà thành đồng tác giả. Kết quả thế nào thì anh ấy cũng đã đồng ý với cách đo từ đầu.

Ngưỡng phải được ký trước khi bấm chạy

Sai lầm tai hại nhất là chạy test trước rồi mới bàn xem kết quả nghĩa là gì. Lúc đó bên nào cũng đọc biểu đồ theo hướng có lợi cho mình. AWS Well-Architected xếp đúng chuyện này vào anti-pattern: không định nghĩa yêu cầu hiệu năng rõ ràng, đo được, như response time, throughput và mục tiêu khả năng mở rộng.

Grafana k6 có sẵn cơ chế cho việc này là threshold, tức tiêu chí đạt/trượt bạn khai báo cho từng metric. Ngưỡng nằm ngay trong file test, nên điều hai bên đã đồng ý được lưu trong version control chứ không chỉ là một dòng trong biên bản họp.

Việc thứ hai cần chốt là chạy ở đâu. AWS cảnh báo môi trường test thu nhỏ có thể dự đoán sai hành vi trên production. Nếu bạn chạy trên một máy staging bé xíu và hệ thống trụ được, kiến trúc sư hoàn toàn có lý khi bác kết quả, nên hãy để chính anh ấy chọn môi trường.

Một ví dụ làm từ đầu đến cuối

Hãy hình dung tình huống trên với vài con số giả định. Sau 20 phút làm việc, hai bên thống nhất tải bình thường là 50 người dùng đồng thời, còn giờ cao điểm mà kiến trúc sư lo là gấp bốn lần. Ngưỡng đạt ở tải bình thường là p95 dưới 800 ms và tỉ lệ lỗi dưới 1%.

Kiến trúc sư thêm một câu hỏi bạn chưa nghĩ tới: nếu hệ thống gục lúc cao điểm, tải phải giảm bao nhiêu thì nó mới tự đứng dậy? Sách SRE của Google cũng nêu đúng câu hỏi này: khi vài server sập dưới tải nặng, tải phải hạ đến đâu thì hệ thống mới ổn định lại. Vì thế kịch bản gồm ba pha.

import http from 'k6/http';
import { check } from 'k6';
import { SharedArray } from 'k6/data';

// Truy vấn thật (đã ẩn danh) do khách cung cấp, không tự bịa
const queries = new SharedArray('queries', () => JSON.parse(open('./queries.json')));

export const options = {
  scenarios: {
    baseline: { executor: 'constant-vus', vus: 50, duration: '15m' },
    stress: {
      executor: 'ramping-vus', startTime: '15m', startVUs: 50,
      stages: [{ duration: '10m', target: 200 }, { duration: '5m', target: 200 }],
    },
    recovery: { executor: 'constant-vus', startTime: '30m', vus: 25, duration: '10m' },
  },
  thresholds: {
    // Ngưỡng hai bên đã ký: chỉ áp cho tải bình thường và pha hồi phục
    'http_req_duration{scenario:baseline}': ['p(95)<800'],
    'http_req_failed{scenario:baseline}': ['rate<0.01'],
    'http_req_duration{scenario:recovery}': ['p(95)<800'],
  },
};

export default function () {
  const q = queries[Math.floor(Math.random() * queries.length)];
  const res = http.post(`${__ENV.BASE_URL}/search`, JSON.stringify({ q }),
    { headers: { 'Content-Type': 'application/json' } });
  check(res, { 'status 200': (r) => r.status === 200 });
}

Để ý rằng pha stress không có threshold. Pha này không chạy để đạt mà để tìm điểm gãy. k6 phân loại test theo mục đích, và stress test là loại dùng để xem hệ thống chạy ra sao ở giới hạn, khi tải vượt mức trung bình kỳ vọng.

AWS cũng xếp việc không đẩy tải vượt giới hạn kỳ vọng vào anti-pattern.

Giả sử kết quả như sau: pha baseline đạt, ở pha stress p95 vọt lên khi số người dùng vượt khoảng 140, pha recovery đạt. Vậy là cả hai cùng đúng một phần. Thiết kế chịu được tải hiện tại nhưng có trần, và giờ cả hai cùng nhìn thấy trần đó là bao nhiêu.

Pha recovery ở đây chỉ thử một mức 25 người dùng, nên nó chỉ cho biết hệ thống có hồi phục ở mức đó hay không. Muốn trả lời trọn câu hỏi của kiến trúc sư, hãy thay nó bằng một ramping-vus hạ tải theo nhiều bậc, chẳng hạn 150, 100, 50 rồi 25, và ghi lại bậc đầu tiên mà p95 quay về dưới 800 ms.

Các bước tự làm ở khách hàng

Hãy bắt đầu sớm. Ed Glas, trong một bài trên blog Microsoft, nhắc rằng nhiều vấn đề hiệu năng nằm ở kiến trúc, không phải loại sửa được ngay trước khi lên production. Nếu kiến trúc sư đang lo, hãy test ngay tuần này chứ đừng đợi tuần go-live.

Nạp đủ dữ liệu trước khi đo, vì theo Ed Glas nhiều vấn đề hiệu năng chỉ lộ ra khi khối lượng dữ liệu lớn. Một database 10.000 bản ghi không kiểm chứng được lời cảnh báo về một database sẽ chứa cả chục triệu.

Test từng thành phần trước, toàn hệ thống sau. Google SRE nhắc rằng mỗi thành phần có điểm gãy riêng nên cần load test riêng, còn Ed Glas đề xuất đi từ giao dịch đơn lẻ, rồi trộn thêm giao dịch, rồi mới đến toàn bộ.

Trong ví dụ trên, giữ nguyên kịch bản nhưng trỏ BASE_URL vào một endpoint chỉ chạy truy vấn database; nếu nó gãy sớm hơn toàn hệ thống, bạn đã tìm ra thủ phạm.

Cuối cùng, ghi lại. ADR (Architectural Decision Record) lưu một quyết định kiến trúc cùng lý do, đánh đổi và hệ quả. Một ADR kiểu “giữ thiết kế đồng bộ, trần đo được khoảng 140 người dùng, thêm hàng đợi khi tải thực tế chạm 100” biến kết quả test thành một cam kết có điều kiện, để ba tháng sau không ai phải cãi lại từ đầu.

Những lỗi khiến bài test chung phản tác dụng

Lỗi hay gặp nhất là bạn tự viết kịch bản rồi mời khách đến xem kết quả. Khách không được tham gia thiết kế thì cũng sẽ không tin kết quả. Hãy để kiến trúc sư chọn mức tải cao điểm và môi trường, kể cả khi bạn thấy con số của anh ấy hơi bi quan.

Lỗi thứ hai là dùng truy vấn tự bịa. Một danh sách năm câu lặp đi lặp lại sẽ được cache hết, và p95 sẽ đẹp đến mức đáng ngờ. Hãy xin khách một mẫu truy vấn thật đã ẩn danh.

Lỗi thứ ba là coi pha stress như bài thi bắt buộc phải đạt. Nếu bạn né việc đẩy hệ thống tới điểm gãy, kiến trúc sư sẽ nghĩ bạn sợ câu trả lời. Tìm ra điểm gãy là thắng lợi chung của hai bên chứ không phải thất bại của bạn.

Lỗi cuối cùng là quên pha hồi phục. Một hệ thống chậm đi lúc cao điểm rồi tự lành rất khác một hệ thống gục rồi nằm luôn. Hãy hỏi thẳng kiến trúc sư trường hợp nào anh ấy lo hơn, rồi để câu trả lời đó quyết định pha hồi phục cần đo kỹ đến đâu.

Biến nó thành một dòng trong CV

Trong CV, đừng chỉ viết “thực hiện load test”. Hãy viết kiểu: thiết kế load test chung với đội kiến trúc của khách, chốt ngưỡng p95 trước khi chạy, xác định điểm gãy của database và ghi quyết định vào ADR.

Khi đi phỏng vấn vị trí FDE, hãy chuẩn bị kể lại một lần như thế, vì nó cho thấy bạn giải quyết được bất đồng kỹ thuật với khách bằng con số chứ không phải bằng việc ai nói to hơn.

Bài tập tuần này: nhớ lại lần gần nhất bạn bất đồng với ai đó về hiệu năng. Viết ra ba con số lẽ ra hai bên phải chốt trước, cùng một kịch bản ba pha để kiểm chứng. Lần tới có người khoanh tay nói “sẽ sập”, bạn đã có sẵn câu trả lời: “Được, mình cùng tìm xem nó sập ở đâu.”

Bài này có hữu ích không?

Dùng cùng trợ lý AIHỏi Claude ↗Hỏi ChatGPT ↗
7 nguồn
Đọc tiếp trên lộ trình · Chặng 4: Khách hàngPhỏng vấn FDE: kể chuyện báo tin xấu cho stakeholder trong chưa đầy 90 giâyỞ vòng phỏng vấn FDE, người phỏng vấn muốn nghe cả lúc dự án đi sai chứ không chỉ lúc nó suôn sẻ. Một câu chuyện tin xấu kể đúng cách, gói trong giới hạn 90 giây tự đặt, có thể nói về bạn nhiều hơn bạn tưởng.