0
1
Lập trình
Thaycacac
Thaycacac thaycacac

Cách Tôi Giải Cứu Hệ Thống Trong Mùa Cao Điểm

Đăng vào 1 tháng trước

• 7 phút đọc

Giới thiệu: Mùa Cao Điểm và Thách Thức Phía Trước

Mùa du lịch đã đến, và bầu không khí tại công ty tôi nóng hơn cả ánh nắng bên ngoài. Hệ thống của chúng tôi—nhịp đập của mọi hoạt động—sắp phải đối mặt với lưu lượng truy cập cao gấp 8–10 lần so với bình thường. Tôi mở laptop và truy cập bảng điều khiển như một người dùng bình thường, nhưng lập tức cảm thấy áp lực: mọi thứ đều chậm chạp và giật lag, mỗi cú nhấp chuột gửi đi một cơn bão yêu cầu mà khó kiểm soát.

Mọi bảng phân tích, mọi biểu đồ đều có thể trở thành “bom CPU và bộ nhớ.” Máy chủ đang chịu áp lực, và OOM (Out of Memory) gần như đảm bảo nếu lưu lượng vẫn tiếp tục tăng. Đây đánh dấu sự khởi đầu của hành trình cứu hệ thống của tôi, nơi mọi quyết định sẽ ảnh hưởng trực tiếp đến trải nghiệm người dùng.


Khám Phá Frontend: Đầu Băng Tảng

Mở F12, tôi thấy hàng trăm yêu cầu liên tục truy cập vào các điểm cuối, nhiều yêu cầu lấy toàn bộ bảng khách hàng, giao dịch, và thanh toán. Bảng điều khiển cố gắng tính toán mọi thứ theo thời gian thực, nhưng CPU và bộ nhớ nhảy vọt với mỗi cú nhấp chuột.

Tôi áp dụng lazy loading cho dữ liệu không quan trọng, lưu trữ tạm thời một số bảng trong localStorage, và hy sinh một chút độ mượt mà trong UX. Ngay lập tức, bảng điều khiển trở nên phản hồi nhanh hơn, backend cảm thấy nhẹ nhàng hơn. Nhưng tôi biết đây chỉ là bề nổi của tảng băng—mối nguy thực sự đang tiềm ẩn sâu bên dưới.


Khám Phá Backend: Nơi Áp Lực Thực Sự Nằm

Frontend chỉ hiển thị phần nổi của tảng băng. Tôi mở nhật ký máy chủ, bật APM, và theo dõi các truy vấn chậm và các chỉ số phân tích. Nhiều điểm cuối tính toán phân tích theo thời gian thực trên các bảng lớn. Các truy vấn nặng đọc không được tối ưu hóa, lấy toàn bộ dữ liệu mỗi khi tải bảng điều khiển, khiến CPU và bộ nhớ chạy quá tải.

Tôi thử tính toán trước các chỉ số nặng và lưu trữ chúng trong Redis. Ban đầu, dữ liệu chậm hơn vài phút so với thời gian thực, khiến tôi lo lắng, nhưng bảng điều khiển chạy mượt mà và backend ổn định. Một đánh đổi rõ ràng: hy sinh một chút độ chính xác để cứu hệ thống. Tỉ lệ hit của Redis tăng lên, và tôi cảm thấy vừa nhẹ nhõm vừa căng thẳng.


CQRS và Các Truy Vấn Nặng Đọc: Giải Pháp Dài Hạn

Các truy vấn nặng đọc tiếp tục gây áp lực lên máy chủ. Tôi thử mở rộng MySQL, thêm các bản sao, tăng RAM—nhưng vẫn xảy ra hiện tượng đột biến bộ nhớ. Tôi quyết định triển khai CQRS, tách biệt các thao tác ghi và đọc, sử dụng OpenSearch để phục vụ các truy vấn nặng đọc.

Việc đồng bộ dữ liệu khá phức tạp, logic cũng rối rắm, nhưng bảng điều khiển cuối cùng đã phản hồi nhanh và đáng tin cậy. Độ phức tạp tăng lên—nhiều dịch vụ hơn trong mã nguồn, các listener đồng bộ dữ liệu, thêm giám sát cho OpenSearch, Redis và MySQL. Tuy nhiên, các bảng phân tích nặng bây giờ chạy mượt mà, CPU và bộ nhớ không còn nhảy vọt.


Tính Toán Trước Bảng Điều Khiển: Hy Sinh Thời Gian Thực

Các bảng phân tích quan trọng nhất, nếu tính toán theo thời gian thực, sẽ khiến máy chủ chịu áp lực dễ bị sập. Tôi đã tính toán trước các kết quả và lưu trữ chúng trong Redis. Khi lưu lượng truy cập cao xảy ra, bảng điều khiển chạy mượt mà, mặc dù dữ liệu không còn hoàn toàn theo thời gian thực. Tôi nhớ khoảnh khắc nhấp chuột qua bảng điều khiển và nhìn thấy các biểu đồ lag lại vài phút—một đánh đổi đáng chấp nhận để giữ cho hệ thống sống sót.

Các truy vấn xuất và bảng điều khiển giờ đây trả về dữ liệu nhanh như chớp từ Redis, CPU giảm từ 95% xuống 60%, và bộ nhớ ổn định.


