OS & Concurrency: Monitoring, So sánh và Cloud
8. System Monitor Chart — Đọc hiểu
CPU Usage % thực sự nghĩa là gì?
CPU Usage % = (thời gian RUNNING) / (tổng thời gian) × 100
Ví dụ Core 0 trong 1 giây:
RUNNING : 700ms → CPU Usage = 70%
IDLE : 300ms
⚠️ "CPU 100%" không có nghĩa là đang tính toán hữu ích 100%. CPU có thể 100% nhưng phần lớn thời gian là context switching overhead — hệ thống bận nhưng không làm việc thật.
Phân loại CPU time
██████████ User (xanh lá) — code ứng dụng đang chạy
████ System (đỏ) — kernel đang chạy (syscalls, interrupts)
░░░░░░ Idle (trống) — không có gì chạy
System time cao bất thường thường chỉ điểm ứng dụng đang gọi quá nhiều syscalls (ví dụ: tạo quá nhiều connections, đọc file nhiều small chunks).
Đọc chart đa core
Core 0 [████████░░] 80%
Core 1 [████░░░░░░] 40%
Core 2 [██████████] 100% ← bottleneck! (single-threaded?)
Core 3 [░░░░░░░░░░] 0% ← hoàn toàn nhàn
Average hiển thị: (80+40+100+0)/4 = 55%
Average 55% nghe có vẻ bình thường, nhưng thực ra Core 2 đang bị nghẽn trong khi Core 3 hoàn toàn nhàn. Đây là dấu hiệu của code chưa được parallel hóa tốt.
Load Average (Linux)
$ uptime
2.5 1.8 1.2
1min 5min 15min
Load = số threads đang RUNNING + WAITING FOR CPU (không phải BLOCKED)
Rule of thumb:
Load = 1.0 trên 1 core → vừa đủ tải
Load = 4.0 trên 4 cores → vừa đủ (100% utilized)
Load = 8.0 trên 4 cores → QUÁ TẢI — threads đang xếp hàng chờ core
Load average tăng dần (1min > 5min > 15min) → vấn đề đang leo thang. Load average giảm dần → đang phục hồi.
Context Switches/sec
< 10,000/s → bình thường, ít threads tranh CPU
> 100,000/s → nhiều threads đang tranh nhau → dấu hiệu nên
dùng goroutine/async thay vì OS thread
9. So sánh tổng quan
Physical OS Thread Goroutine
Thread
─────────────────────────────────────────────────────
Lớp Hardware Kernel Go Runtime
Quản lý bởi CPU Kernel Go runtime
RAM N/A 1-8 MB 2 KB (ban đầu, dynamic)
Stack N/A Cố định Tự động grow
Tạo mới N/A ~1 ms ~300 ns
Context switch N/A ~1-10 µs ~100 ns
Giới hạn = CPU cores ~10,000 ~1,000,000+
Giao tiếp N/A Mutex/Lock Channel (an toàn hơn)
Kernel biết? Có Có Không
Ví dụ thực tế: Web server xử lý 10,000 requests
Java (OS Threads truyền thống):
10,000 requests → 10,000 OS threads
10,000 × 1MB = ~10 GB RAM chỉ cho threads
Context switching liên tục → CPU gần như chỉ switch
→ 💥 Server chết
Go (Goroutines):
10,000 requests → 10,000 goroutines
10,000 × 2KB = ~20 MB RAM
8 OS threads xoay vòng phục vụ tất cả
→ ✅ Mượt mà, hiệu quả
10. Tại sao Go mạnh trong Cloud
Goroutines xử lý concurrency ở quy mô lớn
// Tạo 1 triệu goroutine — bình thường với Go
for i := 0; i < 1_000_000; i++ {
go handleRequest(i)
}
// RAM dùng: ~2 GB (so với ~1 TB nếu dùng OS threads)
Đây là lý do Go servers có thể handle hàng trăm nghìn concurrent connections trên một máy bình thường.
Static Binary: deploy cực nhanh
app.go → ./app (1 file, không cần JVM, không cần interpreter)
→ Docker image: vài MB (thay vì hàng trăm MB)
→ Khởi động: milliseconds
→ Lý tưởng cho serverless và container
Low-latency Garbage Collector
Java GC có thể gây "stop-the-world" pause đột ngột — latency spike khi GC chạy. Go GC concurrent với latency thường dưới 1ms. Quan trọng với SLA yêu cầu p99 latency thấp.
Standard Library mạnh
net/http — HTTP server/client built-in
encoding/json — JSON nhanh built-in
context — timeout, cancellation cho distributed systems
crypto/tls — TLS/HTTPS built-in
Không cần framework nặng để dựng API server hiệu năng cao. Một production HTTP server có thể dùng hoàn toàn standard library.
Hệ sinh thái Cloud "sinh ra từ Go"
| Công cụ | Vai trò |
|---|---|
| Docker | Container runtime |
| Kubernetes | Container orchestration |
| Terraform | Infrastructure as Code |
| Prometheus | Monitoring |
| etcd | Distributed key-value store |
| Consul | Service discovery |
Phần lớn infrastructure tooling hiện đại được viết bằng Go — có lý do cho điều đó.
Ngôn ngữ đơn giản, dễ maintain ở scale lớn
Go chỉ có ~25 keywords. Không có class inheritance phức tạp, không có magic ẩn. Hàng trăm engineers có thể maintain cùng codebase mà không có quá nhiều "what does this do?" moments.
🗺️ Bức tranh tổng thể
Bạn viết code Go
│
▼
Goroutine (2KB, hàng triệu cái)
│ Go runtime M:N scheduler
▼
OS Thread (~8 cái, bằng số cores)
│ Kernel CFS scheduler (vruntime, red-black tree)
▼
Physical Core (thực thi thật: fetch → decode → execute)
│
▼
Kết quả (register → L1/L2/L3 cache → RAM)
│
▼
System Monitor: đo % thời gian core đang RUNNING → hiển thị chart