多租户Seam + JPA应用程序

3
我正在处理一个现有的Seam 2.2.0 + JPA(Hibernate 3.3.1)应用程序,需要将其转换为“每个客户端单个数据库”的环境,其中每个数据库架构相同。该应用程序在Glassfish上运行,使用IceFaces,并且有几个页面利用Conversations。它还使用一个单独的EJB进行身份验证。不幸的是,将客户端拆分到他们自己的数据库中的决定不在我的控制之内。
作为概念验证,我已经通过使用Spring JPA抽象、资源本地事务和ThreadLocal上下文信息,将EntityManagerFactory(ies)和DataSource(s)的管理移到了应用程序中,让应用程序意识到多个数据库。例如,每次用户登录时,如果尚未初始化与其数据库通信的新DataSource,则会初始化一个新的EntityManagerFactory。这在少量数据库的测试环境中运行良好。
我的问题是,这种方法是否适用于数百个数据库?我打算向负载均衡器添加应用程序服务器来处理额外的负载,但是与 typicall 负载平衡应用程序相比,Hibernate/JPA一级缓存和/或Seam上下文管理(即内存消耗)的开销是否需要更多服务器才能扩展?如果是这样,是否可以通过分配具有大量RAM和/或大型分布式缓存的服务器来缓解这种情况?
非常感谢任何见解。

嗨,Alex,你能给我一个使用新的DataSource初始化新的EntityManagerFactory的例子吗?谢谢。 - Kevin Yang
1个回答

1

我曾经使用这种方法开发过一个应用程序,我可以指出的是:

  • 数据源和EntityManagerFactory的管理是困难的部分。但是在测试环境中似乎已经做到了这一点。请再次检查是否正确地处理了Seam Managed Entity Manager。
  • 如果你有数百个数据库,你的应用程序将无法很好地扩展,因为每个数据库的内存消耗都会线性增加。实际上,对于每个数据库,你将拥有不同的EntityManagerFactory(Hibernate SessionFactory)实例,每个实例都需要相当大的内存。
  • 如果配置Hibernate二级缓存,请注意可能出现的问题。由于所有SessionFactories都是从同一数据模型创建的,缓存区域名称可能会发生冲突。我使用hibernate.cache.region_prefix配置参数,以数据库ID作为缓存前缀,使这些名称在各个实例之间保持唯一。

感谢@Stefano。我在类似于生产环境的系统上进行了负载测试,并得出了相同的结论。我不得不删除Drools授权,因为它在每个EntityManagerFactory中消耗了约50%的RAM,并且必须禁用Hibernate注释扫描,而是明确列出带注释的实体类。后者是性能瓶颈,并引起了同步问题。 - Alex A

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