Automation

Polling hay webhook: nên dùng cách nào để nhận dữ liệu?

So sánh polling và webhook theo độ trễ, rate limit, khả năng lấy lại dữ liệu cùng cách kết hợp hai cơ chế trong workflow production.

Polling hay webhook: nên dùng cách nào để nhận dữ liệu?
Mục lục

Bạn đang cần tích hợp một phần mềm quản lý công việc vào quy trình tự động. API của họ cho phép bạn định kỳ gọi lấy danh sách bản ghi mới, đồng thời cũng cung cấp webhook để gửi thông báo mỗi khi có trạng thái thay đổi. Cả hai cách đều đưa được dữ liệu vào luồng xử lý. Câu hỏi khó hơn là cách nào vẫn đáng tin khi kết nối bị gián đoạn, workflow tạm dừng hoặc số lượng bản ghi tăng lên.

Webhook thường được ưu tiên vì nhận tín hiệu gần như tức thì. Polling lại dễ hình dung hơn vì workflow chủ động gọi API theo lịch hẹn giờ. Tuy nhiên, tốc độ chỉ là một phần của quyết định. Bạn còn phải tính đến việc: API có hỗ trợ con trỏ dữ liệu (cursor) không, webhook có được gửi lại khi lỗi mạng không, các bản ghi bị xóa được biểu diễn ra sao và hệ thống sẽ lấy lại phần dữ liệu bị lỡ bằng cách nào.

So sánh Polling và Webhook trong kiến trúc tự động hóa

So sánh cơ chế Polling (Kéo) và Webhook (Đẩy), cùng mô hình lai Push-to-Pull kết hợp đối soát dữ liệu an toàn.

Polling và webhook khác nhau ở điểm khởi đầu

Với polling, workflow chủ động gọi API theo lịch để hỏi xem có dữ liệu mới hoặc thay đổi hay không. Sau mỗi lần chạy, nó lưu một mốc kiểm tra (checkpoint) để lần sau tiếp tục từ vị trí cũ. Checkpoint có thể là cursor, sync token hoặc mốc thời gian do API quy định.

Với webhook, hệ thống nguồn gửi một HTTP request tới endpoint bạn đã đăng ký khi có sự kiện phát sinh. Request đó đánh thức workflow mà không cần chờ đến lần kiểm tra kế tiếp. Endpoint nhận vẫn phải xác thực nguồn gửi, ghi nhận delivery và xử lý các trường hợp nhà cung cấp gửi lại cùng một sự kiện.

Cả hai cơ chế đều có trạng thái (state) cần quản lý: Polling cần lưu vị trí đã đồng bộ. Webhook cần lưu mã định danh lượt gửi (delivery ID), trạng thái xử lý và dấu vết các lần gửi lại. Việc không nhìn thấy state trên sơ đồ kéo thả của workflow không đồng nghĩa với việc bạn có thể bỏ qua nó trong thực tế vận hành.

Chọn webhook khi cần phản ứng sớm và bên gửi có thỏa thuận rõ ràng

Webhook phát huy tối đa lợi thế khi công việc cần bắt đầu ngay sau khi sự kiện phát sinh, chẳng hạn tạo yêu cầu xử lý khi tài khoản bị khóa hoặc cập nhật trạng thái đơn hàng. Hệ thống nguồn chỉ gửi request lúc có việc phát sinh, giúp bạn không phải liên tục gọi API để nhận về những phản hồi rỗng không có dữ liệu mới.

Hiệu quả của cách tiếp cận này phụ thuộc vào những gì nhà cung cấp thực sự hỗ trợ. Trước khi chọn webhook, bạn nên kiểm tra tài liệu của đối tác để làm rõ các điểm sau:

  • Có đúng loại sự kiện và hành động mà quy trình cần hay không.
  • Payload gửi sang chứa đủ dữ liệu hay chỉ là thông báo tài nguyên vừa thay đổi.
  • Có chữ ký bảo mật và mã định danh từng lượt gửi (delivery ID) không.
  • Nhà cung cấp sẽ thử gửi lại trong bao lâu nếu endpoint của bạn tạm thời mất kết nối.
  • Có giao diện hoặc API để xem lịch sử và chủ động gửi lại delivery thất bại hay không.
  • Cấu hình đăng ký (subscription) có thời hạn hay cần gia hạn định kỳ không.

Nếu thiếu sự kiện cần thiết, bạn không thể bù đắp chỉ bằng cách viết thêm code ở phía nhận. Một webhook chỉ báo “tài nguyên đã đổi” cũng chưa đủ để cập nhật dữ liệu đích; worker sẽ phải gọi API lấy trạng thái hiện tại sau khi nhận tín hiệu.

