Начало работы с Heroku на языке Java

Облака – популярная штука, ворвавшаяся и в сферу хостинга. Скажем НЕТ DevOps-ам! Будем сами себе DevOps-ами и поработаем с Heroku на языке Java.

Heroku – очень крутая штука! Тебе не нужно заморачиваться с настройкой железа, балансирования, маршрутизации и прочими радостями воздвижения нового сервиса, т. к. все за тебя сделали (и будут делать) разработчики. Тебе дается уже готовый сервак – бери и ваяй свое приложение.

☕ Подтянуть свои знания по Java вы можете на нашем телеграм-канале «Библиотека Java для собеса»

Самое начало

Это руководство поможет развернуть Java-приложение за считанные минуты.

Предполагается, что у тебя уже:

  • есть бесплатный аккаунт Heroku;
  • установлена Java 8;
  • установлен Maven 3.

Если ты больше любишь Gradle, то тебе в раздел официального хелпа.

Установка

Для Heroku CLI требуется система контроля версий Git. Если она у тебя еще не установлена, выполни следующие действия:

CLI используется для управления и масштабирования приложений, подготовки модулей, просмотра журналов и т. д.

Загрузи и запусти нужный установщик: Mac, Win32, Win64, Linux (sudo snap install heroku --classic).

После установки уже можно вводить команды с помощью директивы heroku в любимом терминале.

Используй команду heroku login для входа в Heroku CLI (может ругнуться фаервол – все разрешаем):

$ heroku login
heroku: Press any key to open up the browser to login or q to exit
 ›   Warning: If browser does not open, visit
 ›   https://cli-auth.heroku.com/auth/browser/***
heroku: Waiting for login...
Logging in... done
Logged in as me@example.com

Эта команда откроет страницу Heroku – нажми там кнопку Войти.

Аутентификация требуется для правильной связки heroku и git.

🧩☕ Интересные задачи по Java для практики можно найти на нашем телеграм-канале «Библиотека задач по Java»

Подготовка приложения

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

$ git clone https://github.com/heroku/java-getting-started
$ cd java-getting-started

Теперь у тебя есть рабочий репозиторий. Приложение включает в себя файл pom.xml, используемый менеджером Maven.

Развертывание приложения

На этом шаге ты развернешь приложение в Heroku.

Первым делом подготовим Heroku к получению исходного кода:

$ heroku create
Creating app... done, floating-ocean-97551
https://floating-ocean-97551.herokuapp.com/ | https://git.heroku.com/floating-ocean-97551.git

На этом шаге создается удаленный репозиторий (с именем heroku) и связывается с локальным.

По дефолту Heroku генерирует случайное имя для приложения, но можно указать и свое.

Теперь давай развернем код:

$ git push heroku master
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Java app detected
remote: -----> Installing JDK 1.8... done
remote: -----> Executing: ./mvnw -DskipTests clean dependency:list install
...
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] BUILD SUCCESS
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] Total time:  15.870 s
remote:        [INFO] Finished at: 2019-07-08T22:42:35Z
remote:        [INFO] ------------------------------------------------------------------------
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 70M
remote: -----> Launching...
remote:        Released v5
remote:        https://floating-ocean-97551.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/floating-ocean-97551.git
 * [new branch]      master -> master

Готово. Убедись, что хотя бы один экземпляр приложения запущен:

$ heroku ps:scale web=1

Теперь перейди в приложение по ссылке, созданной из его имени, или поступи следующим образом:

$ heroku open

Логи

Heroku собирает события со всех выходных потоков приложения и компонентов платформы в единый журнал, упорядоченный по времени.

Чтобы посмотреть логи запущенного приложения, воспользуйся командой heroku logs --tail:

