2008-09-07 4 views
8

Trong podcast # 15, Jeff đã đề cập đến việc anh ta chạy một sự kiện thường xuyên ở chế độ nền như thể nó là một chức năng bình thường - không may là tôi không thể tìm thấy thông qua twitter . Bây giờ tôi cần phải làm một điều tương tự và sẽ ném câu hỏi cho công chúng.Chạy một sự kiện nền thông thường trong ứng dụng web Java

Kế hoạch hiện tại của tôi là khi người dùng đầu tiên (có thể là tôi) vào trang web bắt đầu chuỗi nền cho đến khi thời gian được phân bổ (hàng giờ trên giờ) và sau đó khởi động sự kiện chặn những người khác (Tôi là Windows lập trình bởi thương mại vì vậy tôi nghĩ về các sự kiện và WaitOnMultipleObjects) cho đến khi nó hoàn thành.

Jeff đã làm như thế nào trong Asp.Net và phương pháp của anh có thể áp dụng cho thế giới ứng dụng web Java không?

Trả lời

12

Tôi nghĩ rằng việc phát triển một giải pháp tùy chỉnh để chạy các nhiệm vụ nền không phải lúc nào cũng có giá trị, vì vậy tôi khuyên bạn nên sử dụng Quartz Scheduler trong Java.

Trong trường hợp của bạn (cần chạy các tác vụ nền trong ứng dụng web), bạn có thể sử dụng ServletContextListener có trong bản phân phối cho initialize the engine at the startup of your web container.

Sau đó bạn có một số khả năng để bắt đầu (kích hoạt) các tác vụ nền của bạn (công việc), ví dụ: bạn có thể sử dụng biểu thức lịch hoặc dạng cron. Trong tình huống của bạn, có lẽ bạn nên giải quyết với SimpleTrigger cho phép bạn chạy các công việc theo các khoảng thời gian cố định.

Các công việc có thể được mô tả dễ dàng trong Quartz, tuy nhiên bạn chưa cung cấp bất kỳ chi tiết nào về những gì bạn cần để chạy, vì vậy tôi không thể đưa ra gợi ý trong khu vực đó.

3

Cơ chế của Jeff là tạo một loại đối tượng được lưu trong bộ nhớ cache mà ASP.Net sẽ tự động tạo lại ở một số khoảng thời gian - Nó có vẻ là một giải pháp cụ thể ASP.Net, vì vậy có thể sẽ không giúp bạn (hoặc tôi) nhiều trong thế giới Java.

Xem https://stackoverflow.fogbugz.com/default.asp?W13117

Atwood: Vâng, tôi ban đầu được hỏi trên Twitter, bởi vì tôi chỉ muốn một cái gì đó trọng lượng nhẹ. Tôi thực sự không muốn viết một dịch vụ cửa sổ. Tôi cảm thấy như vậy là ngoài mã ban nhạc. Cộng với mã thực sự làm công việc là một trang web trên thực tế, bởi vì với tôi đó là một đơn vị hợp lý của công việc trên một trang web là một trang web. Vì vậy, nó thực sự giống như chúng tôi đang gọi lại vào trang web, nó giống như một yêu cầu khác trên trang web, vì vậy tôi đã xem nó như một thứ gì đó phải ở nội tuyến và cách tiếp cận nhỏ mà chúng tôi đưa ra đã được đề xuất cho tôi trên Twitter về cơ bản để thêm một cái gì đó vào bộ nhớ cache của ứng dụng với thời gian hết hạn cố định, sau đó bạn có một cuộc gọi trở lại để khi hết hạn nó gọi một chức năng nào đó thực hiện công việc, sau đó bạn thêm nó vào bộ đệm với cùng thời hạn. Vì vậy, nó là một chút, có thể "ghetto" là từ đúng.

Cách tiếp cận của tôi luôn là OS (tức là Cron hoặc Windows task scheduler) tải URL cụ thể tại một khoảng thời gian nào đó, sau đó thiết lập trang tại URL đó để kiểm tra hàng đợi và thực hiện bất kỳ tác vụ nào cần thiết, nhưng tôi muốn được nghe nếu có cách nào tốt hơn.

Từ bảng điểm, có vẻ như FogBugz cũng sử dụng dịch vụ cửa sổ để tải phương pháp tiếp cận URL.

