[Tip trick cho việc tạo một hệ Pub Sub hiệu quả high avail, high performance]

Vâng cũng là một pattern đầy rẫy trên mạng của Java, không hề mới tí nào, nay xin chia sẻ cùng ace những ai cũng định tìm hiểu và tạo một hệ PubSub tương đương đang có …xong có màu sắc của riêng mình, để hỗ trợ trao đổi data qua lại cỡ triệu message/giây.

👉Vâng, khi nói tới PubSub đó là một hệ thống lấy chuyển tin/data từ nơi phát và phát đi tới những nơi đăng ký tin/data. Cho dễ hình dung bạn cứ tưởng tượng là kênh Youtube của bạn được ai đó Subcribe, thế là bạn tạo tin mới, tin đó sẽ tự động gửi tới nhiều Subcriber đăng ký.

Rộng ra PubSub rất cớ lợi cho ai hứng tin nhanh nhất có thể khi ai đó trong mạng xã hội nào đó: comment xấu tối cho nhiệm vụ nghe ngóng… hay có biến đổi trong file, system không như ý mà đòi… phản ứng nhanh. Các bạn làm dữ liệu lớn rất thích những alert kiểu này.

👉Vậy tại sao dùng Java, Go mà không dùng ngôn ngữ khác: lý do đơn giản họ đã thống kê rồi: với Java, Go các thread đc tối ưu hơn, và dễ quản lý hơn. Trong khi đó các ngôn ngữ bậc cao như .NET, NodeJS, PHP, Ruby, Python… chưa tối ưu multi thread và queue… so với Java, Go. Hoặc là bạn phải đầu tư time và viết rất nhiều.

👉Tiếp, tại sao lại dùng queue tự tạo, workload/poolthread tự tạo, tại sao không dùng ActiveMQ, RabbitMQ, MQTT??? Như các fans đều biết:

  • MQTT sẽ ko thể tạo message quá dài hoặc header quá 2 bit
  • Rabbit và Active quá bản quyền. Và những màu cờ sắc áo kiểu hãng riêng cần có xử lý riêng cho…chuyên nghiệp.

Vậy anh e đành dùng java.util.concurrent thôi. Chỉ cần 1 thư viện này đã đủ cho mọi ng triển khai mọi thứ rồi. Thêm nữa a e nên viết với những gì tự tạo thì hay hơn.

👉Vậy thiết kế sẽ thế nào?

  • Cần tạo lớp riêng của mình như: message, sub, pubsub
  • Cần tạo operation chuyên biệt khi ứng message thì nên đưa và stream, và queue, cùng threadpool
  • Java util concurr … cũng đã có sẵn các hàm quản lý các thread. Vậy cần làm bổ sung một monitor để kiểm soát thread nào xong, đóng và mở tiếp cho thread khác.

👉Rủi ro khi sử dụng Thread Pools
Nút chết: hiện tượng tất cả các luồng thực thi đang chờ kết quả từ các luồng bị chặn đang chờ trong hàng đợi do không có luồng để thực thi.
–> giải pháp: luôn check và đóng luồng.

Rò rỉ luồng: Rò rỉ luồng xảy ra nếu một luồng bị xóa khỏi nhóm để thực thi một tác vụ nhưng không được mở lại khi tác vụ hoàn thành.
–> cần mở mới những luồng khi luồng cũ đóng. Luôn check có bao nhiêu luồng đã/đang chạy.

Thiếu tài nguyên: Nếu kích thước nhóm luồng rất lớn thì thời gian sẽ bị lãng phí khi chuyển ngữ cảnh giữa các luồng. Có thể gây vấn đè thiếu tài nguyên.
–> lưu tâm và check có bao nhiêu mem trong hệ thống để mở thêm luồng

👉Điểm quan trọng khác:
Dễ gây nút chết, khi đơi thành hàng.

Thận trong khi sử dụng 1 luồng cho một hoạt động lâu dài. Nó có thể dẫn đến luồng chờ mãi mãi và cuối cùng sẽ dẫn đến rò rỉ tài nguyên.

Luồng được kết thúc rõ ràng vào cuối. Nếu điều này không được thực hiện, thì chương trình sẽ tiếp tục thực thi và không bao giờ kết thúc.

Nên chỉnh, sử dụng các nhóm luồng khác nhau cho các loại tác vụ khác nhau.

👉Tối ưu lượng luồng:
Kích thước tối ưu của nhóm luồng phụ thuộc vào số lượng bộ xử lý có sẵn và tính chất của các tác vụ. Trên hệ thống bộ xử lý N cho hàng đợi các quy trình loại tính toán, kích thước nhóm luồng tối đa là N hoặc N + 1 sẽ đạt được hiệu quả tối đa. Cần tính đến tỷ lệ thời gian chờ (W) và thời gian phục vụ (S) cho một yêu cầu; dẫn đến kích thước nhóm tối đa là N * (1+ W / S) cho hiệu quả tối đa.

Mong ý kiến từ anh em cùng phát triển hệ PubSub

Comments

comments