【问题标题】:Infinispan Unique Cache Manager for deployed Web Applications用于已部署 Web 应用程序的 Infinispan 唯一缓存管理器
【发布时间】:2016-07-01 10:09:59
【问题描述】:

我正在使用 Infinispan 8.1 和 WildFly 10。

我使用以下代码行以编程方式初始化我的 CacheManager:

public class SessionManager {
    private static DefaultCacheManager cacheManager;

    public void initializeCache(){

        if (cacheManager ==null){ 

            GlobalConfigurationBuilder gcbLocal = new GlobalConfigurationBuilder();
            ConfigurationBuilder builderLocal = new ConfigurationBuilder();
            builderLocal.clustering().cacheMode(CacheMode.LOCAL);
            cacheManager = new DefaultCacheManager(gcbLocal.build(), builderLocal.build()); 
            cacheManager.getCache(); 

这些代码行属于在我的服务器上部署的多个 Web 应用程序中作为依赖项导入的 jar。

所以每次我部署一个新的应用程序时,initialize 方法都会被调用并且 infinispan 尝试创建一个新的 DefaultCacheManager,给我这个异常:

ISPN000034: There's already a JMX MBean instance type=CacheManager,name="DefaultCacheManager" already registered under 'org.infinispan' JMX domain. If you want to allow multiple instances configured with same JMX domain enable 'allowDuplicateDomains' attribute in 'globalJmxStatistics' config element

只需添加以下代码行即可解决此问题:

gcbLocal.globalJmxStatistics().allowDuplicateDomains(true);

但是现在的效果是Infinispan会创建一个新的域分隔的CacheManager。这意味着每个应用程序都有自己的。

我的目标是只有 1 个 DefaultCacheManager 为部署在服务器内的所有 Web 应用程序提供服务,如果 WebApplicationA 在 infinispan 缓存中存储一​​些值,则 webApplicationB 可以获取它。

有可能吗?如何获取全局缓存管理器?

【问题讨论】:

    标签: java caching wildfly infinispan


    【解决方案1】:

    Ernest 是对的 - MBean 服务器是每个 JVM 而不是每个 ClassLoader,因此您需要忽略重复的域。但更有趣的是——Wildfly 使用 Infinispan 进行会话集群,因此默认的缓存管理器可能已经在运行。我强烈建议使用您自己的缓存管理器名称:

    new GlobalConfigurationBuilder().globalJmxStatistics()
                        .cacheManagerName(CACHE_NAME).build();
    

    Ernest 还建议使用 HotRod 服务器集群并使用 HotRod 客户端连接到它(这比使用 REST 接口快得多)。在您描述的情况下,这听起来很合理。

    【讨论】:

    • 是否有可能使用 jmx infinispan 获取属于其他 Web 应用程序的缓存管理器?
    • 我不确定您为什么要为此使用 JMX?我深信客户端/服务器模型正是您所需要的。
    • 性能问题。我认为客户端服务器调用将花费太多时间。 infinispan-jmx 知道重复的 mbean...它应该让我有可能检查缓存管理器...还是不?
    【解决方案2】:

    很明显,您在 web 模块 (.war) 中运行此代码 - 或在捆绑在 war 文件中的 jar 中。由于类加载器受到保护,您不能跨 Web 模块共享实例(这对您有好处)。

    你有几个选择:

    1. 不要部署 war 文件,而是创建一个包含多个 Web 模块和一个 EJB 的 ear 文件,然后创建和使用缓存管理器。然后每个 web 模块将通过本地 EJB 到达缓存,infinispan 库部署在 ear/lib 中。

    2. 运行 Infinispan 服务器(Infinispan 的独立 Wildfly 安装)并更改您的代码以使用远程客户端:

      -- HotRod 客户端从外部连接到它(此处的文档:http://infinispan.org/docs/8.2.x/getting_started/getting_started.html#_using_hot_rod_to_access_an_infinispan_data_grid)。

      -- REST 客户端(此处的文档:http://infinispan.org/docs/8.2.x/user_guide/user_guide.html#_infinispan_rest_server

      每个 Web 模块都可以单独执行此操作。

    【讨论】:

    • 感谢您的回答。但是您知道 infinispan 使用 jgroups 作为服务器场节点上的通信层。这样,如果 webapplicationA 将相同的对象存储到 ServerNodeA 上的缓存中,webapplicationA 就可以在 ServerNodeB 上获取相同的对象。所以我在问...如果作为类加载器的 Web 模块受到保护,如果我已经创建了 DefaultCacheManager Mbean,为什么 infinispan 会抱怨?初始化不应该直接进行吗?
    • 它并没有真正“抱怨”(请记住,正如您所提到的,有一个配置选项可以更改行为)。此外,实例是按虚拟机检查的,而不是按类加载器检查的。给定的 Wildfly 实例上只有一个 VM。关于您对跨节点数据的评论,这就是 Infinispan 的重点。问题是:为什么要在同一个 VM 中“成员”节点(您将在同一个服务器实例上备份数据)?您可以这样做以进行测试,但在生产中实际上没有意义。
    • ... 但想象一下,将不同的 Web 应用程序作为具有 SSO 机制的同一 ERP 的模块。提供跨应用程序共享数据的可能性非常有用,将数据存储在共享缓存中。
    • 不同的网络应用程序?是的......但实际上,它们是不同的工件,以某种方式链接到单个更高级别的应用程序/系统(因此需要共享数据)。在这种特殊情况下,要审查的是您的部署 (IMO)。而且我真的不认为你有问题,因为 Infinispan 确实允许你的场景。
    猜你喜欢
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    相关资源
    最近更新 更多