У меня есть небольшое приложение , основанное на загрузке Spring, которое использует базу данных Postgres в качестве хранилища данных. Я хотел задокументировать действия по развертыванию этого примера приложения в Cloud Foundry . Некоторые из шагов описаны в справочном руководстве по Spring Boot, однако в руководствах недостаточно разъясняется, как интегрироваться с хранилищем данных, предоставляемым в облачной среде. Spring-cloud обеспечивает связь между приложениями Spring, развернутыми в облаке, для обнаружения и подключения к связанным службам, поэтому первым шагом является включение библиотек Spring-cloud в проект со следующими записями pom:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-spring-service-connector</artifactId> <version>1.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-cloudfoundry-connector</artifactId> <version>1.0.0.RELEASE</version> </dependency>
Как только эта зависимость установлена, подключение к связанному сервису становится простым, просто определите конфигурацию по следующим направлениям:
@Configuration public class PostgresCloudConfig extends AbstractCloudConfig { @Bean public DataSource dataSource() { return connectionFactory().dataSource(); } }
Это приложение теперь может быть развернуто в облаке на основе Cloud Foundry. Пример приложения может быть опробованы в версии Cloud Foundry развернуты с заплечиков-лайт , это как шаги в моей машине выглядит как раз Cloud Foundry это и работает с заплечиков-лайт:
Следующая команда создает при условии пользователя службы в Cloud Foundry:
cf create-user-provided-service psgservice -p '{"uri":"postgres://postgres:[email protected]:5432/hotelsdb"}'
cf push spring-boot-mvc-test -p target/spring-boot-mvc-test-1.0.0-SNAPSHOT.war --no-start
Свяжите сервис с приложением и перезапустите приложение:
cf bind-service spring-boot-mvc-test psgservice cf restart spring-boot-mvc-test
По сути, Spring Cloud в идеале должен взять на себя управление и аккуратно проанализировать учетные данные связанной службы, которая в Cloud Foundry преобразуется в переменную среды VCAP_SERVICES, и создать из нее источник данных.
Однако в этом подходе есть проблема: после создания bean-компонента источника данных с использованием весенне-облачного подхода он больше не работает в локальной среде.
Потенциальным решением этой проблемы является использование профилей Spring, если предположить, что в облачной среде имеется другой «облачный» профиль Spring, в который возвращается источник данных на основе облака:
@Profile("cloud") @Configuration public class PostgresCloudConfig extends AbstractCloudConfig { @Bean public DataSource dataSource() { return connectionFactory().dataSource(); } }
и пусть автоконфигурация Spring-boot создаст источник данных в локальной среде по умолчанию, таким образом, конфигурация работает как локально, так и в облаке. Откуда этот «облачный» профиль, он может быть создан с помощью ApplicationContextInitializer и выглядит следующим образом:
public class SampleWebApplicationInitializer implementsApplicationContextInitializer<AnnotationConfigEmbeddedWebApplicationContext> { private static final Log logger = LogFactory.getLog(SampleWebApplicationInitializer.class); @Override public void initialize(AnnotationConfigEmbeddedWebApplicationContext applicationContext) { Cloud cloud = getCloud(); ConfigurableEnvironment appEnvironment = applicationContext.getEnvironment(); if (cloud!=null) { appEnvironment.addActiveProfile("cloud"); } logger.info("Cloud profile active"); } private Cloud getCloud() { try { CloudFactory cloudFactory = new CloudFactory(); return cloudFactory.getCloud(); } catch (CloudException ce) { return null; } } }
Этот инициализатор использует возможности сканирования Spring-cloud для активации «облачного» профиля.
И последнее, что я хотел попробовать, — это заставить мой локальный объект вести себя как облако по крайней мере в глазах Spring-Cloud, и это можно сделать, добавив некоторые переменные окружения, с помощью которых Spring-Cloud определяет тип облака, в котором приложение развернуто, ниже приведен мой сценарий запуска на локальном компьютере, чтобы приложение притворилось, будто оно развернуто в Cloud Foundry:
read -r -d '' VCAP_APPLICATION <<'ENDOFVAR' {"application_version":"1","application_name":"spring-boot-mvc-test","application_uris":[""],"version":"1.0","name":"spring-boot-mvc-test","instance_id":"abcd","instance_index":0,"host":"0.0.0.0","port":61008} ENDOFVAR export VCAP_APPLICATION=$VCAP_APPLICATION read -r -d '' VCAP_SERVICES <<'ENDOFVAR' {"postgres":[{"name":"psgservice","label":"postgresql","tags":["postgresql"],"plan":"Standard","credentials":{"uri":"postgres://postgres:[email protected]:5432/hotelsdb"}}]} ENDOFVAR export VCAP_SERVICES=$VCAP_SERVICES mvn spring-boot:run
Весь этот образец доступен в этом GitHub месте: https://github.com/bijukunjummen/spring-boot-mvc-test
Вывод
Spring Boot вместе с проектом Spring-Cloud теперь предоставляют отличный набор инструментов для создания облачных приложений, готовых к работе на платформе Spring, и, надеюсь, эти заметки полезны для интеграции Spring Boot с Spring-Cloud и использования их для бесшовных локальных и облачных развертываний.