Trong thời đại công nghệ phát triển không ngừng, ngày càng có nhiều hệ thống phần mềm tiên tiến hơn ra đời, đi kèm với đó là dữ liệu ngày càng lớn và phức tạp hơn. Để xử lý dữ liệu lớn và phức tạp, các hệ thống phần mềm hiện đại thường được thiết kế theo mô hình Microservices. Mô hình Microservices giúp chia nhỏ hệ thống thành các dịch vụ (service) nhỏ hơn, mỗi dịch vụ lại có thể có nhiều thành phần nhỏ hơn nữa.

Một trong những thách thức lớn nhất khi xây dựng hệ thống Microservices là làm sao để các dịch vụ giao tiếp với nhau một cách hiệu quả. Trong bài viết này, chúng ta sẽ cùng tìm hiểu về một kỹ thuật giao tiếp giữa các dịch vụ hoặc các thành phần trong mô hình Microservices, đó là kỹ thuật Polling.

Đây là bài blog thuộc series System Design của mình, nếu bạn quan tâm đến các vấn đề liên quan đến thiết kế hệ thống phần mềm, hãy theo dõi series này để cập nhật những kiến thức mới nhất nhé!

Một số khái niệm và thuật ngữ

Trước khi đi vào chi tiết về Polling, chúng ta cùng đi qua một số khái niệm và thuật ngữ nhé:

  • Việc giao tiếp trong một hệ thống phần mềm là giữa nhiều dịch vụ hoặc thành phần khác nhau.
  • Có hai thuật ngữ khi nói đến việc giao tiếp giữa hai thành phần bất kỳ trong mô hình Microservices, chúng ta thường nghĩ phân biệt ra upstreamdownstream. Upstream là thành phần trả về dữ liệu, còn downstream là thành phần nhận dữ liệu từ upstream.

💡 Một ví dụ khá dễ hiểu và thực tế về upstream và downstream là chúng giống như thượng nguồn và hạ nguồn của một con sông. Thượng nguồn là nơi nước chảy ra, còn hạ nguồn là nơi nước chảy đến, hạ nguồn sẽ phải phụ thuộc vào thượng nguồn để có nước chảy xuống. Vậy nên, ở đây upstream sẽ là thượng nguồn, còn downstream là hạ nguồn.

  • Nếu áp dụng vào các kiến trúc và hệ thống thực tế thì chúng có thể là:

    • Client-Server: Client (Browser) là downstream, Server (Máy chủ) là upstream.
    • Service-Service: Trong mô hình Microservice gồm nhiều services thì phía gửi yêu cầu là downstream, phía nhận yêu cầu là upstream.
    • Service-Database: Service gửi yêu cầu đến Database để lấy dữ liệu, Service là downstream, Database là upstream.
  • Chúng ta có thể thấy rằng hai khái niệm upstream và downstream là khá phổ biến và quan trọng trong việc thiết kế hệ thống phần mềm. Chúng có thể áp dụng trong nhiều trường hợp, ngữ cảnh khác nhau, giúp chúng ta dễ dàng hơn trong việc hiểu và thiết kế hệ thống.

Vậy Polling là gì?

Hiểu một cách đơn giản thì Polling là một kỹ thuật mà một downstream sẽ liên tục gửi yêu cầu đến upstream để kiểm tra và lấy trạng thái, dữ liệu mới nhất nếu có thể. Kỹ thuật Polling thường được sử dụng trong các trường hợp sau:

  • Downstream cần lấy dữ liệu mới nhất từ upstream mà không biết dữ liệu đó khi nào được cập nhật.
  • Downstream cần kiểm tra trạng thái của upstream mà không biết trạng thái đó khi nào thay đổi.

Từ bản chất của polling, có 2 cách thức Polling phổ biến: Long PollingShort Polling.

Short Polling

Short Polling là cách thức Polling mà downstream sẽ gửi yêu cầu đến upstream để lấy dữ liệu mới nhất, và upstream sẽ trả về dữ liệu ngay lập tức cho dù dữ liệu cần lấy đã thay đổi hay không. Tuỳ vào cách thức cấu hình, downstream sẽ gửi yêu cầu Polling sau một khoảng thời gian nhất định (interval time).

Cách thức hoạt động

sequenceDiagram
    participant D as Downstream
    participant U as Upstream
	Note right of D: interval time = 5s
	loop Every 5 seconds (interval time)
		D->>U: Poll (request) for data
		U->>D: Data (response)
	end

Trong sơ đồ trên, chúng ta có thể thấy cách thức hoạt động giữa thành phần Upstream và Downstream như sau:

  • Khi downstream cần lấy dữ liệu từ upstream, downstream sẽ gửi yêu cầu đến upstream để lấy dữ liệu.
  • Sau một khoảng thời gian, ở ví dụ này là 5 giây, downstream sẽ gửi yêu cầu tiếp theo đến upstream để lấy dữ liệu mới nhất, và quá trình này sẽ tiếp tục như vậy cho đến khi downstream không cần lấy dữ liệu nữa.

