【问题标题】:How to use HTTPClient from within EJB in TomEE如何在 TomEE 的 EJB 中使用 HTTPClient
【发布时间】:2015-11-04 18:38:21
【问题描述】:

我有一个 EJB3 bean,它需要从多个 HTTP 服务器进行 GET 或 POST。我已经阅读了有关编写 JCA 适配器的文档,以及有关 Apache HTTPComponents 的文档,特别是 HTTPClient 提供的托管连接、托管连接工厂等。

我注意到BasicHttpClientConnectionManager 的文档说要使用它,而不是PoolingHttpClientConnectionManager“EJB 容器内部”。目前尚不清楚“EJB 容器内部”是指要在容器中运行的 EJB 中的用户代码,还是容器自己的实现代码(例如,您可能放入 JCA 适配器中的内容。

我仍然有点不清楚,在架构上,如何处理任务以最大限度地利用容器提供的服务。到目前为止,我的选择似乎是:

  1. 在 EJB 中,创建一个新的 BasicHttpClientConnectionManager,然后创建一个客户端,如下所示:

    BasicHttpClientConnectionManager cxMgr = new BasicHttpClientConnectionManager() HttpClients.custom().setConnectionManager(cxMgr).build()

    我相信,这将导致没有连接池,而是 EJB 实例池,这可能不会那么高效,因为 EJB 容器无法知道哪个 bean 实例持有与哪个远程的活动连接HTTP 服务器。

  2. 编写一个(相当小的)JCA 适配器来包装 PoolingHttpClientConnectionManager,然后在 EJB 中,使用 @Resource 注释获取该适配器并使用它来构建 HTTPClient

  3. 编写一个 JCA 适配器来管理 HTTPClients 池并在需要时分发它们。

我不清楚我应该采用哪种方法,或者我是否忽略了某种已经内置在容器中的 HTTP 连接管理服务(在本例中为 TomEE plus)。我该怎么做?

【问题讨论】:

  • 我在 EJB 中直接使用了 PoolingHttpClientConnectionManager(没有 JCA 适配器),但那是一个单例(我们使用的是 ejb-3.1)并且连接数相当固定

标签: ejb ejb-3.0 apache-httpclient-4.x apache-tomee jca


【解决方案1】:

事情没那么简单:这些选项都不匹配。具体答案取决于您的 HTTP 连接的远程端是否是单个资源。

如果它是单个逻辑资源,则 JCA 匹配最佳。不过,您几乎不应该在适配器中避免对它的 HTTP 特性的任何引用:为您的远程系统设计一个适当的逻辑接口,然后在该接口上实现一个资源适配器。您的客户端请求他们需要的数据,然后接收它不是作为 HTML 字符串,而是作为即用型 Java bean。您将能够利用 EJB 容器提供的许多优势而不会违反要求。

如果您需要一个入口点来访问未指定数量的外部服务(HTML 页面搜索索引可能就是这种工作),那么事情就会变得棘手。 JCA 不打算用于这类事情,但它非常适合它们:我正在维护 TCP SocketConnector 项目,它的功能几乎相同,而且一切都像魅力一样。 EJB 不适合这里:无状态 bean 池很难控制,单例将要求您自己编写非阻塞池实现,而有状态是一种单线程的。

还有一个额外的选择:虽然 JCA 将更容易集成到您现有的 Java EE 环境中,但如果您是第一次从头开始实现资源适配器,可能会很困难。与 JMS 队列连接的外部 HTTP 查询工具在这里可能会派上用场。 JMS 将更容易平衡工作负载,但它消除了任何交互性并可能减慢整个链的速度。

附:对于原始问题的第三个选项:无需在 JCA 中实现池化,因为默认情况下容器已经为所有资源适配器实例维护连接池。只需为每个 JCA 的 ManagedConnection 保留一个 HTTP 客户端连接,一切都可以开箱即用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-27
    相关资源
    最近更新 更多