I'm looking for a scalable "at" replacement, with high availability. It must support adding and removing jobs at runtime.
Some background:
I have an application where I trigger millions of events, each event occurs just once. I don't need cron like mechanisms (first Sunday of the month, etc), simply date, time and context.
Currently I'm using the Quartz scheduler, and while it is a very good project, it has difficulties to handle the amount of events we throw at it, even after a lot of tweaking (sharding, increasing polling interval, etc.) due to the basic locking it performs on the underline database. Also, it is a bit overkill for us, as basically we have millions of one time triggers, and relatively small number of jobs.
I'd appreciate any suggestion
If I was facing the same scenario I would do the following...
Setup a JMS queue cluster (e.g RabbitMQ or ActiveMQ) using a queue replication setup over a few boxes.
Fire all the events at my nice highly-available JMS queue.
Then I would code an agent application that popped the events of the JMS queue as needed, I could run multiple agents on multiple boxes and have that combined with the correct JMS failover url etc.
You could also use the same sort of model if your jobs are firing the events...
Fyi, a nicer way of scheduling in core Java is as follows:
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(sensibleThreadCount);
threadPool.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//Pop events from event queue.
//Do some stuff with them.
}
}, initialDelay, period, TimeUnit.X);
Maybe just use JGroups shared tree with tasks sorted by execution time. Nodes will will take first task and schedule timer, which will execute at given time. On task remove timer can be canceled.
So basically you can use just JGroups and simple java Timers/Executors.
I didn't read it whole, but here is some proof of concept or maybe even solution
how about the java timer?
import java.util.*;
public class MyTask extends TimerTask{
public void run(){
System.out.println( "do it!" );
}
}
and then
Timer timer = new Timer();
MyTask job1 = new MyTask();
// once after 2 seconds
timer.schedule( job1, 2000 );
job1.cancel();
MyTask job2 = new MyTask();
// nach each 5 seconds after 1 second
timer.schedule ( job2, 1000, 5000 );
Related
Please take time to read below. Your help will be highly appreciated
I have a scenario where I need to monitor some realtime activity. Say for example a method is getting called in realtime within milli seconds. I have to monitor as if when the method was first called and when the method was called last.
So, after that method is hit last I need to wait for sometime say 10 seconds and see if it doesn't called again within that time. If its not called then I need to run some code.
I want to use ExecuterService and use newCachedThreadPool(). But I am confused on how to implement this.
If you are not sure what I am talking about, take some example of say when there is some network breakdown and u where receiving heartbeats and suddenly u stopped receiving it then you show some error message on screen for e.g. Connection not available. In my case its some third party application which is sending some message and its just one way communication. Like, my application sent some request and other application keep on sending responses. So, I need to monitor that response and somehow need to know when I received the last response.
My approach - I thought of executing a task each time that method is called which will wait for 10 seconds and within 10 seconds, if that method got called again, it will somehow cancel the current task and will create another task (or reuse if possible) which will again run for 10 seconds. This will keep on happening until the last message received (when the method got called last) and after that once 10 sec delay is over, the task will be executed and some code will run to show error message on the UI.
I have used Timer earlier, which solved this problem but created a performance issue as new Timer which a new TimerTask is instantiated every time a new message is received hence creating a hell lot of objects which garbage collector could not reclaim that fast, thus resulting in outOfMemorry Error and making Server non responsive. Obviously it was a bad code that's why I am here for help.
Please help me in giving some approach to solve this problem.
This is quite easy if you approach it with the most basic of tools--sometimes with simple problems the enhanced tools like thread pools just distract from a trivial solution.
Let's say you have a simple thread (Runnable). That thread checks a time stamp to see if that time stamp is 10 seconds old. If it is you notify your listener, if not you delay a few millis and check again.
Now all your method has to do is update the (volatile) time stamp to "now" every time it runs. There may be some other business rules to implement here but it should be a good foundation.
The only issue now is how you notify your listeners. If this happens rarely you can probably call them on the same thread you are checking the time with--but I think you ruled that out. If it happens more often but you don't want/need it to "nest" your notifications, you can have a second thread hanging around with no purpose except to notify the client when triggered by your watcher thread.
If you need to "nest" notifications (notify the listener before the original notification has returned) then you need a thread pool for your notifications to go out on.
Finally I suppose if you want to catch EVERY time your timer isn't called for 10 seconds but you don't want to nest, your timing thread could push "events" onto a threadsafe queue and your "Notification" thread could pull them off and send the events one at a time.
That should cover all the possibilities.
You may use ScheduledExecutorService.
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
java.util.concurrent.Executors.newCachedThreadPool :
Creates a thread pool that creates new threads as needed, but will
reuse previously constructed threads when they are available. These
pools will typically improve the performance of programs that execute
many short-lived asynchronous tasks. Calls to execute will reuse
previously constructed threads if available. If no existing thread is
available, a new thread will be created and added to the pool. Threads
that have not been used for sixty seconds are terminated and removed
from the cache. Thus, a pool that remains idle for long enough will
not consume any resources. Note that pools with similar properties but
different details (for example, timeout parameters) may be created
using ThreadPoolExecutor constructors
As you have many short-lived tasks, cached thread pool is best option.
Short example:
public class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s){
this.command=s;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName()+" Start. Command = "+command);
processCommand();
System.out.println(Thread.currentThread().getName()+" End.");
}
private void processCommand() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public String toString(){
return this.command;
}
}
To run WorkerThread use :
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
Runnable worker = new WorkerThread("threadName");
executor.execute(worker);
To stop WorkerThread use:
executor.shutdown();
I am reading about timers in Java SDK 1.3
It is mentioned as follows in POSA volume 2 in active object pattern
JDK 1.3 introduced a mechansim for executing timer-based tasks
concurrently in the classes java.util.Timer and java.util.TimerTask.
When ever the scheduled execution time of a task occurs it is
executed. The scheduling calls are executed in the clinets thread,
while the tasks themselves are executed in a thread owned by Timer
object. A timer internal task queue is protected by locks because the
two threads outlined above operate on it concurrently.
The task queue is implemented as a priority queue so that the next
TimerTask to expire can be identified efficiently. The timer thread
simply waits until this expiration.
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.format("Time's up!%n");
timer.cancel(); //Terminate the timer thread
}
}
public static void main(String args[]) {
new Reminder(5);
System.out.format("Task scheduled.%n");
}
}
My question is
Can we have multiple schedule functions with single timer? Request to give an example here and how it works. For example if we have two scheduled one task for every 5 seconds as shown above and another for every 12 seconds but I want to use same Reminder object instead of using another (i.e., creating) Reminder object. I want to know how internally it works like how timer stated like 5,5,2, 3, and so on . (as I have same kind of requirement in my project which I have to do in C++ with out using boost. I am planning to use single timer rather than multiple timers.
What is delay argument here and how it is used.
schedule(TimerTask task, long delay, long period)
Thanks for your time and help.
If you don't have to use SDK 1.3, you can use Java 5.0 which introduced the ScheduledExecutorService which makes Timers redundant IMHO.
The ScheduledExecutorService has been around more than 9 years, perhaps it is time to upgrade.
BTW 1.3 was end of lifed, before Sun officially had End of Life dates. It is ancient and unless you like history lessons, I suggest you live in the present. ;)
BTW Java 5.0 and Java 6 are both end of life and Java 7 will have its end of life date announced next year.
So I would look at Java 7 or 8 if I were you, and ignore anything which is more than a few years old because there are many practices which are either bad, or out dated on the Internet and they don't get updated.
If you like learning about bad or out of date practices, the rose india web site is the finest collection I have found. ;)
I am looking for a load balanced thread pool with no success so far. (Not sure whether load balancing is the correct wording).
Let me explain what I try to achieve.
Part 1:
I have Jobs, with 8 to 10 single tasks. On a 6 core CPU I let 8 thread work on this tasks in parallel which seems to deliver best peformance. Whe one task is ready, another one can start. Once all ten tasks are finished, the complete job is done. Usually a job is done in 30 to 60 seconds.
Part two:
Some times, unfortunately, the job takes more then two hours. This is correct due to amount of data that has to be calculated.
The bad thing is, that no other job can start while job1 is running (assuming, that all threads have the same duration) because it is using all threads.
My First idea:
Have 12 threads, allow up to three jobs in parallel.
BUT: that means, the cou is not fully untilized when there is only 1 job.
I am looking for a solution to have full CPU power for job one when there is no other job. But when an other job needs to be started while one other is running, I want the CPU power allocated to both job. And when a third or fourth job shows up, I want the cpu power alocated fairly to all four jobs.
I apreciate your answers...
thanks in advance
One possibility might be to use a standard ThreadPoolExecutor with a different kind of task queue
public class TaskRunner {
private static class PriorityRunnable implements Runnable,
Comparable<PriorityRunnable> {
private Runnable theRunnable;
private int priority = 0;
public PriorityRunnable(Runnable r, int priority) {
this.theRunnable = r;
this.priority = priority;
}
public int getPriority() {
return priority;
}
public void run() {
theRunnable.run();
}
public int compareTo(PriorityRunnable that) {
return this.priority - that.priority;
}
}
private BlockingQueue<Runnable> taskQueue = new PriorityBlockingQueue<Runnable>();
private ThreadPoolExecutor exec = new ThreadPoolExecutor(8, 8, 0L,
TimeUnit.MILLISECONDS, taskQueue);
public void runTasks(Runnable... tasks) {
int priority = 0;
Runnable nextTask = taskQueue.peek();
if(nextTask instanceof PriorityRunnable) {
priority = ((PriorityRunnable)nextTask).getPriority() + 1;
}
for(Runnable t : tasks) {
exec.execute(new PriorityRunnable(t, priority));
priority += 100;
}
}
}
The idea here is that when you have a new job you call
taskRunner.runTasks(jobTask1, jobTask2, jobTask3);
and it will queue up the tasks in such a way that they interleave nicely with any existing tasks in the queue (if any). Suppose you have one job queued, whose tasks have priority numbers j1t1=3, j1t2=103, and j1t3=203. In the absence of other jobs, these tasks will execute one after the other as quickly as possible. But if you submit another job with three tasks of its own, these will be assigned priority numbers j2t1=4, j2t2=104 and j2t3=204, meaning the queue now looks like
j1t1, j2t1, j1t2, j2t2, etc.
This is not perfect however, because if all threads are currently working (on tasks from job 1) then the first task of job 2 can't start until one of the job 1 tasks is complete (unless there's some external way for you to detect this and interrupt and re-queue some of job 1's tasks). The easiest way to make things more fair would be to break down the longer-running tasks into smaller segments and queue those as separate tasks - you need to get to a point where each individual job involves more tasks than there are threads in the pool, so that some of the tasks will always start off in the queue rather than being assigned directly to threads (if there are idle threads then exec.execute() passes the task straight to a thread without going through the queue at all).
The easiest thing to do is to oversubscribe your CPU, as Kanaga suggests, but start 8 threads each. There may be some overhead from the competition, but if you get to a single job situation, it will fully utilize the CPU. The OS will handle giving time to each thread.
Your "first idea" would also work. The idle threads wouldn't take resources from 8 working threads if they aren't actually executing a task. This wouldn't distribute the cpu resources as evenly when there are multiple jobs running, though.
Do you have a setup where you can test these different pipelines to see how they're performing for you?
I think since your machine is 6 core CPU. Better have 6 worker thread for each job-thread. So that when ever one thread got a new job, it starts up to six parallel workers to work on the single job. This will ensure consuming the full cpu power when there is only one job at a time.
Also please have a look at Fork and Join concept in java 7.
References_1 References_2References_3 References_4
Also learn about newcachedthreadpool()
Java newCachedThreadPool() versus newFixedThreadPool
I am looking for a good solution or probably an API to solve the following problem:
My application does a task in a loop, for example it sends e-mails etc. I need to limit the average rate of messages to for example 100 messages per second or 1000 messages per last minute ...
No I am looking for an algorithm or an API which does exactly this task.
You can use a ScheduledExecutorService to schedule tasks for a given period of time.
For example, to schedule 100 tasks per second you can say:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(nThreads);
scheduler.scheduleAtFixedRate(mailSender, 0, 10, TimeUnit.MILLISECONDS);
Obviously, you need to track how many tasks have executed and turn off the scheduler after the job is done.
Token bucket algorithm is very easy to implement and use yet very powerful. You can control the throughput at runtime and queue some requests to handle peeks.
The simplest way I can think of is to delay when to send each emails depending on how many are waiting.
final ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(1);
int ratePerSecond = ...
public static void execute(Runnable run) {
int delay = 1000 * service.getQueue().size() / ratePerSecond;
service.schedule(run, delay, TimeUnit.MILLISECONDS);
}
This will ensure that the tasks are performed only as close to together as the rate allows.
Guava has a RateLimiter class that does exactly that.
I'm looking for some guidance on how to manage multiple timer tasks. I'd like to be able to dynamically create timers and then when each timer is finished, it'll reset itself.
Example:
Timer 1
- perform action x
- reset to perform action x again in 30 minutes
Timer 2
- perform action y
- reset to perfom action y again in 10 minutes
What you want is the ScheduledExecutorService.
It allows you to schedule tasks to run at a given time or at a given rate.
The following code creates a timer and executes it every 1000 ms after an initial delay of 500 ms. You can easily define two or more timers this way.
TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println( "exec" );
}
};
new Timer().scheduleAtFixedRate( task, 500, 1000 );
Perhaps it could be worth reviewing Quartz Enterprise Job Scheduler
Quartz is a full-featured, open source job scheduling system that can be integrated with, or used along side virtually any J2EE or J2SE application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components or EJBs.