Bạn cũng cần vận hành một endpoint HTTPS công khai để bên gửi có thể truy cập. Endpoint này phải được theo dõi lỗi xác thực, xử lý tải tăng, lưu sự kiện trước khi phản hồi và bảo vệ secret như đã trình bày trong bài Webhook là gì và cần kiểm tra gì trước khi đưa vào production?.

Polling phù hợp khi API là đường lấy thay đổi đáng tin cậy hơn

Nhiều hệ thống không cung cấp webhook cho dữ liệu bạn cần. Có những API chỉ phát sự kiện cho một vài thay đổi lớn, hoặc webhook của họ không hỗ trợ gửi lại khi gặp lỗi. Khi đó, polling là lựa chọn thực tế và đáng tin cậy hơn nếu API hỗ trợ lọc và phân trang tốt.

Polling cũng phù hợp cho những công việc vốn dĩ chạy theo đợt (batch processing). Báo cáo tài chính tổng hợp cuối ngày không nhất thiết phải kích hoạt mỗi khi có một giao dịch phát sinh. Việc gom lại đọc một lần theo khoảng dữ liệu, xử lý thành từng mẻ rồi đối chiếu kết quả sẽ dễ kiểm soát hơn nhiều so với việc duy trì hàng ngàn lượt chạy lắt nhắt.

Độ trễ của polling phụ thuộc vào lịch chạy và thời gian xử lý. Thăm dò quá thường xuyên sẽ tạo nhiều request rỗng và làm cạn kiệt hạn mức gọi API (rate limit). Thăm dò quá thưa lại khiến dữ liệu đến muộn. Chu kỳ phù hợp cần xuất phát từ nhu cầu thực tế: nếu bản ghi đến chậm tới lần chạy kế tiếp thì có gây ảnh hưởng gì không, và lượng dữ liệu tồn đọng lớn nhất có được xử lý xong trước lần chạy sau hay không.

Khả năng vận hành hạ tầng cũng ảnh hưởng đến lựa chọn này. Khi máy chủ nhận nằm trong mạng nội bộ không thể mở cổng tiếp nhận kết nối từ Internet, polling theo chiều ra ngoài (outbound) sẽ thuận tiện hơn rất nhiều mà không cần cấu hình reverse proxy hay mở cổng trên tường lửa.

Đừng polling bằng cách tải lại toàn bộ dữ liệu

Một tác vụ gọi API danh sách rồi tải toàn bộ dữ liệu ở mỗi lần chạy chỉ có thể hoạt động khi dữ liệu còn ít. Theo thời gian, phản hồi từ máy chủ ngày càng lớn, phải lật nhiều trang hơn và bạn sẽ lãng phí toàn bộ quota API vào những bản ghi không hề thay đổi.

Bạn nên ưu tiên cơ chế đồng bộ phần gia tăng (incremental sync) do API cung cấp. Google Calendar là một ví dụ chuẩn mực: lần đầu tiên ứng dụng thực hiện đồng bộ toàn bộ (full sync) và nhận về một chuỗi nextSyncToken. Ở các lần sau, bạn chỉ cần gửi kèm token này để máy chủ chỉ trả về đúng những sự kiện đã thêm, sửa hoặc xóa kể từ lần trước. Nếu kết quả có nhiều trang, token dùng cho lần kế tiếp chỉ xuất hiện ở trang cuối cùng.

Quy trình polling an toàn cần tuân thủ các bước:

  1. Đọc mốc kiểm tra (checkpoint) đã hoàn tất gần nhất.
  2. Gọi API với cursor hoặc sync token tương ứng.
  3. Đọc tuần tự từng trang và xử lý dữ liệu theo mã định danh duy nhất.
  4. Ghi nhận cả bản ghi cập nhật lẫn bản ghi đã bị xóa theo đúng thỏa thuận API.
  5. Chỉ lưu checkpoint mới sau khi toàn bộ mẻ dữ liệu (batch) đã xử lý xong hoàn toàn.

Bước cuối cùng là rào chắn khôi phục quan trọng: nếu bạn lưu checkpoint ngay khi vừa đọc xong trang đầu rồi ứng dụng bị crash ở trang kế tiếp, lần chạy sau sẽ bắt đầu từ checkpoint mới và bỏ qua phần dữ liệu chưa xử lý. Khi một batch gặp lỗi, checkpoint cũ phải được giữ nguyên để workflow có thể đọc lại dữ liệu trong lần chạy tiếp theo.

