【问题标题】:Spring boot command line application doesn't terminate with neo4j driverSpring boot 命令行应用程序不会以 neo4j 驱动程序终止
【发布时间】:2021-07-08 05:48:25
【问题描述】:

我已将 Neo4j 连接添加到一个简单的 Spring Boot 命令行应用程序 - 它实现了CommandLineRunner

我几乎遵循了Neo4j driver manual 中的示例,但我的应用程序在main() 完成后并未终止。
与这些来源的唯一偏差是driver.close() 方法不是在main() 结束时调用,而是在@PreDestroy 注释方法中调用:

@Service
public class DatabaseGraphService {
    
    private volatile Driver driver;
    
    private final Logger LOG;
    
    public DatabaseGraphService() {
        LOG = LogManager.getLogger(getClass());
    }

    @PostConstruct
    private void initialize() throws Exception {
        driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "neo4j"));
    }
    
    @PreDestroy
    public void close() throws Exception {
        LOG.info("Shutting down Neo4j driver...");
        driver.close();
    }
    
    // ...
    
}

主类:

@SpringBootApplication(scanBasePackages={ "it" })
public class SpringBootConsoleApplication implements CommandLineRunner {

    @Autowired
    private DatabaseGraphService graphService;
    
    private static Logger LOG = LoggerFactory
      .getLogger(SpringBootConsoleApplication.class);

    public static void main(String[] args) {
        LOG.info("STARTING THE APPLICATION");
        
        SpringApplication.run(SpringBootConsoleApplication.class, args);
        LOG.info("APPLICATION FINISHED");
    }
 
    @Override
    public void run(String... args) {
        LOG.info("EXECUTING : command line runner");
    }
    
}

我在 Sprint 工具套件(基于 Eclipse 的 IDE)中运行它,这是它记录的内容:

i.c.c.e.SpringBootConsoleApplication     : APPLICATION FINISHED

但没有别的,进程保持活跃;当我按下停止按钮时,然后:

inMXBeanRegistrar$SpringApplicationAdmin : Application shutdown requested.
i.c.c.services.DatabaseGraphService      : Shutting down Neo4j driver...
com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
[...]

如果我在不执行任何查询的情况下运行程序,则该进程定期存在。只要我进行查询 - 无论我是使用所有结果还是对 Result 对象不执行任何操作 - 它都会保持活动状态。

我做错了吗?或者这可能是预期的行为,因为当main() 完成时,它只是它的线程终止?

虽然,在同一个应用程序中,我连接到一个 PostgreSQL 实例,也在那里进行查询,但应用程序在添加 Neo4j 连接之前正确终止。

【问题讨论】:

  • 您知道您不需要这样做,Spring Boot 会为您配置 Neo4J(如果包含)?所以我建议尝试一下,而不是自己做。如果您使用的是 Neo4j,我觉得 Hikira 也是配置的一部分很奇怪?因此,根据您的依赖关系,由于部件被自动配置,事情可能仍在运行。
  • @M.Deinum 实际上不是,我只是在关注 Neo4j 文档。哦,刚刚检查了两次:我看到了 Spring Data 和 Neo4j OGM,但不知何故没有看到 Boot Starter 页面!谢谢,我会检查一下。关于 Hikari,主要数据源是 PostgreSQL 数据库,Neo4j 是最近添加的。
  • @M.Deinum 不,同样的结果。我按照Neo4j Java Driver Spring Boot Starter page 上的说明进行操作——我使用的是 Boot 2.3.9——但应用程序没有终止。
  • 如前所述,可能有更多的事情开始了,然后只有你的命令行工作(可能是一个监控线程?你是否包括执行器和/或 spring-web 等)。您能否发布/添加更多信息,因为目前信息太少。是仅在添加 Neo4j 之后发生还是在此之前发生?
  • @M.Deinum 我会尝试发布更多代码。同时,我可以告诉你,这只是在添加 Neo4j 后才开始出现的。此外,如果存在依赖项/连接/等,但实际上没有向 Neo4j 运行查询,则应用程序将终止。它仅在执行查询时才保持活动状态,似乎连接池“保持开启”。

标签: java spring-boot neo4j neo4j-driver


【解决方案1】:

Neo4j Java Driver 管理负责网络通信的内部线程。它在涉及网络的第一次 API 使用时引导它们。

您的应用程序不会退出,因为这些线程一直在运行。要关闭它们,您必须调用 Driver 的 close 方法。 4.3.4 Javadoc sn-p:

Close all the resources assigned to this driver, including open connections and IO threads.

在描述的设置中,它应该在运行打包的 JAR 时在中断信号 (CTRL+C) 上调用。

从版本 4.3.2 开始,这些线程已更新为守护线程,因此它们不会阻止应用程序完成执行。此外,此更改也已向后移植到版本 4.2.7 和 4.1.4。

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • 这个答案实际上包含基本信息,并有额外上下文的链接。但是,为了更方便,我对其进行了修改并内联了 Javadoc。
猜你喜欢
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 2019-08-27
  • 2020-02-08
  • 1970-01-01
  • 2018-05-29
相关资源
最近更新 更多