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

  1. Tìm service chiếm nhiều thời gian.
  2. Xem Profile.
  3. Phân tích downstream dependency.
  4. 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.