当前位置: 首页 > 知识库问答 >
问题:

spring boot和长期运行任务

蒲魁
2023-03-14

在我的spring boot应用程序中,我必须实现一个导入服务。用户可以提交一组JSON文件,应用程序将尝试从这些文件中导入数据。根据JSON文件中的数据量,单个导入过程可能需要1或2个小时。

我不想在导入过程中阻止用户,因此我计划接受导入任务,并通知用户此数据已排定处理时间。我将把数据放入队列,另一端的空闲队列使用者将启动导入过程。此外,我需要有一个可能性来监视队列中的一个作业,如果需要的话终止它们。

现在,我正在考虑使用嵌入式Apache ActiveMQ来引入消息生产者和消费者逻辑,但在此之前,我想问一下--从体系结构的角度--它是描述的任务的好选择,还是可以用更合适的工具来实现。比如普通spring@async等等?

共有1个答案

祁彬
2023-03-14

可以像这样用Camel并发地处理文件

from("file://incoming?maxMessagesPerPoll=1&idempotent=true&moveFailed=failed&move=processed&readLock=none").threads(5).process()

查看http://camel.apache.org/file2.html

但我认为更适合您的需求的是使用独立的ActiveMQ、将文件移动到ActiveMQ的独立服务和能够独立地杀死或重新启动每个文件的独立消费者。

最好像您说的那样使用ActiveMQ并且您可以轻松地创建一个服务来将消息移动到带有Camel的队列中,如下所示:

        CamelContext context = new DefaultCamelContext();
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=true");
        context.addComponent("test-jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
        context.addRoutes(new RouteBuilder() {
            public void configure() {
            // convertBodyTo to use TextMessage or maybe send them as file to the Queue            from("file://testFolderPath").convertBodyTo(String.class).to("test-jms:queue:test.queue");
            }
        });
        context.start();

这里有一些例子

http://www.programcreek.com/java-api-examples/index.php?api=org.apache.camel.component.jms.JMSComponent

https://skills421.wordpress.com/2014/02/08/sending-local-files-to-a-jms-queue/

https://github.com/apache/camel/blob/master/examples/camel-example-jms-file/src/main/Java/org/apache/camel/example/cameljmstofileexample.Java

https://github.com/apache/camel/tree/master/examples

要进行监视和管理,您可以将jmx与VisualVM或Hawtio一起使用http://hawt.io/getstarted/index.html

http://camel.apache.org/camel-jmx.html

为了消费,您可以使用DefaultMessageListenerContainer和队列上的并发消费者,为此,您需要更改DefaultMessageListenerContainer的ConnectionFactory(多线程JMS客户端ActiveMQ)上的prefetchPolicy

 类似资料:
  • 我使用的是Activti版本6.0.0。 我想同步执行活动中的任务,但我有一个长时间运行的任务,可能需要20分钟来执行。我想在我的控制器中快速获得过程实例ID,而不考虑在bpmn中完成任务,所以我在bpmn文件中添加了一个中间计时器事件“0分钟”。 我已经开始执行一个进程,比如说processInstanceid p1。当时只有我再次启动这个进程,比如说使用processInstanceid p2

  • 完成上一节的初次运行后,你肯定会发现一点:一旦你按下 Ctrl+C,停下标准输入输出,logstash 进程也就随之停止了。作为一个肯定要长期运行的程序,应该怎么处理呢? 本章节问题对于一个运维来说应该属于基础知识,鉴于 ELK 用户很多其实不是运维,添加这段内容。 办法有很多种,下面介绍四种最常用的办法: 标准的 service 方式 采用 RPM、DEB 发行包安装的读者,推荐采用这种方式。发

  • 问题内容: 问题 我已经将一个长期运行的任务划分为多个逻辑子任务,因此我可以在每个子任务完成时报告结果。但是,我正在尝试报告将永远无法完成的任务的结果(而不是不断产生价值),并且正在使用现有的解决方案来做到这一点。 背景 我正在为我编写的某些Python程序构建Web界面。用户可以通过Web表单提交作业,然后返回查看该作业的进度。 假设我有两个函数,每个函数都可以通过单独的形式进行访问: :执行大

  • 完成上一节的初次运行后,你肯定会发现一点:一旦你按下 Ctrl+C,停下标准输入输出,logstash 进程也就随之停止了。作为一个肯定要长期运行的程序,应该怎么处理呢? 本章节问题对于一个运维来说应该属于基础知识,鉴于 ELK 用户很多其实不是运维,添加这段内容。 办法有很多种,下面介绍四种最常用的办法: 标准的 service 方式 采用 RPM、DEB 发行包安装的读者,推荐采用这种方式。发

  • 我在context.xml文件中定义了一个Spring调度任务,它每分钟运行一次。该任务调用postgres存储过程。存储过程运行时可以持续一分钟以上。如果当前运行没有完成,spring框架会调用相同的调度程序吗?谢谢,