Bỏ qua để đến nội dung

Giới hạn

10 phút đọc

Ferry API kiểm soát tần suất gọi lệnh theo địa chỉ IP xuất phát của hệ thống đối tác nhằm bảo vệ tính ổn định toàn hệ thống. Trang này mô tả mức giới hạn áp dụng toàn cục, các ngoại lệ được siết chặt tại bước xác nhận xuất vé, và các giới hạn kỹ thuật khác mà đối tác cần xử lý.

Ferry áp dụng cấu hình giới hạn tần suất chung cho toàn bộ API công khai: 50 lệnh gọi trong mỗi 100 mili-giây, đếm theo địa chỉ IP nguồn.

Đơn vị thời gian tính bằng mili-giây (100 ms tương đương 1/10 giây). Do đó, mức 50 lệnh/100 ms tương đương thông lượng xử lý lên tới khoảng 500 lệnh/giây.

Mức trần này được thiết lập để ngăn chặn các đợt bùng nổ lưu lượng hoặc tấn công từ chối dịch vụ thô. Một hệ thống tích hợp đặt vé hoạt động bình thường hiếm khi chạm đến ngưỡng giới hạn này.

Sơ đồ dưới đây cho thấy đường đi của một lệnh gọi qua các tầng giới hạn tốc độ và kết quả nhận được:

flowchart TB
CALL["Một lệnh gọi từ hệ thống của bạn"]
IP{"Lớp 1 — đếm theo địa chỉ IP<br/>50 lệnh trong mỗi 100 mili-giây"}
OVER{"Lớp 2 — bước xác nhận xuất vé?<br/>5 lệnh trong mỗi 60 giây"}
LOCK{"Lớp 3 — khoá xuất vé theo booking<br/>còn hiệu lực 600 giây"}
SOFT{"Lớp 4 — giới hạn mềm xuất vé<br/>5 lần trong mỗi 60 giây"}
OK["Ferry xử lý bình thường"]
E429["Nhận 429<br/>gọi lại theo khoảng lùi tăng dần"]
LOCKED["Nhận lỗi nghiệp vụ 120100<br/>chờ ít nhất 60 giây rồi gọi lại"]
SOFTED["Nhận lỗi nghiệp vụ<br/>không phải 429"]
CALL --> IP
IP -->|"vượt trần IP"| E429
IP -->|"trong trần"| OVER
OVER -->|"không phải bước xác nhận"| OK
OVER -->|"là bước xác nhận, vượt 5 lệnh trong 60 giây"| E429
OVER -->|"là bước xác nhận, trong trần"| LOCK
LOCK -->|"booking đang có tiến trình xuất vé khác"| LOCKED
LOCK -->|"booking rảnh"| SOFT
SOFT -->|"vượt 5 lần trong 60 giây"| SOFTED
SOFT -->|"trong trần"| OK

Khi vượt ngưỡng, hệ thống trả về mã trạng thái HTTP 429 (Too Many Requests) kèm mốc thời gian và đường dẫn gọi API.

Hai lưu ý quan trọng:

  • Không có thông điệp tuỳ biến: Thân phản hồi 429 trả về thông báo lỗi chuẩn từ thư viện bảo vệ. Bộ xử lý lỗi không nên tìm kiếm chuỗi văn bản tiếng Việt cụ thể trong thân phản hồi này.
  • Ferry không ghi log mức lỗi cho mã 429: Tầng lọc lỗi chỉ ghi nhận sự cố từ mã 500 trở lên. Hệ thống Ferry không tự động phát hiện đối tác đang bị chặn tần suất; việc theo dõi tỷ lệ lỗi 429 hoàn toàn thuộc về trách nhiệm giám sát của đối tác.

Chiến lược thử lại khuyến nghị: khi nhận mã 429, áp dụng thuật toán lùi tăng dần có yếu tố ngẫu nhiên (bắt đầu từ 1 giây, nhân đôi sau mỗi lần thử, chặn trần 30 giây, tối đa 5 lần).

Phần lớn các API sử dụng mức giới hạn toàn cục. Ba nhóm thao tác sau đây có quy định riêng:

Nhóm lệnh gọiGiới hạn áp dụngCơ chế đếmÝ nghĩa thực tế
Toàn hệ thống (mặc định)50 lệnh / 100 mili-giâyTheo địa chỉ IPÁp dụng cho tra cứu, tạo đơn, quản lý chung
Bước xác nhận xuất vé5 lệnh / 60 giâyTheo địa chỉ IPSiết chặt để bảo vệ kết nối với cổng hãng tàu
Tra cứu booking công khai60 lệnh / 60 giâyTheo địa chỉ IPDành cho trang tra cứu công khai của khách cuối
Kênh sự kiện SSE thời gian thựcMiễn giới hạn tần suấtKhông áp dụngChỉ phục vụ phiên đăng nhập web, không mở cho API key

Phân biệt hai cơ chế giới hạn tại bước xác nhận xuất vé

Phần tiêu đề “Phân biệt hai cơ chế giới hạn tại bước xác nhận xuất vé”

Bước xác nhận xuất vé có hai cơ chế kiểm soát cùng mang con số 5 lần / 60 giây nhưng khác biệt hoàn toàn về bản chất:

Cơ chếCăn cứ đếmPhản hồi khi vượt ngưỡng
Giới hạn cứng tầng mạngĐịa chỉ IP của bạnHTTP 429 kèm thông điệp chuẩn
Giới hạn mềm tầng nghiệp vụTừng mã booking cụ thểLỗi nghiệp vụ (mã sáu chữ số), không phải 429

Giới hạn mềm theo booking cho phép tối đa 5 lần xác nhận trong vòng 60 giây trên cùng một booking. Cơ chế này bảo vệ hệ thống khỏi việc người dùng bấm xác nhận liên tục trên một đơn hàng khi lệnh đầu tiên đang được xử lý.

Quy tắc thử lại:

  • Nhận mã 429: Chờ theo khoảng lùi tăng dần rồi gọi lại.
  • Nhận lỗi nghiệp vụ: Tra cứu lại trạng thái booking trước; việc gọi lại mù quáng sẽ chỉ lặp lại cùng một lỗi nghiệp vụ đó.

Ngoài giới hạn tần suất theo thời gian, đối tác cần lưu ý các trần kỹ thuật sau:

Giới hạnGiá trị trầnHành vi khi vượt quá
Kích thước dữ liệu gửi lên (Payload)Tối đa 1 MBLệnh gọi bị từ chối ngay tại tầng biên
Số bản ghi mỗi trang phân trangTối đa 50 (một số API là 100)Kẹp im lặng: hệ thống tự giới hạn về mức trần mà không báo lỗi
Khoá xuất vé theo bookingGiữ khoá 600 giâyLệnh thứ hai gửi lên khi đang xuất vé nhận mã 120100
Khoá thanh toán theo bookingGiữ khoá 180 giây, độc lập với khoá xuất véLệnh thanh toán đồng thời nhận mã 120100
Mã xác thực email5 lần / 15 phút cho một emailLần thứ 6 trở đi bị từ chối
Hạn chờ webhook gửi ra2.000 mili-giâyĐiểm nhận của bạn chậm hơn 2 giây là mất sự kiện vĩnh viễn

Hai điểm cần lưu ý đặc biệt:

  • Kẹp phân trang im lặng: Yêu cầu lấy 200 bản ghi nhưng chỉ nhận về 50 bản ghi là hành vi bình thường. Đối tác không được kết luận “hết dữ liệu” khi nhận ít bản ghi hơn số lượng yêu cầu mà phải kiểm tra con trỏ phân trang tiếp theo.
  • Hạn chờ webhook là ràng buộc phía bạn: Điểm tiếp nhận webhook của bạn bắt buộc phải trả lời trong vòng 2 giây. Hãy áp dụng mô hình nhận sự kiện vào hàng đợi và phản hồi 200 ngay lập tức.

