Thiết kế ứng dụng thư báo với hàng đợi tạm thời

Hầu hết các đích JMS (hàng đợi và chủ đề) đều được tạo một cách hành chính và được coi như là tài nguyên tĩnh ngay cả khi các đích động (hàng đợi và chủ đề tạm thời) có hỗ trợ trong JMS. Sử dụng hàng đợi tĩnh để liên lạc giữa các tầng trong ứng dụng client/server sẽ tạo trở ngại cho tính linh hoạt và khả năng bảo trì ứng dụng. Trong bài này, chúng ta sẽ xem xét các mặt lợi ích cũng như hạn chế khi sử dụng đích tạm thời trên một hệ thống “kiểm tra sức khoẻ” doanh nghiệp. Chúng ta cũng sẽ xem xét khả năng thiết kế sử dụng hàng đợi tạm thời như một lựa chọn thay thế cho hàng đợi tĩnh và khảo sát một số chiến lược thiết kế khác, dùng đồng bộ cả yêu cầu và đáp ứng.

Tổng quan

Các đích tạm thời hay hàng đợi tạm thời, chủ đề tạm thời được xây dựng với vai trò như một lựa chọn nhẹ nhàng trong một kiến trúc hệ thống linh hoạt, có thể được dùng như là đích duy nhất cho các trả lời. Các đích này được giới hạn phạm vi với kết nối tạo ra nó, và được loại bỏ trên server ngay khi kết nối đóng lại. Chỉ có một hàng đợi đơn được yêu cầu cho nhà sản xuất hoặc người gửi để kết nối với người tiêu dùng sử dụng đích tạm thời. Trường JMS header (JMSReplyTo) luôn được dùng chung với các đích tạm thời.

Từ khi nhân dạng của đích tạm thời chỉ được biết trong kết nối hay phiên tạo ra nó, người dùng hay người nhận không thể biết tên đích. Giải pháp là nhà sản xuất hay người gửi phải gửi tên đích tạm thời đó với vai trò như một trường header (JMSReplyTo), một phần của tin báo, gửi tới một hàng tĩnh đã biết từ phía nhà sản xuất hay người gửi.

Giới hạn của đích tạm thời

  • Một đích tạm thời chỉ có thể được sử dụng bởi kết nối tạo ra nó.
  • Vòng đời của đích tạm thời chỉ trong thời gian kết nối được tạo.
  • Khi bạn đóng kết nối có đích tạm thời, đích cũng bị đóng và nội dung bên trong nó bị mất.
  • Bạn không thể có các kịch bản con lâu dài trong TemporaryTopic.
  • Mỗi đích tạm thời đều là duy nhất và không thể sao chép.
  • Các đích tạm thời không thể được định tuyến bằng dịch vụ tin báo doanh nghiệp.

Đích tĩnh và đích động

Về mặt chức năng, đích tĩnh và đích động có một số thuộc tính tương phản:

Đích tĩnh:

  • Được tạo một cách hành chính từ bên ngoài ứng dụng như là một phần của quá trình triển khai ban đầu.
  • Có một số nhân dạng nổi tiếng (được phân giải bởi JNDI) cho cả người tiêu dùng và nhà sản xuất.
  • Có thể hỗ trợ xử lý đồng thời bằng cách cấu hình đa phiên.
  • Có xu hướng cho truyền tải thư không đồng bộ.
  • Định thời hạn thư và cấp phát tài nguyên được mô tả như là một phần quá trình tạo hành chính các đích (không được định nghĩa bởi JMS).

Đích động:

  • Được tạo không cố định bởi bản thân ứng dụng.
  • Được tạo bởi người dùng và bị huỷ ngay sau khi phiên kết thúc.
  • Nhân dạng đích phải được chuyển theo một số cách thức tới nhà sản xuất.
  • Được sử dụng chủ yếu cho các thư đồng bộ (mô hình một yêu cầu/một trả lời), nhưng không giới hạn số lượng thư một đích tạm thời có thể giữ.
  • Độ dài thực của thời gian một thư được giữ trong hàng đợi và hậu quả tràn tài nguyên không được định nghĩa bởi JMS.

Một trường hợp nghiên cứu

Mặc dù có nhiều điểm hạn chế, nhưng các đích tạm thời cũng có nhiều nâng cao đáng kể trong sử dụng ứng dụng thời gian thực. Ở phần này, chúng ta sẽ kiểm tra một ứng dụng thư điển hình sử dụng JMS.