Spolsky: Vì vậy, chúng tôi có trang đặc biệt này được gọi là heartbeat.asp. Và trang đó, bất cứ khi nào bạn đánh nó, và ai cũng có thể đánh nó bất cứ lúc nào: không đau. Nhưng khi trang đó chạy nó kiểm tra một hàng đợi các nhiệm vụ chờ đợi để xem có điều gì cần được thực hiện hay không. Và nếu có bất cứ điều gì cần được thực hiện, thì có một thứ và sau đó lại nhìn vào hàng đợi đó và nếu có bất cứ điều gì khác được thực hiện, nó trả về dấu cộng và toàn bộ trang web mà nó trả lại chỉ là một ký tự đơn với dấu cộng trong đó. Và nếu không có gì khác để được thực hiện, hàng đợi bây giờ là trống rỗng, nó trả về một dấu trừ. Vì vậy, bất cứ ai có thể gọi nó và nhấn nó nhiều lần, bạn có thể tải lên heartbeat.asp trong trình duyệt web của bạn, bạn nhấn Ctrl-R Ctrl-R Ctrl-R Ctrl-R cho đến khi bạn bắt đầu nhận được minuses thay vì cộng. Và khi bạn đã làm điều đó FogBugz sẽ hoàn thành tất cả công việc bảo trì của nó mà nó cần phải làm. Vì vậy, đó là phần đầu tiên, và phần thứ hai là một dịch vụ Windows rất đơn giản chạy, và toàn bộ công việc của nó là gọi heartbeat.asp và nếu nó được cộng, gọi lại sớm, và nếu nó nhận được một cuộc gọi trừ nó một lần nữa, nhưng không phải trong một thời gian. Vì vậy, về cơ bản có dịch vụ Windows này luôn chạy, có nhiệm vụ rất, rất, rất đơn giản chỉ cần nhấn một URL và tìm xem liệu nó có cộng hoặc trừ và sau đó lập lịch khi nó chạy lại dựa trên việc liệu nó có dấu cộng hoặc trừ.Và rõ ràng bạn có thể thực hiện bất kỳ loại biến thể nào bạn muốn trên chủ đề này, ví dụ: bạn có thể thực sự thay vì chỉ trả lại dấu cộng hoặc trừ, bạn có thể nói "Được gọi lại sau 60 giây" hoặc "Gọi lại cho tôi ngay Tôi có nhiều việc phải làm hơn. " Và đó là cách nó hoạt động ... để dịch vụ bảo trì nó chạy, bạn biết đấy, bạn biết đấy, một nửa trang mã chạy dịch vụ bảo trì đó, và nó không bao giờ phải thay đổi, và nó không có bất kỳ của logic trong đó, nó chỉ chứa các tickling gây ra các trang web để có được gọi với một tần số đảm bảo nhất định. Và bên trong trang web đó tại heartbeat.asp có mã duy trì hàng đợi công việc cần được thực hiện và xem thời gian đã trôi qua và bạn biết đấy, bảo trì đêm khuya và cứ sau bảy ngày xóa tất cả các thư cũ hơn đã được đánh dấu là spam và tất cả các loại công việc duy trì nền. Và uh, đó là cách thực hiện điều đó.

5

Như đã đề cập, Quartz là một giải pháp tiêu chuẩn. Nếu bạn không quan tâm đến việc phân cụm hoặc sự bền bỉ của các tác vụ nền trong quá trình khởi động lại, bạn có thể sử dụng hỗ trợ ThreadPool tích hợp (trong Java 5,6). Nếu bạn sử dụng ScheduledExecutorService, bạn có thể đặt Runnables vào nhóm chủ đề nền chờ một khoảng thời gian cụ thể trước khi thực thi.

Nếu bạn quan tâm đến phân cụm và/hoặc sự kiên trì, bạn có thể sử dụng hàng đợi JMS để thực thi không đồng bộ, mặc dù bạn vẫn cần một số cách trì hoãn các tác vụ nền (bạn có thể sử dụng Quartz hoặc ScheduledExecutorService để thực hiện việc này).

2

Chúng tôi sử dụng jtcron cho các tác vụ nền đã lên lịch của chúng tôi. Nó hoạt động tốt, và nếu bạn hiểu cron nó sẽ có ý nghĩa với bạn.