2010-07-23 32 views
9

Tôi có một ứng dụng sử dụng Trình lên lịch thạch anh để lên lịch công việc. Ứng dụng hiện đang chạy phiên bản Quartz 1.6.2. JobStore của tôi là org.quartz.impl.jdbcjobstore.JobStoreTX với một cơ sở dữ liệu Oracle sao lưu nó. Clustering được bật, nhưng chỉ có một bộ lập lịch sử dụng cơ sở dữ liệu. Thạch anh ThreadPool của tôi được cấu hình như sau:Tôi có thể chờ Công việc thạch anh đang chờ theo thứ tự được kích hoạt không?

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool 
org.quartz.threadPool.threadCount = 5 
org.quartz.threadPool.threadPriority = 5 

Việc của bạn là dài chạy, do đó, nó khá phổ biến để có 5 công việc chạy (tối đa cho phép bên hồ bơi thead của tôi) khi trigger bắn việc làm mới. Các công việc mới được kích hoạt đạn không nổ và tôi thấy đăng thông điệp như sau:

2011-05-20 04:09:30,097 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:29 05/20/2011 
2011-05-20 04:09:30,120 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011 
2011-05-20 04:09:30,125 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:30 05/20/2011 
2011-05-20 04:09:30,138 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011 
2011-05-20 04:11:29,998 INFO [QuartzScheduler_scheduler-servername-111305822376676_MisfireHandler] o.q.impl.jdbcjobstore.JobStoreTX - Handling 2 trigger(s) that missed their scheduled fire-time. 

Khi một công việc chạy kết thúc, một trong những việc làm misfired sẽ được nhấc lên và chạy bình thường. Tuy nhiên, Quartz dường như nhận một công việc không hài lòng một cách ngẫu nhiên, không liên quan đến thứ tự các công việc ban đầu được dự kiến ​​thực thi. Lý tưởng nhất, tôi muốn chúng được chọn theo thứ tự mà chúng được cho là đã chạy, dựa trên thời gian lửa ban đầu của chúng.

Có thể thực hiện các công việc chờ đợi (không hài lòng) của tôi được kích hoạt theo thứ tự đã được kích hoạt khi không gian trong Quartz ThreadPool có sẵn không?

Trả lời

2

Khi thạch anh xử lý một kích hoạt đã bỏ lỡ thời gian cháy, nó sẽ cập nhật nextFireTime của trình kích hoạt. Theo mặc định, trình kích hoạt sẽ bị coi là bị mất nếu nextFireTime vượt quá 60 giây trong quá khứ. Trình kích hoạt bị bỏ qua vẫn nên được chọn dựa trên nextFireTime và thứ tự ưu tiên nhưng tôi đoán nó có vẻ ngẫu nhiên vì một số trình kích hoạt đã được cập nhật và những trình kích hoạt khác không được kích hoạt.

Tôi khuyên bạn nên tăng thuộc tính org.quartz.jobStore.misfireThreshold. Xem http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigRAMJobStore.html (mặc dù thuộc tính giống hệt nhau cho tất cả các cửa hàng việc làm). Điều này sẽ làm cho việc kích hoạt lại các trình kích hoạt của bạn ít có khả năng hơn.

+0

Tôi thực sự không thể kiểm tra điều này vì tôi có một công việc mới, chưa sử dụng thạch anh trong nhiều năm và không thể bận tâm để thiết lập một dự án thử nghiệm để xem liệu công trình này có hoạt động hay không. Tuy nhiên, tôi rất ấn tượng rằng bạn đã lo lắng trả lời câu hỏi 5 năm cũ và câu trả lời của bạn có vẻ hữu ích, vì vậy tôi sẽ tiếp tục và đánh dấu câu trả lời này là đã được giải quyết :) –

+0

Tôi đã gặp sự cố tương tự tràn ngăn xếp. Cuối cùng tôi đào sâu mã và tìm ra bản thân mình nhưng nghĩ rằng tôi sẽ để điều này ở đây trong trường hợp bất cứ ai khác đang tìm kiếm câu trả lời trong tương lai. – samblake

+0

@JonQuarfoth Điều gì làm việc cho bạn cuối cùng? Tôi đang lên kế hoạch 10s của hàng nghìn công việc và công việc sẽ chạy dài vì tôi cần di chuyển blob từ vị trí này sang vị trí khác và các đốm màu đó có thể lớn đến 100GB. Tôi đang lên kế hoạch sử dụng Quartz clustering để khi master lên lịch công việc, nô lệ sẽ tiếp tục làm việc trên những công việc đó và tôi không thực sự quan tâm đến việc bỏ lỡ lửa vì tôi chỉ quan tâm đến công việc được chọn bởi một trong những nô lệ cuối cùng . Có lẽ tôi có thể thiết lập một giá trị ngưỡng misfire ridiculously lớn. Xin vui lòng cho tôi biết những gì các bạn nghĩ về nó. Cảm ơn. – Coder

