محمد صادق شیخ زاهدی
محمد صادق شیخ زاهدی
خواندن ۵ دقیقه·۷ ماه پیش

زمان بندی اجرای وظایف SpringBoot

سلام :)

گاهی نیاز هست که ما یک سری کار ها و تسک ها را در دوره زمانی مشخص یا بصورت زمان بندی شده اجرا کنیم، Spring Boot این امکان را برای ما فراهم می کند که وظایف را برای اجرا در یک دوره زمانی معین با کمک انوتیشن Scheduled@ زمان بندی کنیم.

ابتدا باید زمانبندی(scheduling) را در پروژه SpringBoot فعال کنیم برای اینکار نیاز هست که در بالای کلاس اصلی اسپرینگ که شامل متد main پروژه هست انوتیشن @EnableScheduling اضافه کنیم، در کنار انوتیشن @SpringBootApplication. به عنوان مثال:

// Annotation @SpringBootApplication @EnableScheduling // Class public class SchedulerApplication { // Main driver method public static void main(String[] args) { SpringApplication.run(SchedulerApplication.class,args); } }

خب حال برای نوشتن کدهای زمان بندی شده ما نیاز داریم به ایجاد یک @Component کلاس که اسم اون رو Scheduler می گذاریم و درون آن متد scheduleTask() را برای زمان بندی یک کار با استفاده از انوتیشن Scheduled@ تعریف می کند.

متد ()schedulerTask در کلاس Scheduler به سادگی تاریخ و زمانی را که task در آن اجرا می شود چاپ می کند.

// Annotation @Component // Class public class Scheduler { // Method // To trigger the scheduler every one minute // between 19:00 PM to 19:59 PM @Scheduled(cron = &quot0 * 19 * * ?&quot) public void scheduleTask() { SimpleDateFormat dateFormat = new SimpleDateFormat( &quotdd-MM-yyyy HH:mm:ss.SSS&quot); String strDate = dateFormat.format(new Date()); System.out.println( &quotCron job Scheduler: Job running at - &quot + strDate); } }

عنصر cron مشخصشده در انوتیشن Scheduled@ اجازه میدهد تا عبارات cron را برای دربرداشتن تریگرها در ثانیه، دقیقه، ساعت، روز ماه، ماه، و روز هفته تعریف کنیم. عبارت مشخص شده در اینجا در عنصر cron زمانبندی را هر یک دقیقه بین ساعت 19:00 تا 19:59.00 راه اندازی کند.

یعنی هر یک دقیقه بین ساعت 19:00 تا 19:59.00 تابع scheduleTask صدا زده می شود و ما خروجی آن را در کنسول مشاهده می کنیم.

*برای اجرای یک متد در زمان مشخص، باید از انوتیشن Scheduled@ در بالاسر متد مربوطه استفاده نمایید، که به صورت کلی 4 نوع ورودی fixedDelay،fixedRate،initialDelay و cronرا دارد. که ما در مثال بالا از cron استفاده کردیم حال بیایید این چهار نوع را بررسی کنیم

1- fixedDelay

در این حالت، مدت زمان بین پایان آخرین اجرا و شروع اجرای بعدی ثابت است. کار همیشه منتظر می ماند تا کار قبلی تمام شود.این گزینه باید زمانی استفاده شود که اجرای قبلی قبل از اجرای مجدد اجباری باشد که یک عدد ثابت به میلی ثانیه دریافت می کند.

@Scheduled(fixedDelay = 1000) public void scheduleFixedDelayTask() { System.out.println( &quotFixed delay task - &quot + System.currentTimeMillis() / 1000); }

2- fixedRate

این گزینه باید زمانی استفاده شود که هر اجرای وظیفه مستقل باشد که یک عدد ثابت به میلی ثانیه دریافت می کند.

توجه داشته باشید که کارهای برنامه ریزی شده به طور پیش فرض به صورت موازی اجرا نمی شوند. بنابراین حتی اگر از fixedRate استفاده کنیم، تا زمانی که کار قبلی انجام نشود، کار بعدی فراخوانی نخواهد شد.

