Tối Ưu Hiệu Suất
Leo thang từ khách hàng về việc chậm chạp là một trong những khoảnh khắc căng thẳng nhất trong một dự án outsourcing. Ứng dụng cảm thấy ổn trong staging, nhưng dưới traffic thực, thời gian phản hồi API tăng gấp ba và người dùng đang phàn nàn. Các performance agent của Sun Agent Kit phân tích ứng dụng của bạn một cách có hệ thống — xác định N+1 query, index bị thiếu, blocking I/O, và memory leak — sau đó sinh ra các bản sửa cụ thể, có mục tiêu mà codebase của bạn cần, không phải danh sách chung chung “hãy cân nhắc caching.”
Tổng Quan
Mục tiêu: Chẩn đoán nguyên nhân gốc rễ của regression hiệu suất, triển khai bản sửa có mục tiêu, và xác nhận cải tiến
Thời gian: 30–60 phút (so với 4–12 giờ profiling thủ công và thử sai)
Agent sử dụng: debugger, scout, implementer, tester
Lệnh: /sk:debug, /sk:scout, /sk:cook, /sk:test
Yêu Cầu Trước Khi Bắt Đầu
- Sun Agent Kit đã được cài đặt và xác thực (hướng dẫn cài đặt)
- Quyền truy cập vào application log hoặc file log với slow request trace
- Truy cập cơ sở dữ liệu để phân tích query (read-only credential là đủ)
- Một kịch bản có thể tái tạo — URL path, payload, và tốc độ request xấp xỉ gây ra chậm
- Tùy chọn: APM data export (Datadog, New Relic, hoặc application-level timing log)
Quy Trình Từng Bước
Bước 1: Profile ứng dụng và xác định bottleneck
Bắt đầu bằng cách cung cấp cho agent triệu chứng — một URL endpoint chậm hoặc một đoạn log — và để nó xác định nguồn gốc.
/sk:debug "API endpoint GET /api/products is returning in 3-8 seconds. Normal was 200ms. Traffic increased 3x last week."
Điều gì xảy ra: Agent thực hiện:
- Phân tích mô tả triệu chứng và xác định endpoint bị ảnh hưởng cùng baseline mong đợi
- Truy vết đường dẫn request từ controller qua service đến database query
- Phân tích pattern query để tìm N+1 query, index bị thiếu, và result set không giới hạn
- Kiểm tra caching layer và xác định synchronous I/O trong hot path
- Tạo phân tích nguyên nhân gốc rễ với các phát hiện được ưu tiên
Bước 2: Scout toàn bộ codebase để tìm các vấn đề hiệu suất khác
Mở rộng phạm vi tìm kiếm để phát hiện các vấn đề tiềm ẩn trước khi chúng trở thành leo thang tiếp theo.
/sk:scout "N+1 query, SELECT *, missing pagination, synchronous I/O, no cache, unbounded loop"
Điều gì xảy ra: Agent thực hiện:
- Quét codebase để tìm các anti-pattern hiệu suất phổ biến
- Ưu tiên các phát hiện theo tác động (HIGH cho N+1 trong hot path, LOW cho admin view)
- Tạo roadmap sửa lỗi lưu vào
plans/reports/
Bước 3: Sửa N+1 query bằng eager loading
Agent viết lại các query bị ảnh hưởng để dùng join hoặc eager loading, phù hợp với idiom ORM đã có trong codebase của bạn.
/sk:cook "Fix N+1 queries in ProductController, OrderController, and UserController — use eager loading per the ORM conventions in this project"
Điều gì xảy ra: Agent thực hiện:
- Phát hiện ORM đang dùng (Eloquent, Prisma, TypeORM, v.v.) và áp dụng eager loading theo idiom
- Viết lại query để include các model liên quan trong một lần gọi database
- Thêm pagination ở những nơi result không bị giới hạn
- Chạy test để xác minh không có regression
Bước 4: Thêm database index cho các cột traffic cao
Agent đọc migration history của bạn, xác định các index bị thiếu trên foreign key và các cột được filter thường xuyên, và sinh các file migration.
/sk:cook "Add missing database indexes for performance — analyze the schema and generate migrations"
Điều gì xảy ra: Agent thực hiện:
- Phân tích schema để tìm foreign key, cột trong mệnh đề WHERE, và cột ORDER BY không có index
- Sinh file migration với định nghĩa index phù hợp
- Ước tính tác động của mỗi index lên các pattern query phổ biến
Bước 5: Triển khai caching layer
Thêm Redis caching vào các endpoint traffic cao nhất, với TTL phù hợp và cache invalidation hook.
/sk:cook "Add Redis caching to GET /api/products and GET /api/categories — 5 minute TTL, invalidate on product or category write"
Điều gì xảy ra: Agent thực hiện:
- Kiểm tra cấu hình Redis trong môi trường dự án
- Áp dụng cache-aside pattern cho các endpoint được chỉ định với cache key được tham số hóa
- Thêm cache invalidation hook trên các write operation (create, update, delete)
- Viết test cho cache hit, cache miss, và invalidation scenario
Bước 6: Xác nhận cải tiến
Chạy bộ test và xác minh các tối ưu hóa hoạt động đúng.
/sk:test "run all tests and verify no regressions from performance optimizations"
Điều gì xảy ra: Agent chạy bộ test đầy đủ bao gồm test cache và query mới, và báo cáo bất kỳ lỗi nào.
Ví Dụ Hoàn Chỉnh: Thời Gian Phản Hồi API Tăng Sau Traffic Spike
Tình huống
API danh mục sản phẩm của một khách hàng e-commerce Nhật Bản hoạt động tốt trong giai đoạn pilot — vài trăm người dùng đã đăng ký, thời gian phản hồi nhanh. Lần ra mắt chính thức mang lại hàng nghìn người dùng trong 48 giờ. Đến ngày thứ hai, PM của khách hàng có mặt trên Slack của bạn: “Trang sản phẩm mất 5–8 giây để tải. Một số request bị timeout hoàn toàn. Vui lòng sửa ngay lập tức.” Team của bạn chưa bao giờ thấy môi trường production dưới load thực. Bạn không có APM tooling được cấu hình.
Chuỗi lệnh sử dụng
# 1. Chẩn đoán — cung cấp triệu chứng cho agent
/sk:debug "Product catalog API (GET /api/v1/products) degraded from 200ms to 5-8s after launch. Timeouts occurring under load. No APM data available."
# 2. Performance audit đầy đủ để tìm tất cả vấn đề liên quan
/sk:scout "N+1 query, missing index, missing pagination, synchronous I/O, no cache, unbounded loop"
# 3. Sửa các vấn đề có tác động cao nhất trước
/sk:cook "Fix N+1 queries in product catalog — use eager loading per ORM conventions"
/sk:cook "Add database indexes on foreign keys and frequently filtered columns"
# 4. Thêm caching layer
/sk:cook "Add Redis caching to product list and product detail endpoints — tag-based invalidation on product write events"
# 5. Thêm pagination để ngăn chặn result set không giới hạn
/sk:cook "Add cursor-based pagination to GET /api/v1/products — default page size 20, max 100"
# 6. Chạy test toàn bộ
/sk:test "run full test suite after performance optimizations"
Kết quả
Trong vài giờ sau khi leo thang, API trở về thời gian phản hồi nhanh dưới load. Khách hàng nhận được một báo cáo giải thích các nguyên nhân gốc rễ cụ thể và các thay đổi đã thực hiện. PM phản hồi: “Cảm ơn vì phản hồi nhanh. Vui lòng thêm monitoring để chúng tôi phát hiện sớm hơn lần sau.” Đó là cuộc trò chuyện về scope mở rộng, không phải khủng hoảng.
So Sánh Thời Gian
| Tác vụ | Thủ công | Với Sun Agent Kit |
|---|---|---|
| Đọc code để tìm query chậm | 60 phút | vài phút |
| Xác định pattern N+1 thủ công | 45 phút | vài phút |
| Nghiên cứu và viết index migration | 30 phút | vài phút |
| Thiết kế và triển khai cache layer | 90 phút | vài phút |
| Viết cache invalidation logic | 30 phút | vài phút |
| Viết báo cáo hiệu suất cho khách hàng | 30 phút | vài phút |
| Tổng cộng | ~5 giờ | dưới 30 phút |
Bảng Mục Tiêu Hiệu Suất
Dùng các mục tiêu này làm acceptance criteria khi đóng ticket hiệu suất:
| Loại Endpoint | p50 chấp nhận được | p95 chấp nhận được | p99 tối đa |
|---|---|---|---|
| List (có pagination, có cache) | < 100ms | < 200ms | < 500ms |
| List (có pagination, không cache) | < 300ms | < 600ms | < 1,000ms |
| Detail (một record) | < 80ms | < 150ms | < 300ms |
| Write (create/update) | < 200ms | < 400ms | < 800ms |
| Search (full-text) | < 500ms | < 1,000ms | < 2,000ms |
| Report / aggregation | < 2,000ms | < 5,000ms | < 10,000ms |
Thực Hành Tốt Nhất
1. Luôn đo trước khi tối ưu — lấy con số baseline ✅
Agent yêu cầu mô tả triệu chứng trước khi sinh bất kỳ bản sửa nào. Nếu bạn bỏ qua profiling và nhảy vào “thêm Redis khắp nơi,” bạn có thể cache nhầm thứ và che đi vấn đề thực sự. Yêu cầu một số liệu cụ thể: “3.200ms trung bình trên GET /api/products dưới 50 người dùng đồng thời” là chẩn đoán; “cảm thấy chậm” thì không phải.
2. Sửa N+1 query trước khi thêm caching ✅
Cache một query chậm không phải là giải pháp — đó là che giấu vấn đề. Một N+1 kích hoạt hàng trăm query mỗi request vẫn sẽ kích hoạt chúng mỗi lần cache miss, và trong workload write nặng, cache sẽ miss liên tục. Sửa query trước, sau đó thêm caching để giảm tải database hơn nữa.
3. Đừng cache database write để tăng tốc thời gian phản hồi ❌
Thật hấp dẫn khi “cache” một write operation bằng cách trả về thành công ngay lập tức và xử lý bất đồng bộ. Đây là pattern message queue, không phải cache — và triển khai sai tạo ra data loss. Nếu bạn cần xử lý async, dùng /sk:cook "add job queue" để scaffold tích hợp queue đúng cách, không phải ad-hoc in-memory cache.
4. Đừng đặt một TTL duy nhất cho tất cả dữ liệu cached ❌
Tên sản phẩm thay đổi không thường xuyên — TTL 10 phút là ổn. Giỏ hàng của người dùng thay đổi mỗi lần tương tác — cache nó 10 phút gây ra bug lost-cart. Agent mặc định TTL bảo thủ theo loại entity; xem xét và điều chỉnh chúng dựa trên tần suất write của bạn trước khi deploy.
Xử Lý Sự Cố
Vấn đề: Sau khi thêm index, query không nhanh hơn
Giải pháp: Chạy EXPLAIN ANALYZE trên query chậm để xác nhận index đang được dùng. Postgres và MySQL đôi khi bỏ qua index mới nếu statistics bị cũ. Chạy ANALYZE products; (Postgres) hoặc ANALYZE TABLE products; (MySQL) để cập nhật statistics. Nếu query planner vẫn bỏ qua index, agent có thể giúp thiết kế lại index để phù hợp tốt hơn với mệnh đề WHERE và ORDER BY của query.
Vấn đề: Redis caching hoạt động trong development nhưng gây ra stale data trong production
Giải pháp: Nguyên nhân phổ biến nhất là thiếu cache invalidation trên các write path bạn chưa tính đến. Chạy /sk:scout "find all write operations on the products table" để tìm tất cả những chỗ ghi vào bảng — mỗi chỗ đều cần cache invalidation hook. Agent sẽ liệt kê những cái bị bỏ sót.
Vấn đề: Load test cho thấy error rate cao ngay cả sau khi sửa
Giải pháp: Error rate cao dưới load thường chỉ ra connection pool exhaustion, không phải tốc độ query. Kiểm tra kích thước database connection pool (DB_POOL_SIZE trong .env). Một misconfiguration phổ biến là để pool ở mặc định 5 connection trên server xử lý 100+ request đồng thời. Đặt nó thành (2 × CPU cores) + number of disks làm điểm khởi đầu.
Vấn đề: Hiệu suất tốt dưới load test nhưng chậm với người dùng thực
Giải pháp: Load test dùng cùng endpoint và payload không nắm bắt được sự biến đổi của thế giới thực. Chạy /sk:debug "slow for specific users" và kiểm tra xem sự chậm có tương quan với những người dùng có dataset lớn (nhiều order, nhiều sản phẩm trong giỏ hàng). Giải pháp thường là thêm user_id index hoặc giới hạn phạm vi query đang vô tình load dữ liệu cross-user.
Bước Tiếp Theo
- Đánh Giá Code — Phát hiện performance anti-pattern trong code review trước khi lên production
- Tái Cấu Trúc Code Cũ — Tái cấu trúc cấu trúc thường giải quyết các vấn đề hiệu suất hệ thống mà bản vá điểm không thể tiếp cận
- Kiểm Tra Bảo Mật — Chạy song song với công việc hiệu suất để đảm bảo tối ưu không đưa vào regression bảo mật
Điểm mấu chốt: Leo thang hiệu suất cảm thấy cấp bách vì chúng thực sự cấp bách — và con đường nhanh nhất từ API chậm trở lại thời gian phản hồi nhanh là profiling có hệ thống theo sau là các bản sửa có mục tiêu, không phải đoán mò và hy vọng.