Как использовать HTTPClient из EJB в TomEE

У меня есть bean-компонент EJB3, который должен получить или отправить сообщение с нескольких HTTP-серверов. Я прочитал документацию по написанию адаптеров JCA, а также документацию по HTTP-компонентам Apache, в частности, по управляемым соединениям, фабрикам управляемых соединений и т. д., которые предлагает HTTPClient.

Я отмечаю, что документация для BasicHttpClientConnectionManager предлагает использовать его, а не PoolingHttpClientConnectionManager "Внутри контейнера EJB". Неясно, относится ли «Внутри контейнера EJB» к пользовательскому коду в EJB, который должен быть запущен в контейнере, или к собственному коду реализации контейнера (например, к тому, что вы можете поместить в адаптер JCA.

С точки зрения архитектуры я все еще немного не понимаю, как справиться с задачей, чтобы максимально использовать преимущества услуг, предлагаемых контейнером. Пока мой выбор выглядит следующим образом:

  1. Внутри EJB создайте новый BasicHttpClientConnectionManager, а затем создайте клиента, например:

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

    Я полагаю, что это приведет не к пулу соединений, а к пулу экземпляров EJB, что, вероятно, не будет столь эффективным, поскольку контейнер EJB не имеет возможности узнать, какой экземпляр компонента поддерживает активное соединение с каким удаленным HTTP-сервером.

  2. Напишите (достаточно минимальный) адаптер JCA, который обертывает PoolingHttpClientConnectionManager, а затем внутри EJB возьмите этот адаптер с аннотацией @Resource и используйте его для создания HTTPClient.

  3. Напишите адаптер JCA, который управляет пулом HTTPClient и передает их по мере необходимости.

Мне неясно, какой подход мне следует использовать, и игнорирую ли я какую-то службу управления HTTP-соединениями, которая уже встроена в контейнер (в данном случае TomEE plus). Как мне это сделать?


person Chris Owens    schedule 04.11.2015    source источник
comment
Я использовал PoolingHttpClientConnectionManager непосредственно в EJB (без адаптера JCA), но это был Singleton (мы используем ejb-3.1) и имеет довольно фиксированное количество подключений.   -  person matt freake    schedule 12.11.2015


Ответы (1)


Это не так просто: ни один из этих вариантов не подходит. Конкретный ответ зависит от того, является ли удаленная сторона вашего HTTP-соединения единым ресурсом или нет.

Если это один логический ресурс, то лучше всего подходит JCA. Тем не менее, вам вряд ли следует избегать каких-либо ссылок на природу HTTP в вашем адаптере: спроектируйте правильный логический интерфейс для вашей удаленной системы, а затем реализуйте адаптер ресурсов на этом интерфейсе. Ваши клиенты запрашивают нужные им данные, а затем получают их не в виде строк HTML, а в виде готовых к использованию компонентов Java. Вы сможете использовать многие преимущества, предоставляемые EJB-контейнером, не нарушая его требований.

Если вам нужна точка входа для доступа к неопределенному количеству внешних сервисов (например, индексирование поиска HTML-страниц), тогда все становится сложнее. JCA не предназначен для таких вещей, но он вполне им подходит: я поддерживаю проект TCP SocketConnector, который делает почти то же самое, и все работает как шарм. EJB здесь не подходит: пул bean-компонентов без сохранения состояния трудно контролировать, синглтоны потребуют от вас написания неблокирующей реализации пула самостоятельно, а statefuls, ну, своего рода однопоточные.

Существует также дополнительный вариант: хотя JCA будет проще интегрировать в существующую среду Java EE, реализовать адаптер ресурсов с нуля может быть сложно, если вы делаете это впервые. Здесь может пригодиться внешний инструмент HTTP-запросов, связанный с очередью JMS. JMS упрощает балансировку рабочей нагрузки, но устраняет любую интерактивность и может замедлить всю цепочку.

P.S. Для третьего варианта вашего исходного вопроса: нет необходимости реализовывать пул в JCA, поскольку контейнер уже по умолчанию поддерживает пул соединений для всех экземпляров адаптера ресурсов. Просто сохраните одно HTTP-клиентское соединение для каждого ManagedConnection JCA, и все будет работать «из коробки».

person Roman Nazarenko    schedule 13.04.2016