Khi một máy EC2 đã chạy production, điều nguy hiểm nhất thường không phải là một lỗi “to tát” nhìn thấy ngay, mà là những thứ nhỏ nhưng âm thầm phá máy:
- log tăng quá nhanh làm đầy disk
- process gửi log lỗi liên tục làm ngốn RAM
- CPU hoặc network tăng bất thường nhưng không ai để ý
- disk gần đầy mà không ai phát hiện sớm
Những thứ này không phải bug business logic, nhưng lại là kiểu vấn đề có thể làm app chậm, restart, treo hoặc downtime rất nhanh.
Kết luận nhanh
Nếu phải chốt vài điểm quan trọng nhất khi quản lý một EC2 production:
- nếu dùng Docker, phải giới hạn log ngay từ đầu để tránh tràn volume
- các log không quan trọng hoặc không cần giữ lâu phải limit hoặc bỏ bớt
- nếu không deploy bằng Docker mà chạy app trực tiếp trên EC2, phải cực cẩn thận với PM2 log và các process ship log kiểu Elasticsearch
- CPU, RAM, disk và network phải được theo dõi liên tục; thấy bất thường là phải xử lý sớm
Vì sao log là thứ dễ giết EC2 nhất?
Rất nhiều máy production chết theo cách rất “ngớ ngẩn”:
- app vẫn chạy
- code không lỗi lớn
- nhưng disk đầy vì log
Khi disk đầy, hậu quả có thể là:
- container restart lỗi
- database local lỗi ghi file
- app không ghi thêm log được
- system service hoạt động bất thường
- deploy mới thất bại
Đây là lý do log không được phép để “cứ tăng tự nhiên”.
Nếu dùng Docker, phải limit logs ngay từ đầu
Đây là rule rất quan trọng.
Nếu bạn chạy app bằng Docker trên EC2 mà để mặc định, log của container có thể tăng liên tục trong:
/var/lib/docker
Nếu service có:
- request nhiều
- lỗi lặp
- debug log quá chi tiết
thì volume có thể đầy rất nhanh.
Cách an toàn là set log rotation ngay trong Docker.
Ví dụ với Docker Compose:
services:
api:
image: my-api:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Ý nghĩa:
- mỗi file log tối đa
10MB - giữ tối đa
3file
Như vậy container không thể tự đẻ log vô hạn trên disk nữa.
Không phải log nào cũng đáng giữ
Trong production, có nhiều loại log giá trị rất thấp:
- healthcheck request
- debug log quá chi tiết
- retry log lặp đi lặp lại
- trace của các service phụ không ai xem
Những log kiểu này nếu đẩy nhiều sẽ chỉ:
- tốn disk
- tốn network
- tốn CPU
- làm khó đọc log quan trọng thật
Nguyên tắc là:
- log nào không giúp debug hoặc vận hành thì giảm bớt
- log nào ít giá trị thì limit
Các luồng gửi log không quan trọng cũng phải limit
Ví dụ rất thực tế là các luồng gửi log lên ELK hoặc hệ thống tập trung.
Nếu một service phụ:
- log nhiều
- gửi liên tục
- nhưng thực ra không ai dùng để phân tích
thì bạn đang tốn tài nguyên vô ích.
Đặc biệt khi log shipper bị lỗi gửi, hàng đợi hoặc buffer có thể tăng lên và kéo theo:
- RAM tăng
- CPU tăng
- network bất thường
- disk queue hoặc file spool tăng
Nói ngắn gọn:
- log không quan trọng thì đừng để gửi vô hạn
- nếu vẫn phải gửi, phải có limit, retention và retry hợp lý
Nếu không deploy bằng Docker mà chạy thẳng trên EC2, phải coi chừng PM2 logs
Nhiều người chạy Node.js hoặc NestJS trực tiếp trên EC2 bằng PM2.
PM2 rất tiện, nhưng cũng dễ thành bẫy nếu:
- stdout/stderr log ra quá nhiều
- không rotate log
- app bị loop lỗi
Khi đó log có thể tăng liên tục trong:
~/.pm2/logs
Nếu không có rotation, chỉ cần một bug hoặc một flow retry lỗi là disk có thể đầy rất nhanh.
Vì vậy nếu dùng PM2, phải:
- kiểm tra log path
- giới hạn hoặc rotate log
- không để debug log quá chi tiết trong production
Tránh để process gửi Elasticsearch logs ăn RAM nếu không gửi được
Đây là một pain point rất thật.
Nếu bạn có process:
- ship log lên Elasticsearch
- hoặc buffer log để gửi đi
nhưng đầu bên kia lỗi, nghẽn hoặc timeout, thì memory usage có thể tăng rất nhanh.
Vấn đề đặc biệt nguy hiểm khi:
- app không chạy trong Docker
- process log shipper sống trực tiếp trên EC2
- không có limit memory rõ ràng
Khi đó một lỗi mạng hoặc lỗi Elasticsearch cũng có thể kéo theo:
- RAM tăng dần
- swap tăng
- máy bắt đầu chậm
- OOM
Nếu bạn không thực sự cần gửi log đó, đừng bật chỉ để “cho có”.
Rule thực dụng với logs
Nếu phải đặt vài rule đơn giản:
- Docker logs luôn phải có
max-sizevàmax-file - PM2 logs luôn phải có cơ chế rotation
- log shipper không quan trọng thì phải limit hoặc tắt
- debug log không nên bật kéo dài trên production
- log growth bất thường phải được xem là incident
Theo dõi EC2 production thì phải nhìn những gì?
Tối thiểu phải theo dõi:
- CPU
- RAM
- disk
- network
Đây là 4 tín hiệu nền tảng nhất. Ngoài ra, nếu máy là EC2 trên AWS, còn có vài tín hiệu rất nên theo dõi thêm:
EC2 status checksCPU creditsnếu dùng dòngTEBS BurstBalancenếu volume còn làgp2
CPU, RAM, disk, network: nhìn cái gì?
CPU
CPU tăng bất thường có thể đến từ:
- app loop
- request tăng đột ngột
- process retry quá nhiều
- log shipper hoặc collector chạy lỗi
Nếu CPU tăng kéo dài, phải kiểm tra ngay:
- process nào đang ăn CPU
- có request spike thật không
- có cron, queue worker hay sidecar nào bị loop không
RAM
RAM là thứ rất dễ âm thầm xấu đi.
RAM tăng bất thường có thể do:
- memory leak
- process buffer log
- queue dồn
- app giữ object quá lâu
- Elasticsearch / log shipper giữ backlog
Khi thấy RAM tăng dần theo thời gian, đừng chỉ restart cho xong. Phải tìm nguyên nhân gốc.
Disk
Disk không chỉ là “còn bao nhiêu GB”.
Bạn phải nhìn:
- dung lượng còn lại
- thư mục nào đang tăng nhanh
- inode nếu máy có nhiều file nhỏ
Các thư mục rất đáng kiểm tra:
/var/lib/docker~/.pm2/logs- thư mục app logs
- cache / temp / spool
Nếu disk gần đầy mà không xử lý sớm, mọi thứ phía sau sẽ bắt đầu lỗi dây chuyền.
Network
Network bất thường có thể là tín hiệu của:
- traffic tăng thật
- retry loop ra ngoài
- ship log quá nhiều
- backup hoặc sync lỗi
- service bị scan hoặc bị abuse
Nếu outbound tăng mạnh không rõ lý do, nên kiểm tra ngay:
- app nào đang gọi ra ngoài
- log shipper có bị retry không
- có service nào đang gửi metrics hoặc logs vô hạn không
Đừng bỏ qua EC2 status checks
Theo tài liệu AWS, EC2 có các status checks để phát hiện vấn đề ở mức instance hoặc hạ tầng bên dưới.
Nguồn:
Điểm rất đáng làm là:
- tạo
CloudWatch alarm - theo dõi
StatusCheckFailed_System - bật
automatic recoverynếu phù hợp
AWS cũng có tài liệu riêng cho việc tự recover instance bằng alarm:
Điều này không thay thế monitoring app, nhưng là một lớp bảo vệ rất đáng có.
Nếu dùng T3 hoặc dòng burstable, phải nhìn CPU credits
Bài này đang nói tới quản lý EC2 production nói chung, nhưng nếu máy của bạn là dòng T như:
t3.microt3.small
thì chỉ nhìn % CPU là chưa đủ.
Theo AWS, các instance burstable có metric riêng về CPU credits trong CloudWatch.
Nguồn:
Những metric rất nên nhìn:
CPUCreditBalanceCPUSurplusCreditBalanceCPUSurplusCreditsCharged
Vì sao quan trọng:
- máy có thể vẫn “chạy được”
- nhưng credit cạn dần
- hoặc bắt đầu burst theo kiểu phát sinh chi phí
Nếu volume còn là gp2, nên theo dõi BurstBalance
Theo AWS, gp2 có metric BurstBalance để theo dõi phần credit I/O còn lại.
Nguồn:
Nếu BurstBalance tụt thấp:
- volume có thể bị throttle về baseline
- app bắt đầu chậm theo kiểu khó đoán
- disk latency tăng dù CPU và RAM chưa chắc cao
Nếu production vẫn đang dùng gp2, đây là tín hiệu rất đáng để ý.
Disk usage trong OS không tự hiện đủ nếu không cài agent
Một điểm dễ hiểu nhầm là:
- EC2 metrics mặc định không tự cho bạn đầy đủ disk usage từ bên trong OS
Theo tài liệu AWS, nếu muốn theo dõi disk space usage từ trong instance mà không SSH vào máy kiểm tra thủ công, bạn nên dùng:
CloudWatch Agent
Nguồn:
Điều này rất hữu ích để alert sớm kiểu:
/còn dưới 20%/var/lib/dockertăng bất thường- log volume gần đầy
Phát hiện bất thường thì phải fix sớm
Đây là nguyên tắc rất quan trọng.
Với production EC2, các dấu hiệu như:
- CPU tăng bất thường
- RAM tăng dần
- disk tụt nhanh
- network spike lạ
không nên để “mai tính”.
Rất nhiều incident lớn bắt đầu từ những tín hiệu nhỏ như vậy.
Càng fix sớm, chi phí càng thấp:
- ít downtime hơn
- ít mất log hơn
- ít phải restart emergency hơn
- ít rủi ro data corruption hơn
Checklist vận hành EC2 production
Bạn nên có ít nhất checklist này:
- Docker logs đã set
max-sizevàmax-filechưa? - PM2 logs đã rotate chưa?
- log shipper nào đang chạy? có thật sự cần không?
- disk usage hiện tại là bao nhiêu?
- thư mục nào đang tăng nhanh?
- CPU / RAM / network có baseline bình thường chưa?
- có alert cho usage bất thường chưa?
StatusCheckFailed_Systemđã có alarm chưa?- nếu là
t3, đã nhìnCPUCreditBalancechưa? - nếu là
gp2, đã nhìnBurstBalancechưa? - đã có
CloudWatch Agentđể thấy disk usage từ bên trong OS chưa?
Điều quan trọng nhất
Nếu chỉ giữ đúng một thói quen, hãy giữ thói quen này:
- đừng để log growth trở thành thứ không được kiểm soát
Trên EC2 production, log không được limit là một trong những cách nhanh nhất để tự làm hỏng máy của mình.
Kết luận
Quản lý một EC2 production không chỉ là deploy app lên rồi để đó. Những thứ cần giữ rất chặt là:
- Docker logs
- PM2 logs
- log shipper
- CPU
- RAM
- disk
- network
- EC2 status checks
- CPU credits nếu là T-series
- EBS burst behavior nếu còn dùng gp2
Trong đó, nếu có dùng Docker, việc đầu tiên nên làm gần như luôn là:
- set giới hạn log
Và nếu không chạy bằng Docker mà dùng app trực tiếp trên EC2, càng phải cẩn thận hơn với:
- PM2 logs
- process gửi log kiểu Elasticsearch
Phát hiện bất thường sớm và xử lý ngay chính là thứ giữ cho máy production sống ổn định lâu dài.