Статьи

Wiring-in-the-Large: недостающая технология для облачных приложений Java

Задумывались ли вы, почему внедрение зависимостей в большинстве сред Java используется только для локальных внутрипроцессных сервисов, а не для распределенных?

Недавно я познакомился с основным докладом Пола Марица   (перейдите к 32-й минуте) на конференции EMC World 2013, которая заставила меня задуматься над этим вопросом в контексте облачных платформ. Основной доклад — отличное и продуманное заявление о том, как  Pivtol  позиционирует себя на развивающемся рынке облачных платформ. Один из его наиболее интересных моментов заключается в том, что с распространением мобильных и взаимосвязанных устройств (часто называемых  Интернетом вещей ) мы видим появление нового класса приложений, которые принимают, обрабатывают и распространяют большие объемы данных.

Мариц подчеркивает свою речь некоторыми полезными эпизодическими данными: один трансатлантический полет дает почти 30 ТБ данных, которые необходимо записать, обработать и проанализировать с помощью нового типа приложений. 

Облачные Ткани

Эти типы приложений не могут быть эффективно построены на традиционных архитектурах сервера приложений Java EE. Вместо этого они будут работать на  облачных структурах : динамической, взаимосвязанной инфраструктуре, которая легко адаптируется.

Динамическая природа облачных структур предъявляет новые требования к существующим средам и контейнерам Java. Например, экземпляры виртуальных машин могут быть созданы или перенесены для удовлетворения повышенного спроса. В этом случае адреса компьютеров (и, следовательно, конечных точек обслуживания) могут изменяться. Это затрудняет управление и масштабирование статических архитектур, часто связанных с кластерами серверов приложений Java EE и брокерами сообщений.

Облачные структуры построены на аппаратной виртуализации, где физические ресурсы компьютера извлекаются с помощью программного обеспечения. Виртуализация должна быть расширена в стеке до моделей программирования Java, чтобы приложения могли работать более эффективно.

Весна: пионер виртуализации сервисов

Весна была пионером в этом отношении. Он виртуализировал многие части сервера приложений Java EE, заменив API-интерфейсы контейнеров для получения ссылок на локальные службы (JNDI) путем внедрения зависимостей. Это позволило запустить код приложения Spring вне контейнера Java EE, например, в модульных тестах. 

По мере того, как облачные фабрики получат распространение, мы увидим необходимость расширить возможности Spring по распределению проводов для распределенных сервисов — проводка в целом. Точно так же, как приложениям не нужны API-интерфейсы контейнеров для получения ссылок на локальные сервисы, им не нужны API-интерфейсы для вызова удаленных сервисов или отправки сообщений на конечные точки. Если вместо этого удаленные службы подключены к коду приложения, инфраструктура фабрики может прозрачно распространять изменения адреса конечной точки при миграции или создании виртуальных машин в ответ на изменяющуюся рабочую нагрузку:

Дополнительным преимуществом проводной связи в целом является  виртуализация связи  .  Код приложения больше не использует специфичные для транспорта API для отправки сообщений или вызова удаленных служб. Вместо этого облачная структура отвечает за внедрение кода с прокси-серверами, которые управляют связью:

Это позволит облачной фабрике принять и настроить наиболее подходящую технологию обмена сообщениями, не требуя изменений на уровне кода. В дополнение к значительному упрощению кода виртуализация связи также позволяет создавать более переносимые облачные приложения.

Проводка в целом на практике

Так как же выглядит проводка в целом на практике? Хорошо, что многие из его концепций предшествуют появлению современных облачных вычислений. Стандарты  OASIS SCA  дают нам простой и знакомый способ подключения удаленных сервисов, которые хорошо сочетаются с облачными структурами:

<composite name="LoanComposite" ...>
  
  <component name="Client">
    <implementation.java class="org.fabric3.sample.client.ClientImpl"/>
    <reference name="service" target="Service"/> 
  </component>
  
  <component name="Service">
    <implementation.java class="org.fabric3.sample.service.ServiceImpl"/>
  </component>
   
  
</composite>

Вышеуказанные сервисы могут быть подключены через JMS, ZeroMQ, AMQP, MQTT или через какую-либо другую коммуникационную технологию — выбор конфигурации зависит либо от времени выполнения SCA, либо от конфигурации развертывания. Код приложения будет выглядеть так же:

public class ClientImpl implements Client {
  
  @Reference
  protected Service service;
  
  public void doSomething() {
    Message message = ...
    service.send(message);   
  }
  
}

Среда выполнения Fabric3 (соответствующая реализация SCA) обеспечивает прозрачное динамическое распространение в конечной точке, как мы обсуждали выше.

Что дальше?

Поддержка Fabric3 для проводного соединения в целом в настоящее время требует развертывания приложений в контейнере Fabric3. Сообщество Fabric3 работает над устранением этого ограничения, чтобы облачные сервисы могли быть доступны повсеместно — буквально из любой среды исполнения JVM или Java. Вот пример:

Fabric fabric = Bootstrap.initialize();
fabric.start();
 
Domain domain = fabric.getDomain();
 
Service service = domain.getService(Service.class);
Message message = ... 
service.send(message);
 
fabric.stop();

Этот API может быть интегрирован в такие среды, как Spring и Guice, чтобы обеспечить прозрачное внедрение удаленных сервисов. По сути, коду приложения больше не нужно иметь дело с конкретными транспортными API, а в случае Spring — с шаблонами.

Возвращаясь к картине Maritz о приложениях следующего поколения, которые в массовом масштабе потребляют, обрабатывают и распространяют данные, мы надеемся, что проводное соединение в целом будет играть ту же модернизационную роль, которую внедрение локальной зависимости сделало для Java EE в корпоративном центре обработки данных. Если вы хотите узнать больше об искусстве возможного, проверьте  Fabric3