0

Nhìn vào thạch anh thread pool, nó sử dụng vòng lặp chờ()/notify(), không công bằng và sẽ chọn ngẫu nhiên một chuỗi mới khi nhiều chuỗi đang chờ.

Bạn có thể sử dụng phiên bản ThreadPool của riêng bạn công bằng. Sao chép mã từ SimpleThreadPool, nhưng thay thế khóa xung quanh nextRunnableLock bằng một java.util.ReentrantLock, chuyển sự thật cho hàm tạo công bằng. Trong SimpleThreadPool đã sửa đổi của bạn, sử dụng ReentrantLock.lock()/unlock() thay vì đồng bộ, và sử dụng ReentrantLock.newCondition(). Signal()/await() thay vì chờ/thông báo, và nó có thể giải quyết vấn đề của bạn.

+0

Những chủ đề trong hồ bơi không có công việc được giao cho họ, do đó, sự công bằng bạn đang nói về không quan trọng. Cho dù chủ đề nào đến miễn phí đầu tiên, sẽ chạy công việc tiếp theo. – jhouse

+0

Tôi nghĩ rằng sự công bằng đến từ các chủ đề bên ngoài hồ bơi thread, runInThread và blockForAvailableThreads cả hai chờ đợi không công bằng. Ý của bạn là gì khi bạn nói, "khi hồ bơi của tôi được phóng to" – sbridges

+0

runInThread() và blockForAvailableThreads() đều được gọi từ cùng một luồng - không có nhiều luồng chờ kết quả của các phương thức đó, vì vậy 'công bằng' của wait()/notify() không quan trọng. (Chỉ một dịch vụ luồng/sử dụng nhóm luồng). – jhouse

2

Tôi nghe có vẻ như bạn đang gặp phải tình huống không hài lòng (kịch bản có nhiều công việc sẵn sàng thực hiện hơn là có chuỗi công nhân). Đặt lệnh misfire và/hoặc thuộc tính ưu tiên trên trình kích hoạt để thay đổi cách hoạt động của từng ứng dụng sau khi đã qua quá trình kích hoạt.

Ngoài ra, bạn có thể xem xét tăng ngưỡng không mong muốn, điều này sẽ thay đổi khoảng thời gian mà trình kích hoạt có thể "trễ" chờ đợi một chuỗi được thực thi trước khi nó được coi là không phù hợp (và có hướng dẫn không phù hợp)).

Có thể thực hiện các công việc chờ đợi (không hài lòng) của tôi được kích hoạt theo thứ tự đã được kích hoạt khi không gian trong Quartz ThreadPool có sẵn không?

Hướng dẫn "không làm gì" sẽ để nguyên thời gian hoạt động.

+0

Đó chắc chắn là một kịch bản không phù hợp - Tôi đã cập nhật câu hỏi để cụ thể hơn một chút vào thời điểm đó. Có một hướng dẫn không phù hợp nào có thể khiến các công việc không hài lòng nhận được theo thứ tự mà ban đầu họ bị sa thải không? –

+3

Các javadoc cho MISFIRE_INSTRUCTION_DO_NOTHING misfire đọc như sau: "Hướng dẫn các Scheduler rằng khi một tình huống cháy, CronTrigger muốn có thời gian tiếp theo lửa-cập nhật đến thời gian tiếp theo trong lịch trình sau thời gian hiện tại, nhưng nó không không muốn bị sa thải ngay bây giờ. " Có lẽ tôi hiểu lầm, nhưng điều đó nghe với tôi như công việc sẽ chỉ bỏ qua bắn và không làm gì cho đến khi nó được kích hoạt. Đây không phải là điều tôi muốn. Tôi muốn công việc để chạy ngay sau khi có các chủ đề có sẵn, nhưng với các công việc chờ đợi lâu nhất chạy đầu tiên nếu có nhiều công việc không hài lòng. –

0

Trong trường hợp CronTrigger, phương pháp updateAfterMisfire() có thể lập lịch lại công việc tại new Date() trường hợp MISFIRE_INSTRUCTION_FIRE_ONCE_NOW chính sách.

Nếu một số tác vụ bị lỗi, một vài tác vụ có thể được lên lịch lại cùng một lúc (cùng một phần nghìn giây), vì máy tính chạy nhanh.

Kết quả là, và nếu không được xác định ưu tiên, trình lên lịch sẽ nhận nhiệm vụ tiếp theo đầu tiên, tất cả cùng với NextFireTime, theo tên khóa hoặc đầy đủ.

updateAfterMisfire() phương pháp nên có lịch lại nhiệm vụ cho một date duy nhất bằng cách sử dụng một Thread.sleep(25), làm ví dụ.

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