是否可以使用 Spring 引导来 运行 一项较长的任务?
Is it possible to run a long task using Spring Boot?
我想 运行 几个长任务 Spring 使用 TaskExecutor 启动。我想要多个 rfid readers 运行ning 并连续获取项目标签。然后我需要使用这些标签来更新数据库。到目前为止,我使用 Spring Boot 无法多次获得 运行ning 任务。这可能吗?
我正在创建一个@Component reader class。创建时,我启动侦听器服务和侦听器以跟踪标签。我有 startMessageService 和 setReaderConfig 方法。第一种方法我启动消息侦听器服务以接收来自 reader 的带有标签信息的消息。第二种方法将 reader 设置为自主读取,因此当标签经过时reader,reader向监听器发送消息,我收到消息。
运行 方法基本上使 reader 在收到消息时继续读取。但由于某种原因,代码无法按我希望的方式运行。一旦 reader 收到标签,我应该会收到一条消息,但我没有。
底部是我的 threadpooltaskexecutor bean。
我不确定我错过了什么。
@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;
}
Spring 引导不施加任何限制;如果你可以用 Java 或其他语言做到这一点,你应该可以用 Java + Spring Boot.
什么是Spring引导
需要明确的是,Spring Boot 基本上只是一个用于构建 Spring 项目的框架,这些项目在历史上非常复杂并且有很多样板代码。您可以使 spring 启动命令行应用程序或 Web 应用程序(更正常)。我敢肯定还有更多选择存在并且即将到来。
因此,Spring Boot 将通过轻松公开 applicaiton.properties 文件中的配置,自动连接所有 spring beans,为您设置连接,让您领先一步controller等,但不限制你写的代码;它只是减轻了它。
你的问题
您可以使用执行程序服务 运行 任意数量的 运行ning 任务,只要您的 PC/server 可以处理它们。
这是一个有效的 spring 引导示例,其中 运行 并行或一分钟执行两个不同的任务。它们可以永远存在并可以做任何事情,您可以轻松地将其扩展到数百个任务。
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(); }
}
}
更多信息
- 如果您需要最终获得结果并等待它们,您可以安排可调用而不是 运行可调用。
- 除了长 运行ning 任务之外,如果您还需要计划任务,执行程序服务有很多变体。
- 您可以使用任意数量的线程;只需增加 10 :).
- 这个特定的应用程序作为命令行应用程序可能更好 - 但我将其设为正常的 spring 启动 Web 类型,以防您需要 controllers/etc 来提供任务检查端点或其他任何东西。它非常无关紧要,因为您主要是在询问任务本身。这个应用程序一旦完成就不会终止,除非你添加一个 System.exit() 因为它期望成为一个长期存在的网络应用程序。
我想 运行 几个长任务 Spring 使用 TaskExecutor 启动。我想要多个 rfid readers 运行ning 并连续获取项目标签。然后我需要使用这些标签来更新数据库。到目前为止,我使用 Spring Boot 无法多次获得 运行ning 任务。这可能吗?
我正在创建一个@Component reader class。创建时,我启动侦听器服务和侦听器以跟踪标签。我有 startMessageService 和 setReaderConfig 方法。第一种方法我启动消息侦听器服务以接收来自 reader 的带有标签信息的消息。第二种方法将 reader 设置为自主读取,因此当标签经过时reader,reader向监听器发送消息,我收到消息。
运行 方法基本上使 reader 在收到消息时继续读取。但由于某种原因,代码无法按我希望的方式运行。一旦 reader 收到标签,我应该会收到一条消息,但我没有。
底部是我的 threadpooltaskexecutor bean。
我不确定我错过了什么。
@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;
}
Spring 引导不施加任何限制;如果你可以用 Java 或其他语言做到这一点,你应该可以用 Java + Spring Boot.
什么是Spring引导
需要明确的是,Spring Boot 基本上只是一个用于构建 Spring 项目的框架,这些项目在历史上非常复杂并且有很多样板代码。您可以使 spring 启动命令行应用程序或 Web 应用程序(更正常)。我敢肯定还有更多选择存在并且即将到来。
因此,Spring Boot 将通过轻松公开 applicaiton.properties 文件中的配置,自动连接所有 spring beans,为您设置连接,让您领先一步controller等,但不限制你写的代码;它只是减轻了它。
你的问题
您可以使用执行程序服务 运行 任意数量的 运行ning 任务,只要您的 PC/server 可以处理它们。
这是一个有效的 spring 引导示例,其中 运行 并行或一分钟执行两个不同的任务。它们可以永远存在并可以做任何事情,您可以轻松地将其扩展到数百个任务。
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(); }
}
}
更多信息
- 如果您需要最终获得结果并等待它们,您可以安排可调用而不是 运行可调用。
- 除了长 运行ning 任务之外,如果您还需要计划任务,执行程序服务有很多变体。
- 您可以使用任意数量的线程;只需增加 10 :).
- 这个特定的应用程序作为命令行应用程序可能更好 - 但我将其设为正常的 spring 启动 Web 类型,以防您需要 controllers/etc 来提供任务检查端点或其他任何东西。它非常无关紧要,因为您主要是在询问任务本身。这个应用程序一旦完成就不会终止,除非你添加一个 System.exit() 因为它期望成为一个长期存在的网络应用程序。