Можно ли запустить длинную задачу с помощью Spring Boot? - PullRequest
0 голосов
/ 30 августа 2018

Я хотел бы запустить несколько длинных задач с Spring Boot, используя TaskExecutor. Я хочу, чтобы несколько RFID-ридеров работали и постоянно получали теги элементов. Затем мне нужно использовать эти теги для обновления базы данных. До сих пор мне не удавалось запускать задачи более одного раза с помощью Spring Boot. Возможно ли это?

Я создаю класс читателя @Component. При создании я запускаю службу слушателя, а слушатель отслеживает теги. У меня есть методы startMessageService и setReaderConfig. Первый метод - запуск службы прослушивания сообщений для получения сообщений с информацией тега от читателя, когда он входит. Второй метод настраивает считыватель на автономное чтение, поэтому, когда теги отправляются читателем, читатель отправляет сообщение слушатель и я получаем сообщение.

Метод run в основном заставляет читателя читать при поступлении сообщений. Но по какой-то причине код работает не так, как я хочу. Как только читатель получит тег, я должен получить сообщение, а я нет.

Внизу мой бин threadpooltaskexecutor.

Я не уверен, что мне не хватает.

@Component
@Scope("prototype")
public class AlienReader extends AlienClass1Reader implements 
TagTableListener, MessageListener, Runnable{
 private String ipaddress;
 private int port;
 private String username;
 private String password;
 int serviceport;

public AlienReader(String ipaddress, int port, String username, String pwd, 
int serviceport) throws UnknownHostException, AlienReaderException, 
InterruptedException{
    super(ipaddress, port);
    this.ipaddress=ipaddress;
    this.port=port;
    this.username=username;
    this.password=pwd;
    this.serviceport=serviceport;
    startMessageService();
    setReaderConfig();

}

}

@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(15);
    executor.setMaxPoolSize(42);
    executor.setQueueCapacity(11);
    executor.setThreadNamePrefix("threadPoolExecutor-");
    executor.setWaitForTasksToCompleteOnShutdown(true);
    executor.initialize();
    return executor;
}

1 Ответ

0 голосов
/ 30 августа 2018

Spring Boot не накладывает никаких ограничений; если вы можете сделать это на Java или другом языке, вы сможете сделать это с помощью Java + Spring Boot.

Что такое пружинный ботинок

Чтобы быть ясным, Spring Boot - это просто основа для создания проектов Spring, которые исторически были достаточно сложными и содержали много кода. Вы можете создавать приложения командной строки с пружинной загрузкой или веб-приложения (которые более обычны). Я уверен, что есть и другие варианты.

Итак, Spring Boot даст вам преимущество, легко предоставив конфигурацию из вашего файла applicationaiton.properties, автоматически подключив все ваши bean-компоненты, настроив проводку для ваших контроллеров и т. Д. Но это не ограничивает код ты пишешь; это просто уменьшает его.

Ваш вопрос

Вы можете использовать службу executor для запуска любого количества долгосрочных задач, если ваш ПК / сервер может их обработать.

Вот пример рабочей пружины, которая запускает две разные задачи параллельно или за минуту. Они могут длиться вечно и делать что угодно, и вы можете легко масштабировать их до сотен задач.

import org.apache.catalina.core.ApplicationContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

@SpringBootApplication
public class App {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(App.class, args);
        App app = run.getBean(App.class);
        app.run();
    }

    private void run() {
        Runnable r1 = () -> {
            for(int i = 0; i < 30; ++i) {
                System.out.println("task 1");
                try {Thread.sleep(1000);} catch(Exception ignored) {}
            }
        };

        Runnable r2 = () -> {
            for(int i = 0; i < 30; ++i) {
                System.out.println("task 2");
                try {Thread.sleep(1000);} catch(Exception ignored) {}
            }
        };

        //Create an executor service with 2 threads (it can be like 50
        //if you need it to be).  Submit our two tasks to it and they'll
        //both run to completion (or forever if they don't end).
        ExecutorService service = Executors.newFixedThreadPool(2);
        service.submit(r1);
        service.submit(r2);

        //Wait or completion of tasks (or forever).
        service.shutdown();
        try { service.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS); }
        catch (InterruptedException e) { e.printStackTrace(); }
    }
}

Дополнительная информация

  • Вы можете запланировать вызовы вместо выполняемых, если вам нужно в конечном итоге получить результаты и ждать их.
  • Существует множество вариантов службы executor, если вам нужны запланированные задачи в дополнение к долгосрочным.
  • Вы можете использовать сколько угодно потоков; просто увеличьте 10:).
  • Это конкретное приложение может быть лучше командной строки, но я сделал его обычным веб-типом с пружинной загрузкой на тот случай, если вам нужны контроллеры и т. Д. Для обслуживания конечных точек проверки задач или чего-то еще. Это довольно неважно, так как вы в основном спрашиваете о самих задачах. Это приложение не будет завершено после завершения, пока вы не добавите System.exit (), так как ожидается, что это будет долгоживущее веб-приложение.
...