Cache Promise, Gộp Yêu Cầu và Làm Nóng Cache

Trước khi lưu lượng truy cập cao, nhiều yêu cầu đồng thời truy cập cùng một dữ liệu làm Redis và cơ sở dữ liệu trở nên chao đảo. Tôi triển khai Cache Promisegộp yêu cầu, kết hợp nhiều yêu cầu để chỉ một truy vấn thực sự truy cập vào cơ sở dữ liệu. Mã trở nên phức tạp hơn, nhưng backend đứng vững—tôi cảm thấy như chúng tôi đã vượt qua một cơn bão.

Tôi cũng lên lịch công việc làm nóng cache. Máy chủ hấp thụ một tải nhẹ trong giờ thấp điểm, nhưng khi lưu lượng đạt đỉnh, dữ liệu đã sẵn sàng. Bảng điều khiển vẫn mượt mà, và backend bình tĩnh xử lý 8–10 lần lưu lượng mà không gặp trục trặc.


Ưu Tiên Yêu Cầu và Truy Vấn Chọn Lọc

Một số xuất Excel hoặc yêu cầu phân tích đã từng làm chậm các thao tác quan trọng. Tôi triển khai bulkheadưu tiên yêu cầu, đảm bảo các yêu cầu quan trọng được xử lý trước. Một số xuất phân tích chậm hơn, nhưng hệ thống vẫn giữ được độ phản hồi.

Để tránh OOM, tôi chỉ truy vấn những trường cần thiết và xử lý các xuất lớn theo lô. Tính toàn vẹn dữ liệu theo thời gian thực bị hy sinh một phần, nhưng máy chủ sống sót, bảng điều khiển vẫn mượt mà, và cảm giác chiến thắng lan tỏa trong hệ thống.


Giám Sát và Cảnh Báo: Cẩn Thận Thì Hơn Là Hối Hận

Trong quá trình chuẩn bị, tôi đã thiết lập giám sát liên tục: CPU, bộ nhớ, hit của Redis, độ trễ truy vấn OpenSearch, số lượng yêu cầu thành công và thất bại. Tôi cấu hình cảnh báo cho các vượt ngưỡng, vì vậy chúng tôi nhận được cảnh báo trước khi hệ thống thực sự gặp sự cố.

Bằng cách này, tôi không cần chờ máy chủ sập mới biết có điều gì sai—các đột biến bộ nhớ hoặc truy vấn chậm được báo cáo ngay lập tức, cho phép can thiệp kịp thời.


Kiểm Tra Chaos và Kiểm Tra Tải

Trước mùa cao điểm, đội ngũ của tôi đã thực hiện kiểm tra tải mô phỏng lưu lượng cao và thực hiện kiểm tra chaos, cố ý phá hỏng một số dịch vụ. Thông qua những bài kiểm tra này, chúng tôi đã học được rất nhiều điều: cache dư thừa, hàng đợi yêu cầu chồng chéo, các deadlock tiềm ẩn trong các listener đồng bộ OpenSearch. Những bài tập này giúp chúng tôi chuẩn bị các kế hoạch hoàn tác, tăng số bản sao và điều chỉnh kích thước lô.


Triển Khai & Sửa Lỗi Nóng Trong Giờ Cao Điểm

Một đêm, trong lúc lưu lượng đạt đỉnh, một lỗi nhỏ trong bảng điều khiển đã được tính toán trước khiến dữ liệu bị lag nhiều hơn bình thường. Tôi phải áp dụng một sửa lỗi nóng ngay trong môi trường sản xuất, triển khai cẩn thận từng bước trong khi giám sát Redis và OpenSearch. Thật căng thẳng, nhưng khi mọi thứ ổn định, tôi cảm thấy như chúng tôi đã thực sự sống sót qua một cơn bão dữ liệu.


Kết Luận: Bài Học Được Rút Ra

Sau khi sống sót qua lưu lượng cao, bảng điều khiển chạy mượt mà, backend ổn định, và người dùng không bị ảnh hưởng. Nghĩ lại trải nghiệm, tôi nhận ra rằng sự chuẩn bị là tất cả: thiết lập giám sát, cảnh báo, kiểm tra tải, kiểm tra chaos, và làm nóng cache trước có thể tạo ra sự khác biệt giữa thành công và thảm họa.

Điều quan trọng không kém là tìm ra nguyên nhân gốc rễ của các vấn đề. Thật dễ dàng để vá các triệu chứng, nhưng trừ khi bạn hiểu các vấn đề cơ bản—dù là truy vấn nặng đọc, điểm cuối không tối ưu hóa, hay dữ liệu không đồng bộ kém—hệ thống cuối cùng sẽ bị gãy khi chịu áp lực.

Cuối cùng, không có giải pháp hoàn hảo. Mỗi lựa chọn đều đi kèm với những đánh đổi: hy sinh một chút độ mượt mà của UX, chấp nhận một số độ trễ nhỏ trong dữ liệu theo thời gian thực, tăng độ phức tạp của hệ thống. Nhận diện những đánh đổi này và lập kế hoạch cho chúng trước thời gian là chìa khóa để giữ cho hệ thống sống sót trong những mùa cao điểm áp lực cao.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào