Статьи

Развертывание загрузочного приложения Spring в Cloud Foundry с помощью Spring-Cloud

У меня есть небольшое приложение , основанное на загрузке Spring, которое использует базу данных Postgres в качестве хранилища данных.
Я хотел задокументировать действия по развертыванию этого примера приложения в Cloud Foundry . Некоторые шаги описаны в справочном руководстве по Spring Boot, однако в руководствах недостаточно разъясняется, как интегрировать хранилище данных, предоставляемое в облачной среде.
Spring-cloud обеспечивает связь между приложениями Spring, развернутыми в облаке, для обнаружения и подключения к связанным службам, поэтому первым шагом является включение библиотек Spring-cloud в проект со следующими записями pom:

01
02
03
04
05
06
07
08
09
10
11
<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>

Как только эта зависимость установлена, подключение к связанному сервису становится простым, просто определите конфигурацию по следующим направлениям:

1
2
3
4
5
6
7
8
9
@Configuration
public class PostgresCloudConfig extends AbstractCloudConfig {
 
    @Bean
    public DataSource dataSource() {
        return connectionFactory().dataSource();
    }
 
}

Spring-Cloud понимает, что приложение развертывается в определенном облаке (в настоящее время Cloud Foundry и Heroku ищут определенные характеристики развернутой платформы Cloud), обнаруживает связанные службы, распознает, что существует связанная служба, с помощью которой источник данных на основе Postgres может быть создан и возвращает источник данных как бин Spring. Это приложение теперь может быть развернуто в облаке на основе Cloud Foundry. Пример приложения можно опробовать в версии Cloud Foundry, развернутой с помощью bosh-lite. Вот как выглядят шаги на моей машине после запуска Cloud Foundry с помощью bosh-lite: Следующая команда создает службу, предоставленную пользователем, в Cloud Foundry:

1
cf create-user-provided-service psgservice -p '{"uri":"postgres://postgres:[email protected]:5432/hotelsdb"}'

Теперь нажмите приложение, но не запускайте его. Мы можем сделать это, как только вышеуказанный сервис привязан к приложению:

1
cf push spring-boot-mvc-test -p target/spring-boot-mvc-test-1.0.0-SNAPSHOT.war --no-start

Свяжите сервис с приложением и перезапустите приложение:

1
2
cf bind-service spring-boot-mvc-test psgservice
cf restart spring-boot-mvc-test

По сути, Spring Cloud в идеале должен взять на себя управление и аккуратно проанализировать учетные данные связанной службы, которая в Cloud Foundry преобразуется в переменную среды VCAP_SERVICES, и создать из нее источник данных. Однако в этом подходе есть проблема: после создания bean-компонента источника данных с использованием весенне-облачного подхода он больше не работает в локальной среде. Потенциальным решением этой проблемы является использование профилей Spring, если предположить, что в облачной среде имеется другой «облачный» профиль Spring, в который возвращается источник данных на основе облака:

1
2
3
4
5
6
7
8
9
@Profile("cloud")
@Configuration
public class PostgresCloudConfig extends AbstractCloudConfig {
 
    @Bean
    public DataSource dataSource() {
        return connectionFactory().dataSource();
    }
}

и пусть автоконфигурация Spring-boot создаст источник данных в локальной среде по умолчанию, таким образом конфигурация работает как локально, так и в облаке. Откуда этот «облачный» профиль, он может быть создан с помощью ApplicationContextInitializer и выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SampleWebApplicationInitializer implements ApplicationContextInitializer<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:

01
02
03
04
05
06
07
08
09
10
11
12
13
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

Вывод

Spring Boot вместе с проектом Spring-Cloud теперь предоставляют отличный набор инструментов для создания облачных приложений, готовых к работе на платформе Spring, и, надеюсь, эти заметки полезны при интеграции Spring Boot с Spring-Cloud и их использовании для бесшовных локальных и облачных развертываний.

Ссылка: Развертывание загрузочного приложения Spring в Cloud Foundry с Spring-Cloud от нашего партнера по JCG Биджу Кунджуммена из блога all and sundry.