External Call Analysis With Jennifer
External Call Analysis With Jennifer
Giới thiệu
Trong nhiều hệ thống enterprise, thời gian xử lý request không nằm trong JVM.
Nguyên nhân thực sự thường nằm ở:
- REST API
- SOAP Service
- TCP Socket
- Database
- Middleware
- Hệ thống đối tác
Từ góc nhìn của người dùng:
Màn hình chậm
Từ góc nhìn của JVM:
Thread bị giữ quá lâu
Từ góc nhìn của Jennifer:
External Call chiếm thời gian lớn nhất
Bài viết này ghi lại các kinh nghiệm điều tra những trường hợp như vậy.
External Call Là Gì
External Call là mọi hoạt động mà JVM phải chờ phản hồi từ bên ngoài.
Ví dụ:
Web User
|
v
JEUS
|
+--> DB
|
+--> API A
|
+--> API B
|
+--> MQ
Trong thời gian chờ phản hồi:
Thread vẫn bị chiếm dụng
Mặc dù CPU gần như không làm gì.
Dấu Hiệu Nhận Biết
Active Thread Tăng
Ví dụ:
Max Thread = 100
Active Thread = 95
hoặc
Active Thread = 100
TPS Không Cao
Ví dụ:
TPS = 57
Response Time Tăng
Ví dụ:
100ms
200ms
500ms
1200ms
CPU Bình Thường
Ví dụ:
CPU = 30%
nhưng hệ thống vẫn chậm.
Đây là dấu hiệu rất thường gặp khi bị nghẽn External Call.
Một Hiểu Lầm Phổ Biến
Nhiều người nhìn thấy:
CPU thấp
và kết luận:
Server khỏe
Điều này không đúng.
Ví dụ:
Response resp = httpClient.execute(request);
Thread sẽ đứng đợi.
Trong thời gian đợi:
CPU thấp
nhưng:
Thread vẫn bị giữ
Kiến Trúc Điển Hình
Trường Hợp Đơn Giản
User
|
v
Service A
|
v
Database
Khá dễ điều tra.
Trường Hợp Thực Tế
User
|
v
Portal
|
+--> Account API
|
+--> Customer API
|
+--> Notification API
|
+--> Billing API
Lúc này việc xác định API nào đang chậm trở nên khó khăn hơn nhiều.
Quy Trình Điều Tra
Bước 1
Xác định thời điểm sự cố.
Ví dụ:
14:35
Bước 2
Mở Monitoring
Kiểm tra:
TPS
Response Time
Active Thread
Active Service
Bước 3
Tìm Service Chậm
Ví dụ:
AccountService
chiếm:
45%
tổng thời gian hệ thống.
Bước 4
Mở Profile
Quan sát breakdown.
Ví dụ:
Service Time
|
+-- Business Logic
|
+-- SQL
|
+-- External Call
Ví Dụ
Total Time = 1200ms
Business Logic = 50ms
SQL = 80ms
External Call = 1070ms
Lúc này gần như chắc chắn nút thắt nằm ở hệ thống khác.
Những Thông Tin Cần Thu Thập
URL
Ví dụ:
/api/customer
Host
Ví dụ:
customer-api.company.local
Thời Gian
Ví dụ:
1050ms
Số Lần Gọi
Ví dụ:
10 lần / request
Đây là lỗi rất phổ biến.
Phân Loại Nguyên Nhân
Hệ Thống Downstream Chậm
Ví dụ:
A
|
v
B
B xử lý:
3000ms
A phải chờ đủ:
3000ms
Timeout Không Hợp Lý
Ví dụ:
readTimeout = 30000
30 giây là quá dài đối với đa số giao dịch online.
Retry Quá Nhiều
Ví dụ:
Call thất bại
Retry 3 lần
Thời gian có thể tăng gấp nhiều lần.
DNS
Đôi khi không phải API chậm.
Mà là:
DNS Lookup
chậm.
SSL Handshake
Xuất hiện nếu:
HTTPS
được thiết lập không đúng cách.
Trường Hợp Thực Tế Đã Gặp
Hiện Tượng
TPS = 57
Response Time = 622 ms
Active Thread = 100
Max Thread = 100
Quan Sát
SQL không tăng bất thường.
CPU không cao.
GC bình thường.
Giả Thuyết
External Call đang giữ thread.
Hướng Điều Tra
- Tìm service chiếm nhiều thời gian.
- Xem Profile.
- Phân tích downstream dependency.
- Thu thêm Thread Dump.
Kết Quả Mong Muốn
Xác định được:
API nào
hoặc
Địa chỉ nào
đang giữ thread lâu nhất.
Thread Dump Và External Call
Trong nhiều trường hợp Thread Dump có thể cho thấy ngay vấn đề.
Ví dụ:
java.net.SocketInputStream
hoặc
sun.nio.ch.SocketChannelImpl
xuất hiện liên tục.
Điều đó có nghĩa:
Thread đang chờ phản hồi mạng
Checklist Điều Tra
Khi Response Time tăng:
- Xác định thời điểm xảy ra lỗi
- Kiểm tra Active Thread
- Kiểm tra Active Service
- Kiểm tra TPS
- Kiểm tra SQL Time
- Kiểm tra External Time
- Kiểm tra timeout
- Kiểm tra retry
- Thu Thread Dump
- Xác định dependency chậm nhất
Lessons Learned
Trong các hệ thống enterprise hiện đại, nguyên nhân gây chậm thường không nằm trong code Java.
Thông thường nút thắt nằm ở:
- Database
- REST API
- SOAP Service
- Message Queue
- Hệ thống đối tác
Khi thấy:
TPS thấp
Response Time cao
Active Thread cao
CPU thấp
hãy nghĩ đến External Call trước khi nghĩ đến việc tăng thread pool.