@Scheduled(fixedRate = 1000) public void scheduleFixedRateTask() { System.out.println( &quotFixed rate task - &quot + System.currentTimeMillis() / 1000); }

اگر میخواهیم از رفتار موازی در کارهای زمانبندیشده پشتیبانی کنیم، باید انوتیشن @Async را اضافه کنیم:

@EnableAsync public class ScheduledFixedRateExample { @Async @Scheduled(fixedRate = 1000) public void scheduleFixedRateTaskAsync() throws InterruptedException { System.out.println( &quotFixed rate task async - &quot + System.currentTimeMillis() / 1000); Thread.sleep(2000); } }

3- initialDelay

برای زمانی است که بخواهیم اجرای اول را در زمان متفاوتی انجام دهیم و بعد با fixed rate/fixed Delay تکرار های بعدی را مشخص کنیم.

اولین اجرا با تاخیر 1 ثانیه ای انجام می شود، سپس سایر اجرا ها هر 2 ثانیه.

@Scheduled(fixedDelay = 1000, initialDelay = 2000) public void scheduleFixedRateWithInitialDelayTask() { long now = System.currentTimeMillis() / 1000; System.out.println( &quotFixed rate task with one second initial delay - &quot + now); }

توجه داشته باشید که چگونه در این مثال از fixedDelay و همچنین initialDelay استفاده می کنیم. این کار برای اولین بار بعد از مقدار initialDelay اجرا می شود و مطابق با fixedDelay به اجرای آن ادامه می دهد.

4- cron

گاهی اوقات تاخیرها و نرخ ها کافی نیستند و ما به انعطاف پذیری یک عبارت cron برای کنترل وظایف خود نیاز داریم. ممکن است شرایطی پیش بیاید که اجرای متد به فواصل زمانی خاصی نیاز داشته باشد. مثلا هر هفته یا آخر هر ماه یا بین یک بازه زمانی مشخص و یا ...

ترتیب قرار گیری مقادیر به صورت زیر است.مقدار سال اجباری نمی باشد ولی سایر فیلد ها باید پر شود.

<second> <minute> <hour> <day-of-month> <month> <day-of-week> <year>

میتوانید از سایت زیر یک عبارت cron تولید یا تست نمایید

https://crontab.cronhub.io/

برای مثال:

@Scheduled(cron = &quot0 15 10 15 * ?&quot) public void scheduleTaskUsingCron) { long now = System.currentTimeMillis() / 1000; System.out.println( &quotschedule tasks using cron jobs - &quot + now); }

توجه داشته باشید که در این مثال، ما یک کار را برنامه ریزی می کنیم که در ساعت 10:15 صبح پانزدهمین روز هر ماه اجرا شود.

* به طور پیش فرض، Spring از منطقه زمانی محلی سرور برای عبارت cron استفاده می کند. با این حال، ما می توانیم از ویژگی zone برای تغییر این منطقه زمانی استفاده کنیم:

@Scheduled(cron = &quot0 15 10 15 * ?&quot, zone = &quotEurope/Paris&quot)

استفاده از تنظیمات application.properties

هاردکد کردن این زمانبندیها ساده است، اما معمولاً نیاز داریم که بتوانیم برنامه را بدون کامپایل مجدد و استقرار مجدد کل برنامه کنترل کنیم.

برای اینکار می توانیم از Spring Expressions و فایل application.properties استفاده کنیم برای اینکار به شکل زیر عمل می کنیم

  • برای وظایف fixedDelay
@Scheduled(fixedDelayString = &quot${fixedDelay.in.milliseconds}&quot)

و قرار دادن fixedDelay.in.milliseconds=1000 در application.properties

  • برای وظایف fixedRate
@Scheduled(fixedRateString = &quot${fixedRate.in.milliseconds}&quot)

و قرار دادن fixedRate.in.milliseconds=1000 در application.properties

  • برای وظایف cron
@Scheduled(cron = &quot${cron.expression}&quot)

و قرار دادن مقدار cron.expression در application.properties

cron.expression=&quot0 15 10 15 * ?&quot


شاید از این پست‌ها خوشتان بیاید