5

我正在创建一个 Java EE 应用程序,它允许用户从 Web 界面添加/删除“socketinfo”表(存储在数据库中)。如果用户从 Web 界面启用“socketinfo”,应用程序服务器必须为传入的数据包创建一个套接字侦听器并处理数据。如果用户禁用或删除“socketinfo”,则必须删除套接字侦听器。整个产品必须包含在一个耳朵中,并且最好是合规的。我考虑过但遇到问题的一些方法是:

  1. 为套接字创建一个 JCA 资源适配器并将 MDB 用作侦听器。我在这里遇到的问题是,当用户添加 MDB 时,我无法弄清楚如何以编程方式为不同的套接字部署 MDB。

  2. 创建一个@Singleton/@Service ejb,通过仔细同步来管理守护线程。可以将单例 ejb 注入业务层,以便在正确的工作流程中进行 CRUD 操作和套接字操作。这里的问题是,假设从 EJB 创建线程被认为是一种不好的做法,并且不符合规范(即使正确处理了单例生命周期并且有适当的同步机制?)。

  3. 将线程放入域模型(另一个单例?)并让 EJB 使用该模型。这是所有这些中最糟糕的,因为应用程序服务器往往有多个类加载器,一般来说容器支持较少,再加上这会受到所有 2. 的影响。

知道如何在 Java EE 中正确处理这种情况吗?

编辑:对这个问题的扩展:假设我决定像 ewernli 在他的解决方案 3 中建议的那样解决这个问题,我在 JCA 中这样做(使用自定义接口来添加内部线程)可以获得什么我不会从(精心设计)单身?虽然创建资源适配器看起来不像是一项艰巨的任务,但它似乎并不完全是微不足道的,并且可能会有点耗时(对于其他开发人员来说可能更难遵循)。

4

2 回答 2

1

您的分析似乎是合理的,当您说不能动态部署 MDB 以适应 JCA 时,您是对的。

更多设计理念:

  • 您可以编写一个返回的 JCA 连接器SocketConnections(本着 JMS 的精神),您可以使用它从套接字读取。继续 JMS 类比,MDB 代表MessageListener,而您要公开的是MessageConsumer.

  • 您可以使用周期性计时器来模拟线程。而不是一个带有while循环的线程,你有一个重新安排自己的计时器。我用它让一个应用程序有一个后台进程,效果很好。请注意,我还直接从 EJB 派生了线程,以便在另一个应用程序中进行一些并发计算,并且效果也很好。但是短暂存在的线程和 bean 中的业务方法会等到全部完成,所以这并不是对规范的重大违反。

  • 另一种设计是让 JCA 连接器处理线程等并将所有消息传递给 MDB。MDB 将接收数据以及与数据对应的“通道”有关的信息,例如套接字端口。这就像在一个 MDB 中多路复用,然后对数据进行解复用。您的连接器可以提供额外的 API 来控制线程的创建等,并且可以将该接口注入您的 EJB(类似于ConnectionFactory)。您的连接器可以提供额外的 API 来控制线程的创建等。不是很清楚,但我希望您明白这一点。如果我是对的,JCA 连接器可以确保将数据同步传送到 MDB,至少每个套接字,以便 MDB 以正确的顺序处理数据。

如果开发时间允许,我会选择#3 。

编辑

这种选择确实部分是设计纯度的问题。尽管用户生成的线程存在一个问题,但您显然不能为它们使用声明性事务。不过,您也许可以UserTransaction自己使用 a 来划分事务。我不知道你能EntityManager在这样的线程中使用多少。如果您主要处理数据并且不使用中间件的太多功能,您可以自己生成线程。请参阅我的另一个答案:EJB 如何并行化一个长的 CPU 密集型进程?. 我想到的其他事情(不知道它们是否有问题):安全管理器可能会阻止创建线程(?),而不是将它们创建为守护线程可能会阻止应用程序。服务器正常关闭(?)。请注意,我从ServeletContextListener在启动时,效果很好。这是一个经常使用的技巧,即使它违反了规范。“新”引入的单例 bean 也可能如此。所以,如果你的时间不够,你当然可以用一个单例 bean 来尝试你的提议,看看什么可行/不可行。

于 2011-05-24T10:10:03.297 回答
1

我相当确定#2 是最好的解决方案(并且也是有效的)。我还没有查看新的“Singleton”ejb 的规范,但我的假设是这些内部的线程是可以接受的(考虑到在这些 ejb 中进行自己的同步是可以接受的)。这些旨在使部署管理类型服务更容易(更容易),您以前可以使用 JMX 来完成(尽管部署不是标准化的)。 在 JMX mbean 中,进行自己的线程管理当然是可以接受的,所以我会将其转移到 Singleton ejbs

快速浏览了 ejb 3.1 规范,我想 Singleton 的唯一允许是并发控制,没有线程/套接字的东西。有点傻。我猜它们不是成熟的 JMX mbean 替代品。也就是说,您始终可以使用 JMX mbean,尽管部署是非标准的。如果您使用的是 jboss,那么 Service 注释等效于 JMX mbean,其中所有内容都应该是允许的(线程、套接字等)。

于 2011-05-24T16:39:24.550 回答