@Schedule creation is performed only once in a clustered environment

I have two instance instances grouped.

Each has a method annotated as

@Schedule(dayOfWeek = "*") public void runMeDaily() {...} 

I would like to run this method only once a day. Not twice a day (one on each copy)

Could I use the flag described here Run the @Scheduled task in only one WebLogic node cluster? or just pick a node, but I wonder if there’s a more elegant way to do this.

This question is somewhat related to EJB3.1 @ Schedule in a clustered environment , but I do not use JBOSS. (and he did not answer)

+5
source share
3 answers

I could only solve this using a solution other than Java EE specific to the platform (patented). In my case, I use TomEE + and Quartz. Starting quartz in cluster mode (org.quartz.jobStore.isClustered = true) and saving timers in the same database forces Quartz to select an instance to start the timer, so it will be launched only once.

This link was very useful - http://rmannibucau.wordpress.com/2012/08/22/tomee-quartz-configuration-for-scheduled-methods/

The shame of Java EE does not indicate this behavior. (still hope) :-)

+1
source

Im uses the same approach as in other threads - checking that a particular host is the right one to run the job. But..

I don't really need tools, but in spring you can use profiles for this. You can probably find a similar solution for your needs. Take a look at http://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles

You can define two separate beans:

 @Configuration @Profile("dev") public class StandaloneDataConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.HSQL) .addScript("classpath:com/bank/config/sql/schema.sql") .addScript("classpath:com/bank/config/sql/test-data.sql") .build(); } } @Configuration @Profile("production") public class JndiDataConfig { @Bean public DataSource dataSource() throws Exception { Context ctx = new InitialContext(); return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource"); } } 

and decide which one to enable by switching the profile. This way, your class with the annotated @Scheduled method will only be loaded for a specific profile. Of course, you need to configure the application to include a profile from nodes only. In a spring application, it will be as simple as passing -Dspring.profiles.active = profile to one of them.

+2
source

I solved this problem by making one of the boxes a master. basically set the environment variable in one of the fields, for example master = true.

and read it in your java code through system.getenv ("master"). if its present and its true, then run your code.

base fragment

 @schedule() void process(){ boolean master=Boolean.parseBoolean(system.getenv("master")); if(master) { //your logic } } 
-1
source

Source: https://habr.com/ru/post/1204816/


All Articles