Bài viết được sự cho phép của tác giả Giang Phan
Trong cuộc sống để có thể hiểu nhau thì chúng ta cần phải trao đổi thông tin với nhau, chúng ta có thể trao đổi thông tin bằng cách nói chuyện trực tiếp, qua điện thoại, email, zalo, skype, facebook, …
Trong phần mềm, các component của chương trình hoặc các chương trình trong một hệ thống cũng cần trao đổi thông tin với nhau để có thể chạy đồng nhất, việc trao đổi thông tin này thông qua message (tin nhắn).
Trong Java, nó cung cấp một số API cho phép các ứng dụng Java có thể tạo, gửi, nhận và đọc các message. Các API này gọi JMS (Java Message Service) API.
Tìm việc làm Java mới nhất lương up to 2000 USD
Giới thiệu JMS
Message là gì?
Message (Tin nhắn) là một phần thông tin. Nó có thể là một text, XML, JSON hoặc một Entity (đối tượng Java), … Message là dữ liệu rất hữu ích để giao tiếp giữa các hệ thống khác nhau.
Messaging là gì?
Messaging (nhắn tin) là việc trao đổi thông tin giữa các thành phần khác nhau trong cùng một hệ thống hoặc các hệ thống khác nhau. Nó có thể xảy ra theo cách đồng bộ hoặc không đồng bộ.
Ưu điểm của nhắn tin là khả năng tích hợp các nền tảng khác nhau, làm giảm tắc nghẽn hệ thống, tăng cường khả năng mở rộng và nâng cao độ tin cậy gửi nhận tin.
Có 2 mô hình nhắn tin: P2P (Point to Point) và Pub/Sub (Publisher/ Subscriber).
JMS là gì?
Java Message Service (JMS) API là một phần của đặc tả kỹ thuật Java Enterprice Edition (Java EE), là một API trung gian hướng thông báo Java (MOM) để gửi tin nhắn giữa hai hoặc nhiều client.
JMS mô tả các phương thức tạo bởi chương trình Java cho việc: tạo (Create), gửi (Send), nhận (Receive), đọc (Read) tin nhắn.
JMS cho phép giao tiếp giữa các thành phần khác nhau của một ứng dụng phân tán được kết nối lỏng lẻo, đáng tin cậy và hỗ trợ bất đồng bộ.
Giao tiếp giữa các client được tạo ra bởi message broker qua các tiêu chuẩn truyền tin bất đồng bộ như AMQP, MQTT.
JMS API là triển khai để xử lý vấn đề nhà sản xuất-người tiêu dùng.
JMS bao gồm 2 thành phần:
- API : hỗ trợ chức năng cho người phát triển phần mềm.
- SPI (Service Provider Interface) : cho phép các Provider tạo ra tool JMS tích hợp, định hướng cho mọi người sử dụng theo hướng chuẩn hóa.
Khi chúng ta phát triển Hệ thống nhắn tin Java với JMS API, thì chúng ta có thể triển khai cùng một ứng dụng trong bất kỳ JMS Provider software nào.
>>> Xem thêm: Học lập trình Java từ đâu và như thế nào?
MOM là gì?
MOM (Message-oriented middleware hay MQ – Message Queue) là một ứng dụng trung gian hỗ trợ gửi và nhận tin nhắn trong các ứng dụng phân tán.
Cơ chế MOM tương tự như database với việc nhận và gửi message, đảm bảo toàn vẹn dữ liệu, transaction và cân bằng cho việc gửi nhận dữ liệu.
Nơi lưu trữ dữ liệu và tương tác với MOM có tên gọi là Destination.
Một số MOM tiêu biểu:
# | JMS PROVIDER | ORGANIZATION |
---|---|---|
1. | WebSphere MQ | IBM |
2. | Weblogic Messaging | Oracle Corporation |
3. | Active MQ | Apache Foundation |
4. | Rabbit MQ | Rabbit Technologies(acquired by Spring Source) |
5. | HornetQ | JBoss |
6. | Sonic MQ | Progress Software |
7. | TIBCO EMS | TIBCO |
8. | Open MQ | Oracle Corporation |
9. | SonicMQ | Aurea Software |
JMS Broker
Để gửi hoặc nhận tin nhắn, trước tiên, JMS Client phải kết nối với JMS message server (còn gọi là JMS Broker – nhà môi giới):
- Một Connection mở ra một kênh liên lạc giữa client và broker.
- Tiếp theo, client phải thiết lập một session để tạo, tạo và đọc tin nhắn. Bạn có thể nghĩ về session như một luồng thông báo xác định cho một cuộc trò chuyện cụ thể giữa client và broker. Bản thân client là producer hoặc consumer.
- Transaction được tạo bởi client là transaction giữa producer và broker hoặc giữa broker và consumer, nhưng không bao giờ giữa producer và consumer.
- Producer gửi tin nhắn đến destination (đích) mà broker quản lý. Consumer truy cập destination đó để lấy tin nhắn.
- Tin nhắn bao gồm header (tiêu đề), optional properties (thuộc tính), và body (nội dung). Body chứa dữ liệu, header chứa thông tin broker cần định tuyến và quản lý tin nhắn và các thuộc tính có thể được xác định bởi các ứng dụng client hoặc bởi provider để phục vụ nhu cầu của chính họ trong việc xử lý tin nhắn.
- Connection, Session, Destination, Message, Producer và Consumer là những đối tượng cơ bản tạo nên một ứng dụng JMS.
Các thành phần của JMS
- JMS Provider :
- JMS API là một tập hợp các interface, không chứa bất kỳ implementation nào. JMS Provider là một hệ thống bên thứ ba, chịu trách nhiệm implement JMS API để cung cấp các tính năng nhắn tin cho khách hàng.
- JMS Provider còn được gọi là phần mềm MOM. JMS Provider cũng cung cấp một số thành phần UI để quản trị và kiểm soát phần mềm MOM này.
- JMS Provider được viết trên chuẩn Java do đó sẽ chạy được trên đa nền tảng.
- JMS Client : Là các chương trình độc lập hoặc các components (thành phần) của ứng dụng, được viết bằng Java có khả năng trao đổi message.
- JMS producer/ publisher : là JMS client tạo và gửi tin nhắn.
- JMS consumer/ subscriber : là JMS client nhận tin nhắn.
- JMS Message : Là các object, định dạng trung gian chứa data để giao tiếp giữa JMS Client và Provider.
- Administered object : hỗ trợ cơ chế quản lý và cấu hình cho JMS Object. Bao gồm:
- ConnectionFactory Object: được sử dụng để tạo kết nối giữa ứng dụng Java và JMS Provider. Tương tự như khái niệm truy cập DataSource của kết nối dữ liệu.
- Destination Object: là nơi lưu trữ cho message, là đối tượng JMS được JMS Client sử dụng để chỉ định đích của tin nhắn mà nó đang gửi và nguồn tin nhắn mà nó nhận được. Có hai loại Destination: Queue and Topic.
- JMS Queue : Khu vực chứa các tin nhắn đã được gửi và đang chờ để đọc (chỉ bởi một consumer). Hàng đợi này đảm bảo các tin nhắn được nhận theo thứ tự gửi và mỗi tin nhắn chỉ được xử lý một lần.
- JMS Topic : Một cơ chế phân phối để publisher gửi tin nhắn đến nhiều người đăng ký (subscriber).
Cơ chế giao tiếp JMS
JMS cung cấp cơ chế giao tiếp bao gồm:
- Asynchronous: JMS tự động chuyển message đến người nhận khi message đến.
- Reliable: một message chỉ được chuyển đến đúng một người nhận mà không có cơ chế nhân bản, do vậy, tín hiệu phản hồi hoàn tất nhận message từ người nhận sẽ gây nên xóa bỏ thông tin trên middleware object.
Các mô hình JMS
JMS hỗ trợ 2 mô hình trao đổi dữ liệu là P2P (Point to Point) và Pub/Sub (Publisher/ Subscriber). Các mô hình trao đổi này gọi là JMS message domain.
P2P (Point to Point)
- Có ba thành phần chính là ứng dụng gửi (sender), Queue, ứng dụng nhận (receiver) tin.
- Sử dụng Queue làm nơi lưu trữ. Queue giữ lại các tin nhắn cho đến khi client nhận hoặc đến thời gian timout thiết lập.
- Định nghĩa 02 đối tượng cho việc gửi và nhận, đó là sender và receiver, và chỉ có một người gửi và một người nhận tin nhắn.
- Mô hình này message chuyển đi tuần tự (FIFO).
- Mô hình cho phép người nhận không cần active tại thời điểm gửi message.
- Sử dụng tín hiệu acknowledge để kích hoạt cho việc nhận message ở người nhận hoàn tất.
- Mô hình có tính bảo mật cao do một người gửi và một người nhận nhưng đôi lúc làm hệ thống bị block lại do chờ message đến.
Pub/ Sub (Publisher/ Subscriber)
- Cũng có ba thành phần chính là phía gửi (sender), Topic, và phía nhận (receiver).
- Mô hình sử dụng Topic làm nơi lưu trữ. Topic thực chất cũng là dạng queue nhưng có nhiều hơn một queue với các queue có đánh độ ưu tiên khác nhau.
- Mô hình cho phép 1 người gửi và nhiều người nhận do vậy đối tượng được định nghĩa là Publisher và Subcriber.
- Topic sẽ lưu lại toàn bộ tin nhắn mà không bị mất đi cho đến khi MOM được reset, hay xóa.
- Mỗi Subscriber sẽ chỉ nhận được message từ topic sau khi đã subscription.
- Không cần sử dụng thông tin acknowledge và message được chuyển đến các subscriber chỉ là bản copy.
- Mô hình bảo mật không cao do gửi nhiều người nhận nhưng được ưu điểm đó là áp dụng thuận lợi cho hệ thống phân tán.
- Mô hình Pub/Sub đòi hỏi đối tượng nhận phải active hay listener tại thời điểm gửi nhận message, nếu không message sẽ mất đi (non-durable). Do vậy, để message vẫn không mất đi nhưng được lưu trữ tạm thời trong MOM và cho phép người dùng truy cập vào MOM với tính xác thực thì chức năng durable phải được kích hoạt.
Cơ chế gửi nhận message trong JMS được chia thành hai thành phần:
- Synchronous: đối tượng nhận và gửi message thông qua thực hiện phương thức receive và phương thức này giữ ứng dụng chờ đợi cho đến khi message tới.
- Asynchronous: đối tượng nhận bắt buộc phải đăng ký cơ chế lắng nghe MessageListener để đón nhận message và phương thức được kích hoạt là onMessage để đón nhận và xử lý message.
Ưu điểm của JMS
- Reliability (Độ tin cậy) : Tin nhắn trung gian (Messaging middleware) đảm bảo tin nhắc được phân phối đến người nhận (receiver). Nếu người nhận ngừng hoạt động vì một số lý do, hệ thống nhắn tin sẽ lưu trữ tin nhắn cho đến khi nó hoạt động trở lại. Đảm bảo một message chỉ được gửi một lần, tránh trường hợp bị mất message hoặc trùng lặp.
- Asynchronous (Bất đồng bộ) : JMS Provider, client có thể gửi và nhận message không đồng bộ. Nghĩa là người gửi và người nhận không cần chờ nhau.
- Ease of Integration (dễ tích hợp) : Nhiều ứng dụng có thể được viết bằng các ngôn ngữ lập trình khác nhau hoặc chạy trên các máy chủ khác nhau. Miễn là chúng sử dụng cùng một giao thức, một phần mềm trung gian nhắn tin có thể được sử dụng để thiết lập liên lạc giữa chúng.
- Scalability (Khả năng mở rộng): Hệ thống nhắn tin giúp quảng bá tin nhắn đến nhiều receiver, giúp mở rộng.
- Flexibility (Tính linh hoạt) : có thể gán các giao thức khác nhau cho các tin nhắn khác nhau, cho phép ta linh hoạt trong việc thiết kế kiến trúc của mình.
- Loosely coupled (Kết nối lỏng lẻo) :
- JMS API là đặc tả kỹ thuật nên được triển khai bởi tất cả các JMS Provider. Vì vậy chúng ta có thể thay đổi Provider hiện tại sang Provider mới với ít thay đổi (có nghĩa là chỉ cấu hình) hoặc không thay đổi mã ứng dụng JMS.
- Tách biệt người gửi và người nhận, và người truyền tin trung gian sẽ lưu tin nhắn đến khi người nhận có thể xử lý.
- Interoperability (Khả năng tương tác) : JMS API cho phép khả năng tương tác giữa các ngôn ngữ nền tảng Java khác như Scala và Groovy.
Nhược điểm JMS
JMS sẽ không bao gồm các tính năng sau, bởi vì JMS chỉ là hệ thống gởi nhận tin:
- Load Balancing/Fault Tolerance
- Error/Advisory Notification
- Administration
- Security
- Wire Protocol
- Message Type Repository
Vì một vài hạn chế của JMS nên đa phần trong các hệ thống distributed sẽ không sử dụng JMS mà sẽ sử dụng các libs được implement dựa trên JMS như Kafka, Zookeeper… các bạn có thể tham khảo thêm. Tuy nhiên, việc nắm được các khái niệm cơ bản của JMS sẽ giúp chúng ta nắm bắt được các third party nhanh chóng hơn.
JMS vs Socket
Ưu điểm của JMS:
- Người gửi và người nhận không cần biết nhau.
- Có thể dễ dàng đăng ký và hủy đăng ký
- Hữu ích cho việc lưu trữ thông tin offline và cập nhật số lượng lớn. Vì vậy, người nhận có thể xử lý từng cái một.
- Người gửi / người nhận có thể làm việc bất đồng bộ.
Ưu điểm Socket:
- Socket cung cấp một kết nối trực tiếp.
- Độ trễ thấp, vì không có máy chủ ở giữa (không có MoM)
- Socket hoạt động ở lớp TCP để truyền dữ liệu ít hơn.
Trường hợp sử dụng JMS?
Một số trường hợp có thể sử dụng JMS:
- Mong muốn các thành phần không phụ thuộc vào thông tin về interface của các thành phần khác, vì vậy các thành phần có thể dễ dàng thay thế.
- Muốn ứng dụng chạy cho dù tất cả các thành phần có hoạt động hay không.
- Ứng dụng cho phép một thành phần gửi thông tin cho người khác và tiếp tục hoạt động mà không cần chờ nhận được phản hồi ngay lập tức.
>>> Xem thêm: Class trong Java là gì? Object trong Java là gì?
AMQP là gì?
AMQP (Advanced Message Queuing Protocol – Giao thức xếp hàng tin nhắn nâng cao) là một giao thức internet mở và được chuẩn hóa để cho phần mềm trung gian hướng thông báo (MOM) truyền message tin cậy giữa các ứng dụng hoặc tổ chức. Các tính năng xác định của AMQP là định hướng tin nhắn, xếp hàng, định tuyến (bao gồm cả P2P và Publisher/Subscriber), độ tin cậy và bảo mật.
AMQP giúp các developer xây dựng một hệ sinh thái tin nhắn đồng nhất, đa dạng, kết nối các hệ thống một cách tương tác và hợp tác.
AMQP thường được so sánh với JMS (Java Message Service), hệ thống nhắn tin phổ biến nhất trong cộng đồng Java. Một hạn chế của JMS là các API được chỉ định, nhưng định dạng thông báo thì không. AMQP là một giao thức, nó mô tả về định dạng của dữ liệu được gửi qua mạng dưới dạng luồng byte dữ liệu truyền được chỉ định. Đặc tính này cho phép các thư viện được viết bằng nhiều ngôn ngữ và chạy trên nhiều hệ điều hành và kiến trúc CPU, tạo nên một tiêu chuẩn nhắn tin đa nền tảng, có thể tương tác thực sự.
Một số điều quan trọng cần nhớ:
- AMQP là một giao thức nhắn tin, không triển khai JMS API.
- JMS là API và AMQP là một giao thức. Vì vậy, không có nghĩa gì khi nói rằng giao thức mặc định của JMS là gì, tất nhiên các ứng dụng client sử dụng HTTP/ HTTPS làm giao thức kết nối khi gọi Web Service.
- JMS chỉ là một đặc tả API. Nó không sử dụng bất kỳ giao thức nào. JMS Provider như ActiveMQ có thể đang sử dụng bất kỳ giao thức cơ bản nào để làm JMS Transport cho JMS API, chẳng hạn: AMQP, MQTT, OpenWire, REST (HTTP), RSS và Atom, Stomp, …
Trong bài này, chúng ta đã tìm hiểu các khái niệm quan trọng của JMS. Trong các bài viết tiếp theo, chúng ta sẽ cùng hiểu hiểu về cách cài đặt và sử dụng JMS thông qua một số JMS Provider như Active MQ, Rabbit MQ, …
Tài liệu tham khảo: