All notes

Một con server, gánh cả production

Vì sao chúng tôi chạy hàng chục site production trên đúng một dedicated server, và ba khối config giúp nó sống sót.

4 phút đọcViết từ Seoul và Nha Trang

Ai gặp chúng tôi cũng đinh ninh rằng chúng tôi chạy cả một dàn cloud instance. Thực ra chỉ có đúng một dedicated server đặt trong data center ở Falkenstein, và nó gánh toàn bộ site production, database lẫn bot mà chúng tôi vận hành.

Đây không phải hoài niệm gì cả. Nó là một cách tự ép mình vào kỷ luật. Khi mọi thứ nằm chung một máy, không có autoscaling nào che giấu được code viết ẩu. Một chỗ rò rỉ bộ nhớ chỉ sau một tiếng là thành rắc rối của mấy dịch vụ hàng xóm. Một job cron chạy loạn lập tức hiện lên trong latency của tất cả. Nên kỷ luật buộc phải nằm ở ba chỗ, và cả ba đều do config ép, chứ không phải do lời hứa.

1. Mọi service đều có trần

# systemd override, applied to every unit, no exceptions
[Service]
MemoryMax=512M
CPUQuota=80%
Restart=on-failure
RestartSec=5

Cái trần đó không phải để chạm tới. Nó ở đó để khi thật sự có sự cố, kernel chỉ giết đúng một service, thay vì để OOM killer bốc đại một nạn nhân trong số bốn chục cái.

2. Mọi job theo lịch đều có lock, timeout và heartbeat

*/5 * * * * flock -n /run/lock/sync.lock timeout 240 /opt/jobs/sync.sh \
            && date > /opt/health/sync.ok

Lock chặn một lượt chạy chậm chồng lên chính nó. Timeout chặn một lượt chạy bị treo giữ lock mãi mãi. Đáng nói nhất là file heartbeat: một watchdog riêng kiểm tra mtime của từng file .ok, và coi chính sự cũ kỹ đó là báo động. Trong production, job hiếm khi lăn đùng ra chết ồn ào. Chúng chết theo kiểu lặng lẽ ngừng chạy.

3. Routing gói gọn trong một file đọc được bằng mắt

example.com {
  encode zstd gzip
  root * /srv/sites/example
  file_server
  handle /api/* { reverse_proxy 127.0.0.1:3160 }
}

Caddy đảm nhận TLS cho mọi domain và định tuyến theo hostname. Đằng sau nó, các app là container hoặc thư mục tĩnh. Database là Postgres và MySQL thuần, mỗi engine một instance, nhiều schema dùng chung. Không có gì cao siêu, mọi thứ đều soi được bằng công cụ tiêu chuẩn.

Một con server đổi lại cho ta những gì: latency mà ta thật sự lý giải được (mọi hop nội bộ đều là loopback), một filesystem duy nhất làm nguồn sự thật (debug là grep, chứ không phải cả một buổi hội thảo về distributed tracing), và tính toán năng lực máy một cách trung thực (htop chính là cái dashboard). Cái giá phải trả là con server trở nên quý giá, mà thứ gì quý giá thì cần được nâng niu tới mức hoang tưởng. Chính sự hoang tưởng đó, những bản backup mà chúng tôi thật sự đem ra khôi phục, phát hiện im lặng, giới hạn bán kính thiệt hại, mới là nội dung chính của phần lớn những ghi chú còn lại.