Фонови работни места през пролетта с JobRunr

1. Общ преглед

В този урок ще разгледаме разпределеното планиране и обработка на фонови задачи в Java с помощта на JobRunr и ще го интегрираме с Spring.

2. Относно JobRunr

JobRunr е библиотека, която можем да вградим в нашето приложение и която ни позволява да планираме фонови задачи с помощта на Java 8 ламбда. Можем да използваме всеки съществуващ метод на нашите пролетни услуги, за да създадем работа, без да е необходимо да прилагаме интерфейс. Работата може да бъде кратък или дългосрочен процес и тя автоматично ще бъде разтоварена във фонова нишка, така че текущата уеб заявка да не бъде блокирана.

За да си свърши работата, JobRunr анализира ламбда Java 8. Той го сериализира като JSON и го съхранява в релационна база данни или в хранилище за данни NoSQL.

3. Характеристики на JobRunr

Ако видим, че произвеждаме твърде много фонови задачи и нашият сървър не може да се справи с товара, можем лесно да мащабираме хоризонтално, като просто добавим допълнителни екземпляри на нашето приложение. JobRunr ще споделя натоварването автоматично и разпределя всички работни места в различните екземпляри на нашето приложение.

Той също така съдържа функция за автоматичен повторен опит с експоненциална политика на отстъпление за неуспешни задачи. Има и вградено табло , което ни позволява да наблюдаваме всички работни места. JobRunr се самоподдържа - успешните задачи автоматично ще бъдат изтрити след конфигурируемо време, така че няма нужда да извършвате ръчно почистване на съхранението.

4. Настройка

За по-голяма простота ще използваме хранилище за данни в паметта, за да съхраняваме цялата информация, свързана с работата.

4.1. Maven конфигурация

Нека да преминем направо към Java кода. Но преди това трябва да имаме следната зависимост на Maven, декларирана в нашия файл pom.xml :

 org.jobrunr jobrunr-spring-boot-starter 1.1.0 

4.2. Пролетна интеграция

Преди да преминем направо към това как да създадем фонови работни места, трябва да инициализираме JobRunr. Тъй като използваме зависимостта jobrunr-spring-boot-starter , това е лесно. Трябва само да добавим някои свойства към application.properties :

org.jobrunr.background-job-server.enabled=true org.jobrunr.dashboard.enabled=true

Първото свойство казва на JobRunr, че искаме да стартираме екземпляр на BackgroundJobServer, който отговаря за обработката на задания. Второто свойство казва на JobRunr да стартира вграденото табло за управление.

По подразбиране jobrunr-spring-boot-starter ще се опита да използва съществуващия ви DataSource в случай на релационна база данни, за да съхранява цялата информация, свързана с работата.

Тъй като обаче ще използваме хранилище за данни в паметта, трябва да предоставим Bean StorageProvider :

@Bean public StorageProvider storageProvider(JobMapper jobMapper) { InMemoryStorageProvider storageProvider = new InMemoryStorageProvider(); storageProvider.setJobMapper(jobMapper); return storageProvider; }

5. Употреба

Сега нека разберем как да създаваме и планираме фонови задачи през пролетта с помощта на JobRunr.

5.1. Инжектирайте зависимости

Когато искаме да създадем работни места, ще трябва да инжектираме JobScheduler и нашата съществуваща услуга Spring, съдържаща метода, за който искаме да създадем работни места, в този случай SampleJobService :

@Inject private JobScheduler jobScheduler; @Inject private SampleJobService sampleJobService;

Класът JobScheduler от JobRunr ни позволява да поставим в опашка или да планираме нови фонови задачи.

В SampleJobService може да бъде някой от нашите съществуващи Пролет услуги, съдържащи метод, който може да отнеме твърде много време, за да се справят по заявка в мрежата. Може да бъде и метод, който извиква някои други външни услуги, където искаме да добавим устойчивост, тъй като JobRunr ще опита отново метода, ако възникне изключение.

5.2. Създаване на огнени и забравени работни места

Сега, когато разполагаме с нашите зависимости, можем да създаваме работни места „забрави и забрави“, използвайки метода на опашката :

jobScheduler.enqueue(() -> sampleJobService.executeSampleJob());

Работните места могат да имат параметри, както всяка друга ламбда:

jobScheduler.enqueue(() -> sampleJobService.executeSampleJob("some string"));

Този ред гарантира, че ламбда - включително тип, метод и аргументи - е сериализирана като JSON към постоянно съхранение (RDBMS като Oracle, Postgres, MySql и MariaDB или база данни NoSQL).

Специализиран работен пул от нишки, работещи във всички различни BackgroundJobServer , ще изпълни тези задания на опашка на фона възможно най-скоро, по начин първи в първия. JobRunr гарантира изпълнението на вашата работа от един работник чрез оптимистично заключване.

5.3. Планиране на работни места в бъдещето

Също така можем да планираме работни места в бъдеще, като използваме метода на графика :

jobScheduler.schedule(() -> sampleJobService.executeSampleJob(), LocalDateTime.now().plusHours(5));

5.4. Планиране на работни места периодично

Ако искаме да имаме повтарящи се задачи, трябва да използваме метода scheduleRecurrently :

jobScheduler.scheduleRecurrently(() -> sampleJobService.executeSampleJob(), Cron.hourly());

5.5. Анотиране с @Job Annotation

To control all aspects of a job, we can annotate our service method with the @Job annotation. This allows setting the display name in the dashboard and configuring the number of retries in case a job fails.

@Job(name = "The sample job with variable %0", retries = 2) public void executeSampleJob(String variable) { ... }

We can even use variables that are passed to our job in the display name by means of the String.format() syntax.

If we have very specific use cases where we would want to retry a specific job only on a certain exception, we can write our own ElectStateFilter where we have access to the Job and full control on how to proceed.

6. Dashboard

JobRunr comes with a built-in dashboard that allows us to monitor our jobs. We can find it at //localhost:8000 and inspect all the jobs, including all recurring jobs and an estimation of how long it will take until all the enqueued jobs are processed:

Bad things can happen, for example, an SSL certificate expired, or a disk is full. JobRunr, by default, will reschedule the background job with an exponential back-off policy. If the background job continues to fail ten times, only then will it go to the Failed state. You can then decide to re-queue the failed job when the root cause has been solved.

All of this is visible in the dashboard, including each retry with the exact error message and the complete stack trace of why a job failed:

7. Conclusion

В тази статия създадохме първия си основен планировчик, използвайки JobRunr с jobrunr-spring-boot-starter . Ключовият извод от този урок е, че успяхме да създадем работа само с един ред код и без никаква XML-базирана конфигурация или необходимост от внедряване на интерфейс.

Пълният изходен код за примера е достъпен на GitHub.