Статьи

Идем по пути микроуслуг — часть 3

В  первой статье  этой серии я создал простой микросервис на основе стека Spring Boot + Data JPA для отображения списка доступных продуктов в формате JSON. Во  второй части я продемонстрировал, как можно загрузить это приложение на Pivotal Cloud Foundry. В этом посте я продемонстрирую необходимые изменения для развертывания на Heroku.

Heroku

Что касается PCF, Heroku требуется локальное специальное приложение. Для Heroku это называется Toolbelt. После установки необходимо войти в свою учетную запись через набор инструментов:

heroku login

Следующим шагом является создание приложения на Heroku. Основное различие между Cloud Foundry и Heroku заключается в том, что первый использует готовые двоичные файлы, а Heroku создает их из исходного кода. Создание приложения Heroku также создаст удаленный Git-репозиторий для отправки, поскольку Heroku использует Git для управления кодом.

heroku create
Creating salty-harbor-2168... done, stack is cedar-14
https://salty-harbor-2168.herokuapp.com/ | https://git.heroku.com/salty-harbor-2168.git
Git remote heroku added

Команда  heroku create также обновляет конфигурацию .git, добавляя новый  heroku пульт. Давайте перейдем к удаленному хранилищу:

Counting objects: 21, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (21/21), 2.52 KiB | 0 bytes/s, done.
Total 21 (delta 1), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Java app detected
remote: -----> Installing OpenJDK 1.8... done
remote: -----> Installing Maven 3.3.3... done
remote: -----> Executing: mvn -B -DskipTests=true clean install
remote:        [INFO] Scanning for projects...
// Here the app is built remotely with Maven
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] BUILD SUCCESS
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] Total time: 51.955 s
remote:        [INFO] Finished at: 2015-10-03T09:13:31+00:00
remote:        [INFO] Final Memory: 32M/473M
remote:        [INFO] ------------------------------------------------------------------------
remote: -----> Discovering process types
remote:        Procfile declares types -> (none)
remote: 
remote: -----> Compressing... done, 74.8MB
remote: -----> Launching... done, v5
remote:        https://salty-harbor-2168.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy.... done.
To https://git.heroku.com/salty-harbor-2168.git
 * [new branch]      master -> master

На этом этапе нужно сказать Heroku, как запустить только что созданное приложение. Это делается через  Procfile расположенный в корне проекта. Он должен содержать подсказку Heroku о том, что мы используем веб-приложение, доступное через http (s), и стандартную командную строку Java. Кроме того, к веб-порту должна быть привязана задокументированная переменная среды Heroku:

web: java -Dserver.port=$PORT -jar target/microservice-sample.jar

Приложение еще не работает, как вам покажет журнал. Чтобы отобразить удаленный журнал, введите:

heroku logs --tail

Там должно быть что-то вроде этого:

Web process failed to bind to $PORT within 60 seconds of launch

Это намекает на то, что требуется веб-узел или, на языке Heroku, динамо. Давайте начнем один:

heroku ps:scale web=1

Приложение теперь должно работать по адресу  https://salty-harbor-2168.herokuapp.com/products  (вы должны быть терпеливы, так как это бесплатный план, приложение, вероятно, спит). И все же чего-то не хватает: он все еще работает во встроенной базе данных H2. Мы должны перейти на более устойчивую базу данных. По умолчанию Heroku предоставляет базу данных для разработки PostgreSQL бесплатно. Создание такой базы данных может быть выполнено либо через пользовательский интерфейс, либо из командной строки.

Документация Spring Boot описывает   библиотеку Spring Cloud Connectors . Он может автоматически определять, что приложение работает на Heroku, и создавать источник данных, связанный с базой данных Postgres, предоставленной Heroku. Однако, несмотря на все мои усилия, я не смог выполнить эту работу, каждый раз сталкиваясь со следующим:

org.springframework.cloud.CloudException: No unique service matching interface javax.sql.DataSource found. Expected 1, found 0

Время немного креативиться. Вместо того, чтобы анализировать базу данных и ее конфигурацию, давайте настроим ее явно. Для этого необходимо создать специальный файл свойств конфигурации профиля для Heroku  src/main/resources/application-heroku.yml:

spring:
    datasource:
        url: jdbc:postgresql://<url>
        username: <username>
        password: <password>
        driver-class-name: org.postgresql.Driver
    jpa:
        database-platform: org.hibernate.dialect.PostgreSQLDialect

Точные настройки подключения к базе данных вы можете найти в пользовательском интерфейсе Heroku. Обратите внимание, диалект, кажется, требуется. Кроме того, POM должен быть обновлен, чтобы добавить драйвер Postgres к зависимостям.

Наконец, чтобы активировать профиль на Heroku, измените его  Procfile следующим образом:

web: java -Dserver.port=$PORT -Dspring.profiles.active=heroku -jar target/microservice-sample.jar

Подтвердите и снова нажмите Heroku, приложение должно быть обновлено, чтобы использовать предоставленный Postgres.

На следующей неделе я создам новую микросервисную сумку для покупок, которая будет зависеть от этого и не будет работать.