2013-08-26 35 views
7

Chúng ta cần triển khai một cơ chế tắt máy duyên dáng vào ứng dụng Servlet của chúng ta.Cách xử lý các yêu cầu servlet trong quá trình tắt máy dài

EDIT: Chúng tôi muốn làm cho nó đơn giản nhất có thể, mà sẽ được xử lý một tín hiệu giết được gửi qua chức năng của hệ điều hành. Điều này sẽ cho phép các quản trị viên hệ thống sử dụng các tiện ích shell (kill hoặc taskkill trên Windows), nếu không họ sẽ phải cài đặt một tiện ích khác chỉ để "nói chuyện" với máy chủ.

Cơ chế này vận hành theo hai giai đoạn:

  1. theo yêu cầu tắt máy, từ chối hoạt động quan trọng nhất định
  2. khối cho đến khi hành động quan trọng được khởi xướng trước đó được hoàn thành; có thể mất vài giờ

Giai đoạn số 1 được triển khai trong lớp DAO của chúng tôi. Giai đoạn # 2 được triển khai trong phương thức ServletContextListener # contextDestroyed của chúng tôi

Vấn đề của chúng tôi là khi contextDestroyed được gọi là vùng chứa Servlet ngừng phục vụ các yêu cầu HTTP tiếp theo.

EDIT: contextDestroyed được gọi khi ai đó đang gọi chức năng giết của hệ điều hành trên quy trình của máy chủ.

Chúng tôi muốn cho phép ứng dụng hoạt động trong Giai đoạn 2, thông báo cho người dùng rằng một số hoạt động không khả dụng.

+0

Câu hỏi hay. Nếu các hoạt động bị từ chối được thực hiện trong các servlet cụ thể, bạn luôn có thể thực hiện (và chỉ những) này trả về một trạng thái trong phạm vi 4xx nếu một tra cứu DB cho thấy tắt máy đang diễn ra? –

+0

Một số hoạt động được khởi xướng bởi các hành động giao diện người dùng và một số hoạt động được khởi tạo bởi một người lên lịch - đó là lý do tại sao tôi đang nghĩ đến việc kiểm soát chúng ở lớp DAO. –

Trả lời

4

Sử dụng filter để giữ danh sách tất cả các yêu cầu quan trọng.

Khi nhận được yêu cầu "chuẩn bị tắt máy", bộ lọc sẽ bắt đầu từ chối một số yêu cầu.

Viết một servlet cho bạn biết số lượng công việc quan trọng vẫn còn trong hàng đợi.

Trong công cụ tắt máy, hãy gửi "chuẩn bị tắt máy". Cuộc thăm dò servlet cho số lượng công việc quan trọng. Khi điều này đạt đến 0, hãy gửi lệnh tắt máy thực sự.

Để thực hiện điều này, hãy tạo một dịch vụ trong lớp nghiệp vụ phối hợp này. Lưu ý rằng mọi thứ phải xảy ra trước khicontextDestroyed() đang được gọi! Việc tắt ứng dụng đặc biệt của bạn không phù hợp với quan điểm J2EE của thế giới, vì vậy bạn phải tự quản lý nó.

Dịch vụ sẽ có thể thông báo cho các bên quan tâm khi tắt máy, có bao nhiêu công việc quan trọng vẫn đang chạy, vv Sau đó, Servlets và bộ lọc có thể sử dụng dịch vụ này để từ chối yêu cầu hoặc cho biết số lượng công việc còn lại.

Khi tất cả các công việc được thực hiện, từ chối tất cả các yêu cầu ngoại trừ quyền truy cập vào servlet "shutdown info", sau đó sẽ thông báo rằng ứng dụng đã sẵn sàng cho cái chết.

Viết công cụ cung cấp cho quản trị viên giao diện người dùng tốt để bắt đầu tắt ứng dụng của bạn.

[EDIT] Bạn có thể cảm thấy bị cám dỗ để ngăn hệ điều hành tắt ứng dụng của bạn. Đừng làm vậy.

Những gì bạn cần làm là viết một công cụ đặc biệt để tắt ứng dụng của bạn bằng cách sử dụng quy trình hai giai đoạn mà tôi đã mô tả ở trên. Đây sẽ là cách tiêu chuẩn để tắt máy.

Có, quản trị viên sẽ khiếu nại về điều đó. Trên Unix, bạn có thể ẩn công cụ này bằng cách đặt nó vào tập lệnh init, vì vậy sẽ không có ai chú ý. Có thể có một giải pháp tương tự trên Windows.

Giết máy chủ luôn có thể dừng nó trong trường hợp (un) các trường hợp như: lỗi trong mã tắt máy, tắt máy trong trường hợp mất điện, lỗi trong mã ứng dụng hoặc khi Murphy xảy ra.

+0

Một số hoạt động được bắt đầu bằng các hành động giao diện người dùng và một số hoạt động được khởi tạo bởi một người lập lịch biểu. Bộ lọc sẽ không hoạt động với các tác vụ được trình lên lịch khởi xướng. –

+0

Bộ lọc sẽ cần giữ danh sách/hàng đợi ở vị trí toàn cục (biến tĩnh hoặc mục nhập trong phạm vi ứng dụng). Điều đó làm cho nó có thể thực hiện nó theo cách mà bộ lập lịch có thể nhìn thấy nó. Nếu mọi thứ khác không thành công, hãy sử dụng khung DI. –

+0

Điều đó sẽ làm cho lớp logic kinh doanh "biết" về lớp trình bày, phải không? –

Các vấn đề liên quan