heroku logs --tail
2019-07-08T22:43:04.169634+00:00 app[web.1]: 2019-07-08 22:43:04.169  INFO 4 --- [io-28914-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-07-08T22:43:04.169767+00:00 app[web.1]: 2019-07-08 22:43:04.169  INFO 4 --- [io-28914-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-07-08T22:43:04.180097+00:00 app[web.1]: 2019-07-08 22:43:04.179  INFO 4 --- [io-28914-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 10 ms

Объявление Procfile

Heroku использует специальный текстовый файл Procfile (мини-конфиг) для явного указания директив запуска приложения.

Procfile в развернутом приложении выглядит примерно так:

web: java -jar target/java-getting-started-1.0.jar

Здесь объявляется тип процесса web и команда, необходимая для его запуска. Web указывает на то, что этот тип процесса будет прикреплен к стеку маршрутизации Heroku для получения трафика.

Масштабирование приложения

Сейчас приложение работает на одном dyno-процессе. Dyno – это легковесный контейнер Linux, запускаемый по команде из Procfile.

Проверить, сколько dyno сейчас запущено, можно так:

$ heroku ps
Free dyno hours quota remaining this month: 987h 28m (98%)
Free dyno usage for this app: 0h 0m (0%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

=== web (Free): java -jar target/java-getting-started-1.0.jar (1)
web.1: up 2019/07/08 17:42:57 -0500 (~ 7s ago)

По умолчанию приложение деплоится в свободном dyno. Свободными они становятся (засыпают) после тридцати минут бездействия (т. е. если они не получают никакого трафика). Это поведение вызывает задержку в несколько секунд при первом запросе “пробуждения”. Последующие запросы будут выполняться нормально.

Чтобы избежать спящего режима dyno, можно обновить тип dyno на хобби или профи. Например, если ты мигрируешь свое приложение на профи уровень, можно легко масштабировать его, попросив Heroku подготовить определенное количество dyno.

Масштабирование приложения в Heroku эквивалентно изменению количества запущенных dyno.

Установить ненулевое количество веб dyno можно так:

$ heroku ps:scale web=1

Объявление зависимостей

Heroku автоматически определяет Java-приложение, если оно содержит файлик pom.xml в корневом каталоге. Ты можешь создать pom.xml для других приложений с помощью команды mvn archetype: create.

В развернутой демке приложения уже имеется pom.xml с такой начинкой:

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

В этом файлике указаны зависимости, требуемые для работы приложения. При развертывании Heroku прочитает файл и все установит, запустив mvn clean install.

В папке есть еще один файл, system.properties, указывающий на версию Java. Содержимое этого необязательного файла ниже:

java.runtime.version=1.8

Запусти mvn clean install в локальном каталоге, чтобы установить зависимости и подготовить систему к локальному запуску приложения. Обрати внимание, что приложению требуется Java 8, но ты можешь запушить другие приложения с поддержкой другой версии Java.

$ mvn clean install
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.266 s
[INFO] Finished at: 2019-07-08T17:43:29-05:00
[INFO] Final Memory: 37M/331M
[INFO] ------------------------------------------------------------------------

Если Maven не установлен или появляется ошибка, например, mvn is not recognized as an internal or external command, используй команду-обертку: запустив mvnw clean install на Windows или ./ mvnw clean install на Mac и Linux. Это одновременно устанавливает и запускает Maven.

Процесс Maven скомпилит и создаст JAR с зависимостями, помещая его в корневой каталог приложения. Этим процессом рулит spring-boot-maven-plugin из pom.xml.

Если ты не юзаешь Spring в pom.xml, можно указать иной плагин:


  

Локальный запуск приложения

Запусти приложение с помощью команды heroku:

$ heroku local web
...
7:06:33 PM web.1 |  2019-04-04 19:06:33.539  INFO 97226 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
7:06:33 PM web.1 |  2019-04-04 19:06:33.783  INFO 97226 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page template: index
7:06:33 PM web.1 |  2019-04-04 19:06:33.949  INFO 97226 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
7:06:34 PM web.1 |  2019-04-04 19:06:34.047  INFO 97226 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 5000 (http) with context path ''

Открой в браузере http://localhost:5000 – ты должен увидеть свое приложение.

Для остановки приложения вернись в окно терминала и нажми CTRL+C.

Внесение локальных изменений

На этом шаге ты узнаешь, как внести локальные изменения и развернуть их в Heroku. В качестве примера мы добавим зависимость и некоторый код.

Измени pom.xml, добавив зависимости для jscience в блок dependencies:

В 28 строке добавь:

<dependency>
  <groupId>org.jscience</groupId>
  <artifactId>jscience</artifactId>
  <version>4.3.1</version>
</dependency>

Теперь добавь следующие объекты в 19 строку файла src/main/java/com/example/Main.java:

import static javax.measure.unit.SI.KILOGRAM;
import javax.measure.quantity.Mass;
import org.jscience.physics.model.RelativisticModel;
import org.jscience.physics.amount.Amount;

Добавь метод hello в 59 строку src/main/java/com/example/Main.java:

@RequestMapping("/hello")
String hello(Map<String, Object> model) {
    RelativisticModel.select();
    Amount<Mass> m = Amount.valueOf("12 GeV").to(KILOGRAM);
    model.put("science", "E=mc^2: 12 GeV = " + m.toString());
    return "hello";
}

Создай src/main/resources/templates/hello.html с таким содержимым:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body},'hello')}">
<body>
  <div class="container">
    <p th:text="${science}"/>
  </div>
</body>
</html>

Проверь изменения:

$ mvn clean install
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.400 s
[INFO] Finished at: 2019-07-08T17:43:38-05:00
[INFO] Final Memory: 37M/328M
[INFO] ------------------------------------------------------------------------
$ heroku local web
...
5:43:53 PM web.1 |  2019-07-08 17:43:53.079  INFO 39652 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
5:43:53 PM web.1 |  2019-07-08 17:43:53.693  INFO 39652 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page template: index
5:43:54 PM web.1 |  2019-07-08 17:43:54.097  INFO 39652 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
5:43:54 PM web.1 |  2019-07-08 17:43:54.321  INFO 39652 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 5000 (http) with context path ''

По адресу http://localhost:5000/hello ты должен увидеть следующее:

E=mc^2: 12 GeV = (2.139194076302506E-26 ± 1.4E-42) kg

Можно деплоить:

$ git add .
$ git commit -m "Demo"
$ git push heroku master
$ heroku open hello

Использование БД

Heroku предоставляет поддержку Postgres, Redis, MongoDB и MySQL.

На этом шаге ты узнаешь о дополнении Heroku Postgres, поставляемом при развертывании всех приложений Java.

Heroku Postgres сама по себе является надстройкой, поэтому для обзора БД можно использовать команду heroku addons:

heroku addons

Add-on                                         Plan       Price  State
─────────────────────────────────────────────  ─────────  ─────  ───────
heroku-postgresql (postgresql-slippery-51080)  hobby-dev  free   created
 └─ as DATABASE

papertrail (papertrail-concentric-67589)       choklad    free   created
 └─ as PAPERTRAIL

The table above shows add-ons and the attachments to the current app (floating-ocean-97551) or other apps.

Чтобы узнать DATABASE_URL, используется команда:

$ heroku config
=== floating-ocean-97551 Config Vars
DATABASE_URL:         postgres://kwzrfqexkujliv:3581c21827af4db24c7cfcf0876bd9edf42c7ec3b5bb289fb1253c8089a328d3@ec2-54-243-47-196.compute-1.amazonaws.com:5432/dfdjtejhj2mtcr
ENERGY:               20 GeV
PAPERTRAIL_API_TOKEN: D8ZHH05QpTlY5R8oFHJ

Команда heroku pg предоставляет более подробную информацию о БД:

$ heroku pg
=== DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           10/20
PG Version:            11.3
Created:               2019-07-08 22:42 UTC
Data Size:             7.7 MB
Tables:                0
Rows:                  0/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-slippery-51080

Дальнейшие действия

Вот инфа для изучения, чтобы продолжить свое путешествие с Heroku:

  • как работает Heroku – дополнительные материалы по настройке, развертыванию и запуску;
  • категория Java предоставляет более подробную информацию о развертывании Java- приложений;
  • категория развертывание предоставляет множество фич для упрощения развертывания.

Ты уже испытал Heroku? Как тебе?

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
11 января 2019

ТОП-10 лучших книг по Java для программистов

Не имеет значения, хотите вы улучшить скилл или только собираетесь начать и...
Библиотека программиста
12 июля 2017

Что такое Docker, и как его использовать? Подробно рассказываем

Разберем по косточкам, ведь Docker – это мощный инструмент, и огромное коли...
admin
05 апреля 2017

6 книг по Java для программистов любого уровня

Подборка материалов по Java. Если вы изучаете его, то обязательно найдете д...