Một hệ thống kiểm tra sức khoẻ doanh nghiệp update thông tin khách hàng (như thêm hay xoá một thành viên) từ đa giao diện (các nhà cung cấp hay các nhóm kiểm tra khác nhau). Các trả lời cho yêu cầu update này phải được gửi đồng bộ để đảm bảo tính hợp lệ doanh nghiệp thích hợp hay tính năng bảo mật giao dịch khác được duy trì. Điều này đòi hỏi ứng dụng phải hỗ trợ đa client, tức đa khách hàng, mà có thể tại một thời điểm gửi đi hàng nghìn thư yêu cầu và mỗi client đều chờ trả lời cho từng thư.

Có hai cách để thiết kế giải pháp:

1. Sử dụng hàng đợi tĩnh cho cả yêu cầu và trả lời.

2. Sử dụng kết hợp cả hàng đợi tĩnh và hàng đợi động.

Ở phương thức đầu tiên, nếu bạn có một hàng đợi tĩnh cho các yêu cầu và một hàng đợi tĩnh khác cho các đáp ứng gửi tới nhiều client, bạn có thể uỷ thác cho một số logic lựa chọn dùng các bộ chọn thư Message Selector (JMS Specification section 3.8.1.1) để lọc thư từ cùng một hàng đợi tĩnh, như minh hoạ trong hình 1.


Hình 1
. Hàng đợi tĩnh đơn cho mô hình đa client.

Phương thức này khá tốn thời gian và có thể không được chấp nhận nếu yêu cầu đáp ứng khắt khe. Sử dụng cặp hàng đợi yêu cầu/đáp ứng riêng cho từng client có thể là ý tưởng tốt hơn nhưng cũng đòi hỏi phải tạo và duy trì đa hàng đợi tĩnh như mô tả trong hình 2.


Hình 2
. Mô hình cặp hàng đợi tĩnh trên từng client

Ở phương thức thứ hai, sẽ có một hàng đợi tĩnh đơn cho tất cả yêu cầu từ phía client. Mỗi client khởi đầu sẽ tạo một hàng đợi tạm thời để nhận các đáp ứng (TQa, TQb, TQc). Client gửi tên của hàng đợi tạm thời đó như là một phần trong các yêu cầu tới hàng đợi tĩnh, như mô tả trong hình 3.


Hình 3
. Mô hình hàng đợi tạm thời cho đa client.

Trong cấu hình này, các đích tạm thời có thể được xem tương tự như lời gọi lại trong xử lý đồng bộ, ví dụ như khi đối tượng được gọi muốn tiếp cận với đối tượng gọi theo cách tách riêng, không đòi hỏi chúng phải biết nhau.

Kiểu kiến trúc được đề nghị cho Server Side dùng hàng đợi tạm thời

Trong ví dụ này chúng ta sẽ xem xét việc sử dụng một Message-driven bean (hay MDB) như một trình nghe thư, và một session facade phối hợp với một hay nhiều đối tượng giao dịch (các session bean trạng thái hoặc phi trạng thái) nhằm tạo thư đáp ứng và gửi thư ra ngoài đường biên (trả lời) tới đích tạm thời như ở hình minh hoạ 4.


Hình 4
. Sơ đồ lớp mô hình thiết kế được đề nghị.

Khởi đầu MDB sẽ tự đăng ký với đích tĩnh thông qua một hoạt động quản trị. Trước khi nhận thư, MDB sẽ gửi thư đó tới session façade để lựa chọn nhân dạng đích tạm thời từ giá trị JMSReplyTo trong phần header của thư. Sau đó, nó tương tác với các đối tượng giao dịch khác để thực hiện luồng công việc được yêu cầu, như minh hoạ ở hình 5. MDB sẽ dùng OutboundProcessor (session bean trạng thái và phi trạng thái) để gửi thư tới đích tạm thời.


Hình 5
. Sơ đồ nối tiếp mô hình thiết kế được đề nghị.

Một số điều phải cần lưu ý về phía Client khi dùng hàng đợi tạm thời

Phiên giao dịch cần được đóng ngay sau khi quá trình xử lý hoàn tất, để hàng đợi tạm thời (Temporary Queue) sẽ được xoá ở phía server. Khi phiên JMS không hỗ trợ đồng thời, hoạt động có thể được triển khai với các đối tượng kết nối. Một phiên giao dịch và một ngữ cảnh đơn luồng để cung cấp và sử dụng các thư tạm thời. Theo mô tả của JMS:

Một phiên hỗ trợ các giao dịch và thật khó để triển khai các giao dịch đa luồng; một phiên không nên được sử dụng đồng thời bởi nhiều luồng.

Cho dù bạn không dùng phiên giao dịch, bạn vẫn được yêu cầu phối hợp các phiên đơn để triển khai quá trình xử lý đồng thời. Chỉ có một phương thức duy nhất có thể được gọi đồng thời là close(). Các luồng là ứng cử viên tốt cho lời gọi huỷ bỏ kể từ khi chúng có thể thực thi đồng thời.

Bạn không cần phải kết thúc giao dịch với khách hàng (QueueReceiver) sau một phiên đóng. Ngay sau khi kết nối được tạo, hàng đợi tạm thời được đóng, tất cả thành phần của kết nối và phiên đều được đóng. Dựa trên tập hợp dữ liệu vô nghĩa hoặc không thích hợp để tái chế các tài nguyên này có thể không đủ thời gian, nhất là trong trường hợp tài nguyên JMS được tạo bên ngoài JVM.

Mã nguồn ví dụ

Đoạn mã dưới đây sẽ cho các bạn biết cách tạo các đích tạm thời (Temporary Destination) như thế nào. Chúng tôi sử dụng một số giao diện phổ biến như Session, tương phản với cấu trúc miền đặc trưng của QueueSession hay TopicSession. Sun khuyến khích sử dụng các giao diện phổ biến không lập trình tới một miền thư đơn để ứng dụng JMS độc lập với miền.

<font color=
"blue">/** Get the Initial Context Factory */</font>

Hashtable env = new Hashtable();
String conFactoryClass = "VendorSpecificCFC";
String url = "MyServer:port";
env.put(Context.INITIAL_CONTEXT_FACTORY, conFactoryClass);
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_PRINCIPAL, "userid" );
env.put(Context.SECURITY_CREDENTIALS, "password");
Context = new InitialContext(env);

<font color=
"blue">/**Access the resources by looking up the JNDI
context*/
/**QueueConnectionFactory is a Factory for QueueConnection
Object*/</font>

javax.jms.ConnectionFactory qcf =
(QueueConnectionFactory)context.lookup("queueConFactoryName");
javax.jms.Connection qConnection =
(QueueConnection)qcf.createConnection("userid", "password");
javax.jms.Queue myQueue =
(javax.jms.Queue)context.lookup("MyQueue");
javax.jms.Topic myTopic =
(javax.jms.Topic)context.lookup("MyTopic");

<font color="blue">/**TopicConnectionFactory is a Factory for
TopicConnection Object*/</font>

javax.jms.ConnectionFactory tcf =
(TopicConnectionFactory)context.lookup("topicConFactoryName");
javax.jms.TopicConnection tConnection =
(TopicConnection)tcf.createConnection("userid", "password");

<font color="blue">/**Create a Session using Connection
Object*/</font>

javax.jms.Session qSession =
qConnection.createSession(false,Session.AUTO_ACKNOWLEDGE);
javax.jms.Session tSession =
tConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);

<font color=
"blue">/**Create the Temporary Destinations using the Session
Object*/</font>

javax.jms.Queue replyQueue = qSession.createTemporaryQueue();
javax.jms.Topic replyTopic = tSession.createTemporaryTopic();

Kết luận

Các đích tạm thời là công cụ hữu ích trong cấu trúc hướng thư báo. Chúng có một điểm khác biệt là nhẹ nhàng hơn và cho phép các ứng dụng co giãn hiệu quả vì bạn có thể mở rộng dễ dàng số liệu tại thời gian chạy. Các đích tĩnh phải được tạo nâng cao và mặc dù hữu ích ở nhiều phương diện nhưng bạn không nên sử dụng tính linh hoạt của nó. Vì lý do đó mà đích tạm thời thường được yêu thích hơn đích tĩnh mặc dù nhiều hoạt động mở rộng đòi hỏi phải thiết lập truyền thông giữa cả người gửi và người nhận.

Thứ Sáu, 04/05/2007 15:43
31 👨 326
0 Bình luận
Sắp xếp theo
    ❖ Tổng hợp