Ưu điểm

  • Đơn giản và dễ triển khai: Short Polling không cần phức tạp về cấu hình, dễ dàng triển khai và sử dụng.
  • Dễ dàng cấu hình interval time: Dễ dàng cấu hình interval time để downstream gửi yêu cầu Polling sau một khoảng thời ngắn nếu cần.

Nhược điểm

  • Tăng độ trễ: Do downstream gửi yêu cầu Polling sau một khoảng thời gian nhất định, nên dữ liệu mà downstream nhận được có thể là dữ liệu cũ, dẫn đến tăng độ trễ trong việc cập nhật dữ liệu mới nhất.
  • Tốn tài nguyên: Do downstream gửi yêu cầu Polling sau một khoảng thời gian nhất định, nếu trong khoảng thời gian đó dữ liệu không thay đổi, downstream vẫn phải tiêu tốn tài nguyên để gửi yêu cầu Polling. Mặc khác nếu dữ liệu thay đổi quá nhiều trong một khoảng thời đó, upstream và downstream sẽ phải xử lý một lượng lớn yêu cầu Polling, dẫn đến tốn tài nguyên cho cả hai phía.

Long Polling

Long Polling là cách thức Polling mà downstream sẽ gửi yêu cầu đến upstream để lấy dữ liệu mới nhất, và upstream sẽ không trả về dữ liệu ngay lập tức cho đến khi dữ liệu cần lấy đã thay đổi, khi đó upstream sẽ trả về dữ liệu cho downstream. Và sau khi downstream nhận được dữ liệu, downstream sẽ gửi yêu cầu Polling tiếp theo để lấy dữ liệu mới nhất.

Cách thức hoạt động

Cách thức hoạt động của Long Polling giữa 2 upstream và B như sau:

sequenceDiagram
	participant D as Downstream
	participant U as Upstream
	Note right of U: timeout = 10s
	loop
		D->>U: Poll (request) for data
		alt Data is changed
			U->>D: Data (response)
		else Timeout
			U->>D: Timeout (response)
		end
		U->>D: Data (response)
	end

Sơ đồ trên có vẻ phức tạp hơn so với Short Polling, chúng ta cùng đi vào chi tiết nhé:

  • Khi một downstream cần lấy dữ liệu từ upstream, downstream sẽ gửi yêu cầu đến upstream để lấy dữ liệu. Upstream sẽ không trả về dữ liệu ngay lập tức cho downstream, mà sẽ chờ cho đến khi dữ liệu cần lấy đã thay đổi.
  • Nếu dữ liệu cần lấy đã thay đổi, upstream sẽ trả về dữ liệu cho downstream. Nếu dữ liệu chưa thay đổi mà thời gian chờ đã hết (timeout), upstream sẽ thông báo cho downstream biết là đã hết thời gian chờ mà dữ liệu chưa thay đổi (điều này tránh tình trạng upstream giữ connection quá lâu).
  • Sau khi downstream nhận được dữ liệu từ upstream, downstream sẽ gửi yêu cầu Polling tiếp theo để lấy dữ liệu mới nhất và quá trình này sẽ tiếp tục như vậy cho đến khi nó không cần lấy dữ liệu nữa.

Ưu điểm

  • Giảm độ trễ: Do upstream chỉ trả về dữ liệu khi dữ liệu cần lấy đã thay đổi, nên giảm độ trễ trong việc cập nhật dữ liệu mới nhất.
  • Tiết kiệm tài nguyên: Do upstream chỉ trả về dữ liệu khi dữ liệu cần lấy đã thay đổi, nên giảm thiểu lưu lượng truy cập giữa 2 dịch vụ, đồng thời giảm tải cho cả 2 dịch vụ.

Nhược điểm

  • Phức tạp hơn Short Polling: Long Polling cần phải xử lý thêm timeout để tránh trường hợp upstream giữ connection quá lâu.
  • Khó cấu hình timeout: Cần phải cấu hình timeout sao cho phù hợp với tần suất cập nhật dữ liệu, nếu cấu hình timeout quá lớn sẽ dẫn đến tăng độ trễ, còn cấu hình timeout quá nhỏ sẽ dẫn đến tăng tải cho cả 2 dịch vụ.

Bảng so sánh

Short PollingLong Polling
Đơn giản và dễ triển khaiPhức tạp hơn Short Polling
Upstream phản hồi ngayUpstream đợi đến khi có dữ liệu mới phản hồi
Tăng độ trễGiảm độ trễ
Tốn tài nguyênTiết kiệm tài nguyên

Kết luận

Trong bài viết này, chúng ta đã cùng tìm hiểu về kỹ thuật Polling, một kỹ thuật giao tiếp giữa các dịch vụ hoặc các thành phần với nhau. Chúng ta đã tìm hiểu về 2 cách thức Polling phổ biến là Short Polling và Long Polling, cùng với ưu điểm và nhược điểm của từng cách thức Polling.

Hy vọng rằng bài viết này sẽ giúp bạn hiểu rõ hơn về kỹ thuật Polling và áp dụng nó vào thiết kế hệ thống của mình một cách hiệu quả nhất. Trong bài viết sau chúng ta sẽ đi sâu vào việc áp dụng Polling vào thực tế nhé.

Chào tạm biệt và hẹn gặp lại ở bài viết tiếp theo 🖐