Jakarta ee GlassFish在不同的物理服务器上运行EJB

Jakarta ee GlassFish在不同的物理服务器上运行EJB,jakarta-ee,glassfish,ejb,jms,jndi,Jakarta Ee,Glassfish,Ejb,Jms,Jndi,我有一个Java EE 6 web应用程序运行在GlassFish3.1上。应用程序使用本地单例EJBMySingleton的两个实例。MySingleton的每个实例都通过API连接到第三方软件 MySingleton.java @Singleton @LocalBean public class MySingleton { @PersistenceContext private EntityManager em; private ThirdPartyAPI thir

我有一个Java EE 6 web应用程序运行在
GlassFish
3.1上。应用程序使用本地
单例EJB
MySingleton的两个实例。MySingleton的每个实例都通过API连接到第三方软件

MySingleton.java

@Singleton
@LocalBean
public class MySingleton { 
    @PersistenceContext private EntityManager em;    
    private ThirdPartyAPI thirdPartyAPI;
    ...
}
@Singleton
@LocalBean
public class MySingletonManager { 
    @EJB private MySingleton mySingletonA;
    @EJB private MySingleton mySingletonB;        ///Aargh! They can't run on the same server!!
    ...
}
MySingletonManager.java

@Singleton
@LocalBean
public class MySingleton { 
    @PersistenceContext private EntityManager em;    
    private ThirdPartyAPI thirdPartyAPI;
    ...
}
@Singleton
@LocalBean
public class MySingletonManager { 
    @EJB private MySingleton mySingletonA;
    @EJB private MySingleton mySingletonB;        ///Aargh! They can't run on the same server!!
    ...
}
以下是限制条件:

  • 第三方软件提供商要求其软件在不同的物理服务器上运行
    ThirdPartyAPI
    的每个实例
  • MySingleton使用
    EntityManager
    的注入实例,在同一
    PersistenceContext
    上进行查询和事务时需要该实例
  • 为了满足约束1,我认为我需要远程访问Singleton EJB:我需要告诉应用程序服务器类似“在服务器A上运行mySingletonA,在服务器B上运行mySingletonB”。为此,我发现可以通过
    JNDI
    调用远程EJB

    为了满足约束2,我认为我需要使用GlassFish
    集群
    ,因为persistencecontext需要在MySingleton的两个实例之间共享

    不幸的是,我找不到任何关于如何同时使用这两种技术(远程EJB和集群)的参考资料

    我正在寻找有关此场景首选体系结构的提示或建议,以及最终的一些实现指南。

    两件事

    首先,如果要连接到外部EIS系统,“正确”的方法是编写JCA适配器并使用@Resource注入实例。它们写起来相当简单,亚当·边有一个写简单的例子。想象一下@Resource,比如为应用程序创建自定义数据源。一旦你弄明白了,这真的很有趣。JEE6规范在技术上不支持编写任何使用套接字或同步的EJB

    如果执行此操作,则可以在集群的两个成员上安装此适配器。每个集群成员都可以指向第三方软件的外部实例。如果任何一个集群成员宕机,一切都将继续正常运行

    但是。。。如果您真的想用单例EJB艰难地完成任务,您可能可以这样做:

    首先,摆脱MySingletonManager。集群是透明的,你不应该知道你是集群的。第二,将您的单例代码更改为:

    @Singleton
    @Remote
    public class MySingleton { 
        @PersistenceContext private EntityManager em;    
        private ThirdPartyAPI thirdPartyAPI;
        ...
    
    }
    
    重要的是要理解,单身不能有状态。如果ThirdPartyAPI在调用之间保持状态,有趣的事情就会发生。您还必须在thirdPartyAPI周围放置一个循环连接代码装饰器,以便它将连接到您的两个ThirdPartyServer。最后,创建一个GlassFish集群并跨集群部署EJB。将其按如下方式注入代码:

    @EJB MySingleton myIns;
    
    这将自动在集群中的某个地方定位EJB,并为您提供一个句柄。现在,假设所有这些都可以工作,并且我没有遗漏任何东西,您现在有一个并发问题,因为默认情况下,对任何EJB的访问都是序列化的。您可以添加@ConcurrencyAttribute(无锁),但EntityManager不是线程安全的,它也是事务性的


    总的来说,单例EJB会给您带来很多问题。花点时间写一个JCA适配器

    谢谢你的回答。考虑到这个话题的复杂性,我需要一些时间。。。顺便问一下:你能澄清一下(最后加上一些参考资料)关于“单身不能有状态”的问题吗?刚刚发现了这篇关于单身的有趣文章。感谢集群J2EE环境中的hintA singleton,实际上集群中每个节点都有一个singleton实例。否则,将出现单点故障。。。因此,在集群环境中,在将状态放入单例时必须采取额外的预防措施,因为它们不是“真正的”单例。最简单的管理方法是避免将状态放入集群的单例中。@perissf附带说明,如果您确实觉得我的答案有用,我当然会感谢您的upvote或accept:)