Năm bước xử lý theo thứ tự:

  1. Giảm số tiến trình phát lệnh thay vì tăng luồng: Giới hạn đếm theo địa chỉ IP nguồn, tăng thêm luồng gọi chỉ khiến bộ đếm đầy nhanh hơn và kéo dài thời gian bị chặn.
  2. Áp dụng khoảng lùi tăng dần ngẫu nhiên (jitter): Thêm một khoảng ngẫu nhiên vào thời gian chờ để tránh việc nhiều luồng cùng gọi lại tại một thời điểm.
  3. Tách biệt hàng đợi đọc và ghi: Không để các lệnh tra cứu chuyến hàng loạt chiếm dụng hạn mức của bước xác nhận xuất vé — nơi chỉ cho phép 5 lệnh/60 giây.
  4. Lưu nhật ký mã truy vết (trace ID): Ghi lại thời điểm, mã truy vết và địa chỉ IP của mỗi lần bị trả mã 429 để làm căn cứ đối chiếu.
  5. Liên hệ Ferry nếu dùng chung IP công cộng: Nếu hệ thống bị chặn thường xuyên dù lưu lượng gọi thực tế thấp, khả năng cao bạn đang chia sẻ địa chỉ IP ra ngoài với một đối tác khác.
Hiểu nhầmThực tếHệ quả
Hạn mức cấp riêng cho từng khoá APIBộ đếm tính theo địa chỉ IPHai đối tác sau cùng một NAT IP chặn lẫn nhau
Mức 50 lệnh mỗi 100 giâyĐơn vị là mili-giây (~500 lệnh/giây)Thiết kế hàng đợi quá chậm không cần thiết
Vượt giới hạn luôn trả về mã 429Giới hạn mềm theo booking trả lỗi nghiệp vụBộ thử lại bỏ sót nhánh lỗi nghiệp vụ
Ferry sẽ cảnh báo khi bị chặn 429Hệ thống không ghi log lỗi cho mã 429Bị chặn nhiều giờ mà không bên nào phát hiện
Bị chặn thì tăng luồng gọi để bùTăng luồng khiến bộ đếm IP đầy nhanh hơnThời gian bị chặn kéo dài hơn
Nhận ít bản ghi hơn yêu cầu là lỗiHệ thống kẹp im lặng tối đa 50-100 bản ghiDừng phân trang sớm và bỏ sót dữ liệu
Webhook đến muộn là do Ferry gửi chậmHạn chờ 2 giây tính tại điểm nhận của bạnSửa sai phía, sự kiện vẫn bị rơi mất

Trang này không tương ứng với một nhóm riêng trên giao diện tra cứu API tại https://api.ferry.vn/docs vì giới hạn tốc độ không được hiển thị trên Scalar:

Mục tiêu đối chiếuNhóm trên giao diện API
Bước xác nhận xuất vé (nơi bị siết 5 lệnh / 60 giây)Bookings
Nhóm ghi dữ liệu lớn (chịu trần 1 MB payload)Bookings, Transactions
Nhóm chỉ đọc dùng chung mức toàn cụcVoyages, Organizations, Customers
TrangĐọc khi nào
Lỗi và cách xử lýCần tra cứu chi tiết mã lỗi 429 và các mã nghiệp vụ
Quy ước chungHiểu cơ chế phân trang bằng con trỏ và quy tắc kẹp bản ghi
Đặt vé: vòng đời một bookingThiết kế luồng đặt vé an toàn với các chặng bị siết tần suất
Xuất vé và đơn hàngNắm vững cơ chế khoá và giới hạn mềm khi xuất vé
WebhooksThiết kế điểm nhận sự kiện phản hồi dưới 2.000 ms
Trước khi chạy thậtĐưa việc giám sát mã 429 vào danh sách kiểm tra nghiệm thu
  • Cam kết dịch vụ về hạn mức: Mức 50 lệnh trong 100 ms là ngưỡng kỹ thuật mặc định, không cấu thành cam kết chất lượng dịch vụ (SLA). Ferry có thể điều chỉnh ngưỡng này tuỳ theo tình trạng tải của hệ thống.
  • Header thông báo thời gian chờ: Hiện chưa có thông tin chính thức về việc bộ đếm có trả về tiêu đề Retry-After trong mọi phản hồi 429 hay không; ứng dụng phía bạn cần tự quản lý khoảng lùi chờ an toàn.