Spring Boot - 无限循环服务

12
我想建立一个无头应用程序,它将在无限循环中查询数据库,并在特定条件下执行一些操作(例如,获取具有特定值的记录并在找到每个消息时启动电子邮件发送过程)。
我想使用Spring Boot作为基础(特别是因为Actuator可以允许公开健康检查),但目前我仅用Spring Boot构建REST web服务。
建立无限循环应用程序时,有什么最佳实践或模式要遵循吗? 有人尝试过基于Spring Boot构建它并可以与我分享他的架构吗?
此致敬礼。
3个回答

26

不要自己实现无限循环,使用框架的任务执行功能来处理它。

@Service
public class RecordChecker{

    //Executes each 500 ms
    @Scheduled(fixedRate=500)
    public void checkRecords() {
        //Check states and send mails
    }
}

别忘了为你的应用程序启用调度功能:

@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class);
    }
}

另请参阅:


1
是否可以使用类似的结构,以便您可以使用一个变量来替代“fixedRate”?例如,我想从配置文件中读取“fixedRate”的值。 (参见 https://stackoverflow.com/questions/69281633/spring-boot-infinite-loop-with-configurable-cycle-time) - waldrabe

5
我正在使用一个消息代理和一个消费者,将其放在Spring Boot应用程序中来完成工作。

你的意思是使用Spring Integration创建通道来轮询数据库,当发现有数据时,你的消费者会对这些行执行逻辑? - Pawel Urban
1
感谢您的提示。我最终使用了Spring Integration + Spring Boot。我使用JDBC入站通道适配器来池化数据库,并编写了自己的ServiceActivator来响应发现的行。这个方法只需很少量的代码,效果非常好。 - Pawel Urban

2

有几种选择。我的方法是在ApplicationReadyEvent上启动循环,并将循环逻辑抽象成可注入的服务。在我的情况下,它是一个游戏循环,但这个模式对你也应该适用。

package com.ryanp102694.gameserver;

import com.ryanp102694.gameserver.service.GameProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class GameLauncher implements ApplicationListener<ApplicationReadyEvent> {
    private static Logger logger = LoggerFactory.getLogger(GameLauncher.class);

    private GameProcessor gameProcessor;

    @Autowired
    public GameLauncher(GameProcessor gameProcessor){
        this.gameProcessor = gameProcessor;
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        logger.info("Starting game process.");
        gameProcessor.start();
        while(gameProcessor.isRunning()){
            logger.debug("Collecting user input.");
            gameProcessor.collectInput();
            logger.debug("Calculating next game state.");
            gameProcessor.nextGameState();
            logger.debug("Updating clients.");
            gameProcessor.updateClients();
        }
        logger.info("Stopping game process.");
        gameProcessor.stop();
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接