Nếu API chỉ cho lọc theo thời gian cập nhật

Không phải API nào cũng hỗ trợ sync token. Nhiều endpoint chỉ nhận tham số như updated_since hoặc updated_at. Ranh giới thời gian chính là nơi dễ làm rơi rụng bản ghi nhất:

  • Hai bản ghi có thể có cùng thời điểm cập nhật (đặc biệt khi hệ thống nguồn chỉ lưu mốc thời gian chính xác đến giây).
  • Một bản ghi khác bị sửa đúng vào lúc workflow đang lật trang.

Nếu lần chạy sau bạn chỉ truy vấn dữ liệu có thời điểm lớn hơn mốc cuối cùng của lần trước, các bản ghi nằm trùng mốc thời gian có thể bị bỏ qua.

Giải pháp an toàn là thiết kế một cửa sổ chồng lấn (overlap window): mỗi lần chạy, bạn lùi mốc thời gian lại một khoảng ngắn (ví dụ 2 đến 5 phút) so với checkpoint cũ, sau đó dùng mã định danh duy nhất (Unique ID) để loại bỏ những bản ghi đã xử lý trước đó.

Trường hợp xóa dữ liệu cũng cần được kiểm tra riêng. Một bản ghi đã biến mất khỏi cơ sở dữ liệu sẽ không xuất hiện trong danh sách “được cập nhật gần đây” nếu API không hỗ trợ đánh dấu xóa ảo (soft delete hoặc tombstone). Khi dữ liệu đích cần phản ánh thao tác xóa, bạn sẽ cần thêm endpoint nhật ký kiểm toán (audit log) hoặc một đợt quét đối chiếu toàn bộ theo lịch định kỳ.

Giảm số lượng request mà không làm mất thay đổi

Nhiều tài liệu API cung cấp sẵn cơ chế giúp bạn polling hiệu quả mà không lãng phí tài nguyên. Nếu endpoint có hỗ trợ ETag hoặc Last-Modified, hãy lưu lại giá trị này và gửi kèm qua header If-None-Match hoặc If-Modified-Since ở lần gọi kế tiếp.

Khi dữ liệu phía nguồn không có gì thay đổi, máy chủ sẽ trả về mã 304 Not Modified với phần thân phản hồi rỗng. Điều này giúp tiết kiệm băng thông mạng. Đặc biệt, GitHub quy định rằng các conditional request hợp lệ nhận về mã 304 sẽ không bị tính vào hạn mức gọi API chính (rate limit).

Bạn cũng nên tuân thủ header x-poll-interval nếu bên cung cấp dịch vụ yêu cầu khoảng nghỉ tối thiểu giữa các lần gọi. Khi nhận mã lỗi 429 Too Many Requests, workflow nên tạm dừng theo thời gian chỉ dẫn trong header Retry-After hoặc thời điểm reset quota của nhà cung cấp.

Webhook làm tín hiệu, API giữ trạng thái hiện tại

Bạn không nhất thiết phải chọn duy nhất một cơ chế. Mô hình kết hợp giữa webhook và API (thường thấy ở Google Calendar Push Notifications) mang lại sự cân bằng rất tốt: webhook chỉ đóng vai trò là tín hiệu báo rằng tài nguyên vừa thay đổi, sau đó worker sẽ gọi API để thực hiện đồng bộ phần gia tăng.

Mô hình này giúp phân định trách nhiệm rõ ràng:

  • Webhook giúp quy trình được kích hoạt sớm mà không phải thăm dò liên tục.
  • API cung cấp dữ liệu đầy đủ và phản ánh đúng trạng thái mới nhất.
  • Con trỏ dữ liệu (cursor) ghi nhận chính xác phần thay đổi đã được đồng bộ.
  • Idempotency ngăn chặn việc áp dụng một bản ghi hai lần.

Nếu có nhiều webhook gửi đến dồn dập cho cùng một tài nguyên trong thời gian ngắn, worker có thể gom tín hiệu lại trước khi gọi API để tránh tạo ra các lượt đọc trùng lặp.

Cách làm này cũng giải quyết tốt bài toán lệch thứ tự delivery: khi một sự kiện cũ đến sau sự kiện mới, worker không áp dụng trực tiếp payload cũ vào cơ sở dữ liệu mà gọi API lấy tài nguyên hiện tại, giúp dữ liệu luôn ở phiên bản mới nhất.

Đối chiếu bù dữ liệu là đường khôi phục an toàn

