2017-09-01 43 views
0

我有一个使用API​​进行控制的Spring应用程序,我们需要单线程,但我无法弄清楚如何实现这一点。该应用程序是对单线程应用程序的重新分解。他们希望为新版本提供相同的基本设计,同时使用我们的新编程方法(即Java,Spring等)并添加额外的功能。如何使Spring应用程序成为单线程或使其具有一个实例?

有一个API资源来启动应用程序:

@RequestMapping("/start") 
public String startProcess(){...} 

如果被调用两次,然后应用程序将启动另一个线程。 我们想阻止这种情况发生。但是,我们仍然希望停止API资源工作:

@RequestMapping("/stop") 
public String stopProcess(){...} 

的应用程序有一个典型的弹簧结构:

@SpringBootApplication 
public class MyApplication{...} 

@RestController 
public class MyController{ 
    @Autowired 
    private MyService myService; 
    ...} 

@Service 
@Transactional 
public class CarolService{ 
    @Autowired 
    private MyDAO myDAO; 
    ...} 

@Repository 
public class myDAO{...} 

如何确保只有一个在运行此应用程序的实例一次?请帮忙!并且,在此先感谢!

回答

1

实际上你有两个不同的问题:让你的API单线程,并确保一次只运行一个此应用程序的实例。

解决方案在概念上是相同的:您必须在某个互斥锁上进行同步。但在第一种情况下做起来比在第二种情况下要容易得多。

要使您的API单线程,您需要同步某些内容。如果您只有一个控制器,只需制作API方法​​即可。如果您拥有多个控制器,则需要创建一些应用程序范围bean,将其注入每个控制器并在其上进行同步。在过去也有类似SingleThreadModel,但我认为它已被弃用。几年没有看到它,但如果Spring有办法设置它,我不会感到惊讶。

确保一次只运行此应用程序的一个实例要困难得多。你基本上想阻止任何人同时启动应用程序的多个副本。实现这一目标的方法之一是拥有一些像数据库这样的中央共享资源。在启动时,应用程序将尝试通过在某个表中创建记录(最多允许一条记录)来“获取”互斥锁。如果记录已成功创建,则应用程序正常启动,否则失败。您需要一些机制来检测陈旧的互斥记录 - 可能就像在互斥记录中保存时间戳一样简单,并通过计划任务(心跳)不断更新它。

我们最近在运行许多微服务的许多实例的应用程序中有类似的任务。我们只需要一个微服务来定期执行某些维护任务。我们通过在中央MongoDB数据库上进行同步来解决这个问题。微服务尝试通过在数据库集合中创建文档来获取互斥体。通过设计,该集合中最多可以存在一个文档,创建该文档的微服务将执行常规任务并在最后删除该文档。该集合配置有自动清理功能,因此如果微服务因任何原因无法删除文档,它将被数据库自动删除。

+0

这是伟大的信息,lexicore。谢谢! –

相关问题