Spring Batch多租户实现

3
我们如何定义Spring Batch作业以针对多个租户运行?
我已经设置每晚按顺序运行一系列作业来针对一个数据库模式。当前,所有作业都从一个位置读取文件并插入到数据库中。批处理配置非常基本,其中我定义了数据源、事务管理器并将作业存储库映射到它。我的作业将指向此存储库和事务管理器。此外,我目前在数据库中持久化批处理元数据信息。
我的新要求是能够针对多个租户(按顺序执行的相同作业)运行这些作业。每个租户的数据可以存在于同一个数据库服务器中的不同模式或甚至不同的数据库服务器中。我的问题是:
1)我们是否应该将所有租户的批处理特定元数据信息存储在一个公共数据库中,还是每个租户数据库都应该有自己的元数据信息?
2)我的理解是,我们需要为每个租户提供一个数据源,以便针对该租户的作业可以访问数据库以存储从文件中读取的数据。当为该租户执行作业时,Spring Batch存储库是否也应该指向当前数据源?
3)我们计划同时启动所有租户[作业],这意味着JOB1可以同时为所有租户运行。此时,我仍然不确定在每个关联不同数据源的租户运行时如何管理作业存储库、数据源和事务管理器。
4)我想到的是为每个租户复制我的现有配置,使用自己的作业存储库指向特定于租户的数据源和事务管理器。如果没有其他动态定义相同内容的方法,这是我实施的最后一件事。
如果有人已经解决或有任何关于如何解决此问题的想法,请分享。示例配置应该有所帮助。
1个回答

0

我曾参与构建一个SaaS应用程序,其中需要使用Spring Batch进行类似但不完全相同的操作。

对于您来说,主要思路是:

a. 定义一个主数据库,在其中存储所有特定配置数据,例如您可能有一张表,将租户名称、信息和数据源配置映射起来。

b. 启动应用程序并读取此数据源,在服务器端维护一个本地缓存,以租户名称为键,租户信息(数据源等)为值。

c. 在您的线程中保持一个本地线程,例如:

public class TenantThreadLocalContext
{
    public static final ThreadLocal<TenantInformation> threadLocal = new ThreadLocal<TenantInformation>();

    public static void set(TenantInformation tenantInformation)
    {
        threadLocal.set(tenantInformation);
    }

    public static void unset()
    {
        threadLocal.remove();
    }

    public static TenantInformation get()
    {
        return threadLocal.get();
    }

}

d. 每当您启动任何线程以开始处理(批处理)时,请使用租户信息设置此线程本地,以便每个线程都知道它与哪个租户相关联。

e. 最后,在数据库处理时,您可以看到线程具有什么数据源,并且您可以使用此数据源进行连接。

如果您正在使用Hibernate,则很幸运,因为Hibernate 4已经为您完成了所有这些工作。请参考:this。如果您需要帮助进行Hibernate配置等方面的问题,我也可以在那方面为您提供帮助。


1
谢谢Sandeep。是的,我们正在使用hibernate4,并且已经设置了多租户。问题是我不确定如何配置Spring Batch来处理多个租户。Spring Batch具有特定于作业的表,其中存储所有与作业相关的信息,我想知道在存储作业元数据方面应该如何最好地进行,我们使用一个公共数据库还是必须是特定于租户的。我们是否将作业存储库映射到每个租户的数据源。 - Mallikarjun
通常我们采用这种方法,租户特定的数据(在您的情况下可能是作业ID等)应该放在租户数据库中,但配置数据(即服务器配置数据不依赖于任何租户但适用于所有租户)应该放在主数据库中。 - Sandeep B
最终我采用了您的建议,使用Spring JDBC模板、ContextSwappableTargetSource和TargetRegistry。 - Mallikarjun
请为 https://jira.spring.io/browse/BATCH-2480 点赞,以便在批处理本身中添加内置支持。 - Sreekanth

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