Webhook có thể không tới endpoint khi hệ thống nhận tạm dừng hoạt động hoặc đối tác hết thời hạn lưu trữ lượt gửi. Polling cũng có thể gián đoạn do lỗi cursor hoặc thông tin xác thực hết hạn. Hệ thống giám sát giúp bạn biết tác vụ thất bại, nhưng không tự tìm lại phần dữ liệu bị thiếu.

Với những quy trình quan trọng, bạn nên bổ sung một tác vụ đối chiếu bù (reconciliation). Tác vụ này chạy định kỳ vào các khung giờ thấp điểm, quét lại dữ liệu nguồn trong một khoảng thời gian hoặc từ checkpoint đã biết để so sánh với các bản ghi đã xử lý. Những bản ghi bị thiếu sẽ được đưa trở lại luồng xử lý có sẵn cơ chế chống trùng.

Tần suất đối chiếu phụ thuộc vào mức độ chấp nhận trễ của nghiệp vụ và chi phí gọi API. Điểm mấu chốt là tác vụ có thể tìm ra sự kiện bị bỏ lỡ mà không tạo thêm dữ liệu trùng lặp trên hệ thống đích.

Ma trận lựa chọn

Tình trạng của hệ thống nguồn và công việcCách tiếp cận phù hợp
Có webhook đúng event, công việc cần bắt đầu sớmDùng webhook; xác nhận retry, signature và delivery ID
Không có webhook, API hỗ trợ cursor hoặc lọc thay đổiPolling incremental và lưu checkpoint bền vững
Công việc xử lý theo báo cáo hoặc batch định kỳPolling theo lịch phù hợp với thời hạn công việc
Webhook chỉ thông báo tài nguyên đã đổiNhận webhook làm tín hiệu rồi gọi API lấy trạng thái hiện tại
Yêu cầu độ tin cậy cao, không được bỏ sót dữ liệuDùng webhook hoặc polling chính, kết hợp job reconciliation
API chỉ cho phép đọc toàn bộ dữ liệuDùng conditional request (ETag), đánh giá chi phí quota
Endpoint nhận nằm trong mạng nội bộ không mở publicPolling outbound theo lịch nếu API và độ trễ cho phép

Bảng trên giúp bạn thu hẹp hướng thiết kế ban đầu. Quyết định cuối cùng vẫn cần dựa trên tài liệu chính thức của API đang tích hợp, vì phạm vi sự kiện, con trỏ dữ liệu, thời hạn lưu log và hạn mức gọi của mỗi hệ thống là khác nhau.

Thử nghiệm trước khi đưa vào vận hành

Nếu chọn polling, bạn nên chạy thử với nhiều trang kết quả, thử trường hợp bản ghi cập nhật rơi vào ranh giới hai lần chạy, bản ghi bị xóa và cursor hết hiệu lực. Hãy thử tắt job giữa lúc đang xử lý batch rồi bật lại để kiểm tra xem checkpoint có bị tiến sai hay không.

Nếu chọn webhook, hãy thử nghiệm các tình huống delivery bị gửi lặp lại, gửi sai thứ tự hoặc worker gặp sự cố sau khi đã tiếp nhận sự kiện. Bài viết Workflow lỗi giữa chừng: retry và khôi phục thế nào? sẽ giúp bạn xác định rõ bước nào có thể chạy lại an toàn.

Với mô hình kết hợp, bạn nên thực hiện một bài kiểm tra quan trọng: cố tình bỏ qua một notification rồi chạy tác vụ đối chiếu bù (reconciliation). Thiết kế đạt yêu cầu khi dữ liệu bị thiếu được tìm lại đầy đủ mà không sinh thêm bản ghi trùng lặp.

Quy trình nhận dữ liệu chỉ thực sự hoàn thiện khi bạn đã xác định rõ nguồn tạo tín hiệu, nơi lưu checkpoint, độ trễ cho phép và phương án xử lý khi mất kết nối. Để kết nối cơ chế nhận dữ liệu này vào bức tranh vận hành tổng thể, bạn có thể tham khảo bài Một workflow automation gồm những thành phần nào? và cân nhắc các giới hạn nghiệp vụ tại bài Khi nào không nên tự động hóa một quy trình?. Nếu bạn đang bắt đầu xây dựng quy trình đầu tiên, hãy tham khảo lộ trình tại Tự động hóa công việc nên bắt đầu từ quy trình nào?.

Nguồn tham khảo

Chia sẻ bài viết hữu ích

Gửi bài viết này cho đồng nghiệp

Đọc tiếp

Bài nên đọc tiếp

Xem tất cả bài về Automation