Статьи

Подходы к привязке приложения Spring Boot к службе в Cloud Foundry

Если вы хотите попробовать Cloud Foundry, самый простой способ сделать это — загрузить отличную версию PCF Dev или создать пробную учетную запись на сайте Pivotal Web Services .

В оставшейся части поста предполагается, что у вас есть доступная установка Cloud Foundry и что вы хорошо понимаете Cloud Foundry. Цель этого поста — перечислить опции, которые есть у вас при интеграции Java-приложения с экземпляром сервиса — в этом демонстрационном примере MySQL используется как пример сервиса для интеграции, но этот подход достаточно универсален.

Обзор приложения

Приложение представляет собой довольно простое приложение Spring-Boot , это REST-сервис, отображающий три типа доменов и их взаимоотношения, представляющий университет — курс, преподаватель и студент. Экземпляры домена сохраняются в базе данных MySQL. Весь исходный код и подходы доступны в этом месте Github, если вы хотите забегать вперед.

Чтобы попробовать приложение локально, сначала установите локальную базу данных сервера mysql, на компьютере Mac OSX с доступным homebrew можно выполнить следующий набор команд:

1
2
3
4
5
6
7
8
9
brew install mysql
 
mysql.server start
mysql -u root
# on the mysql prompt:
 
CREATE USER 'univadmin'@'localhost' IDENTIFIED BY 'univadmin';
CREATE DATABASE univdb;
GRANT ALL ON univdb.* TO 'univadmin'@'localhost';

Откройте Spring-Boot в cf-db-services-sample-auto:

1
mvn spring-boot:run

и конечная точка с образцами данных будет доступна по адресу http: // localhost: 8080 / courses.

Попробуйте это приложение на Cloud Foundry

Если у вас установлена PCF Dev, работающая локально, вы можете попробовать развертывание приложения следующим образом:

1
2
cf api api.local.pcfdev.io --skip-ssl-validation
cf login # login with admin/admin credentials

Создайте экземпляр службы Mysql:

1
cf create-service p-mysql 512mb mydb

и нажмите приложение! (manifest.yml обеспечивает привязку приложения к экземпляру службы)

1
cf push

Конечная точка должна быть доступна по адресу http://cf-db-services-sample-auto.local.pcfdev.io/courses

Подходы к подключению услуг

Теперь, когда у нас есть приложение, которое работает локально и на примере локального Cloud Foundry, это подходы к подключению к экземпляру службы.

Подход 1 — Ничего не делать, пусть сборка Java обрабатывает детали подключения

Этот подход продемонстрирован в проекте cf-db-services-sample-auto . Здесь подключение к локальной базе данных было указано с помощью Spring Boot и выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
---
 
spring:
  jpa:
    show-sql: true
    hibernate.ddl-auto: none
    database: MYSQL
 
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost/univdb?autoReconnect=true&useSSL=false
    username: univadmin
    password: univadmin

Когда это приложение передается в Cloud Foundry с использованием Java Buildpack , в приложение внедряется компонент, называемый java-buildpack-auto -configuration, который перенастраивает подключение к службе на основе привязки службы времени выполнения.

Подход 2. Отключите автоматическую реконфигурацию и используйте свойства времени выполнения.

Этот подход продемонстрирован в проекте cf-db-services-sample-props . Когда служба связана с приложением, в приложение вводится набор свойств среды под ключом «VCAP_SERVICES». Для этого конкретного сервиса запись выглядит примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"VCAP_SERVICES": {
  "p-mysql": [
   {
    "credentials": {
     "hostname": "mysql.local.pcfdev.io",
     "jdbcUrl": "jdbc:mysql://mysql.local.pcfdev.io:3306/cf_456d9e1e_e31e_43bc_8e94_f8793dffdad5?user=**\u0026password=***",
     "name": "cf_456d9e1e_e31e_43bc_8e94_f8793dffdad5",
     "password": "***",
     "port": 3306,
     "uri": "mysql://***:***@mysql.local.pcfdev.io:3306/cf_456d9e1e_e31e_43bc_8e94_f8793dffdad5?reconnect=true",
     "username": "***"
    },
    "label": "p-mysql",
    "name": "mydb",
    "plan": "512mb",
    "provider": null,
    "syslog_drain_url": null,
    "tags": [
     "mysql"
    ]
   }
  ]
 }

Необработанный json немного неудобен для использования, однако Spring Boot автоматически преобразует эти данные в плоский набор свойств, который выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
"vcap.services.mydb.plan": "512mb",
"vcap.services.mydb.credentials.username": "******",
"vcap.services.mydb.credentials.port": "******",
"vcap.services.mydb.credentials.jdbcUrl": "******",
"vcap.services.mydb.credentials.hostname": "******",
"vcap.services.mydb.tags[0]": "mysql",
"vcap.services.mydb.credentials.uri": "******",
"vcap.services.mydb.tags": "mysql",
"vcap.services.mydb.credentials.name": "******",
"vcap.services.mydb.label": "p-mysql",
"vcap.services.mydb.syslog_drain_url": "",
"vcap.services.mydb.provider": "",
"vcap.services.mydb.credentials.password": "******",
"vcap.services.mydb.name": "mydb",

Учитывая это, подключение к базе данных может быть указано в приложении Spring Boot следующим образом — в файле application.yml:

1
2
3
4
5
spring:
  datasource:
    url: ${vcap.services.mydb.credentials.jdbcUrl}
    username: ${vcap.services.mydb.credentials.username}
    password: ${vcap.services.mydb.credentials.password}

Одна небольшая уловка заключается в том, что, поскольку я теперь явно беру на себя управление указанием возможности подключения службы, необходимо отключить динамическую реконфигурацию java-buildpack-auto, что можно сделать с помощью метаданных манифеста:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
---
applications:
  - name: cf-db-services-sample-props
    path: target/cf-db-services-sample-props-1.0.0.RELEASE.jar
    memory: 512M
    env:
      JAVA_OPTS: -Djava.security.egd=file:/dev/./urandom
      SPRING_PROFILES_ACTIVE: cloud
    services:
      - mydb
 
buildpack: https://github.com/cloudfoundry/java-buildpack.git
 
env:
    JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}'

Подход 3 — Использование Spring Cloud Connectors

Третий подход состоит в том, чтобы использовать отличный проект Spring Cloud Connectors, и конфигурация, которая определяет подключение службы, выглядит следующим образом и демонстрируется в подпроекте cf-db-services-sample-connector :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Configuration
@Profile("cloud")
public  class CloudFoundryDatabaseConfig {
 
    @Bean
    public Cloud cloud() {
        return new CloudFactory().getCloud();
    }
 
    @Bean
    public DataSource dataSource() {
        DataSource dataSource = cloud().getServiceConnector("mydb", DataSource.class, null);
        return dataSource;
    }
}

Плюсы и минусы

Вот плюсы и минусы каждого из этих подходов:

подходы Pros Cons
Подход 1 — Пусть Buildpack справится с этим 1. Простое, приложение, которое работает локально, будет работать без каких-либо изменений в облаке 1. Волшебный — автоматическая реконфигурация может показаться волшебной для того, кто не понимает основной поток
2. Количество поддерживаемых типов услуг довольно ограничено —
скажем, например, если подключение к Cassandra требуется, то автоматическая реконфигурация не будет работать
Подход 2 — явные свойства 1. Довольно просто.
2. Следует подходу Spring Boot и использует некоторые из лучших практик приложений, основанных на загрузке — например, существует определенный порядок, в котором создаются пулы соединений с источниками данных, и все эти лучшие практики просто используются в этом подходе.
1. Авто-реконфигурация должна быть явно отключена
2. Необходимо знать, как выглядят сплющенные свойства
3. «Облачный» профиль, возможно, придется вводить вручную через свойства среды, чтобы различать локальную разработку и развертывание облака
4. Сложно инкапсулировать возможность повторного использования подключения к новым типам услуг, например, Cassandra или DynamoDB.
Подход 3 — Spring Cloud Connectors 1. Простота интеграции
2. Легко добавить в многократную интеграцию с новыми типами услуг
1. Обходит оптимизацию логики пула соединений Spring Boot.

Вывод

Лично я предпочитаю использовать подход 2, так как он наиболее точно соответствует настройкам Spring Boot, не выдерживая минусов подхода. Если требуется более сложное подключение к услуге, я, скорее всего, воспользуюсь подходом 3. Хотя ваш пробег может отличаться

использованная литература

1. Весенняя музыка Скотта Фредерика была постоянным проводником.

2. Я щедро позаимствовал у образца Бена Хейла pong_matcher_spring .

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