Русский
Русский
English
Статистика
Реклама

Ktor

Шаблон Kotlin микросервисов

27.02.2021 20:23:19 | Автор: admin

Для разработчиков не секрет, что создание нового сервиса влечет за собой немало рутиной настройки: билд скрипты, зависимости, тесты, docker, k8s дескрипторы. Раз мы выполняем эту работу, значит текущих шаблонов IDE недосточно. Под катом мои попытки автоматизировать все до одной кроссплатформенной кнопки "сделать хорошо" сопровождаемые кодом, примерами и финальным результатом.
Если перспективы создания сервисов в один клик с последующим автоматическим деплоем в Digital Ocean звучат заманчиво, значит эта статья для вас.

Начнем создавать наш шаблон и прежде всего рассмотрим организацию сборки. Несмотря на любовь многих к maven за его простоту и декларативность, использовать будем gradle, ибо он современее и позволяет писать скрипт сборки на одном языке с проектом. Помимо самого Kotlin плагина, нам потребуется еще два:

plugins {  kotlin("jvm") version "1.4.30"  // Чтобы собрать fat jar  id("com.github.johnrengelman.shadow") version "6.1.0"  // Чтобы собрать self-executable приложение с jvm  id("org.beryx.runtime") version "1.12.1"}

Из зависимостей, в качестве серверного фреймворка был выбран "родной" для Kotlin Ktor. Для тестирования используется связка testNG + Hamkrest с его выразительным DSL, позволяющим писать тесты таким образом:

assertThat("xyzzy", startsWith("x") and endsWith("y") and !containsSubstring("a"))

Собираем все вместе, ориентируясь на Java 15+

dependencies {  // для парсинга аргументов командой строки  implementation("com.github.ajalt.clikt:clikt:3.1.0")  implementation("io.ktor:ktor-server-netty:1.5.1")  testImplementation("org.testng:testng:7.3.0")  testImplementation("com.natpryce:hamkrest:1.8.0.1")  testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")}application {  @Suppress("DEPRECATION") // for compatibility with shadowJar  mainClassName = "AppKt"}tasks {  test {    useTestNG()  }  compileKotlin {    kotlinOptions {      jvmTarget = "15"    }  }}

В исходный код генерируемый шаблоном по умолчанию добавлен entry-point обработки аргументов командой строки, заготовка ддя роутинга, и простой тест (заодно служащий примером использоования testNG с Hamkrest).
Из того что следует отметить, позволил себе небольшую вольность с официальным Kotlin codestyle чуть-чуть поправив его в .editorsconfig:

[*.{kt, kts, java, xml, html, js}]max_line_length = 120indent_size = 2continuation_indent_size = 2

В первую очередь, это вопрос вкуса, но ещё так в одну строчку помещается больше кода, что помогает избежать переноса в выражениях внутри класса и функции, лямбды, например.
Чтобы собрать self-executable jar используйте команду

gradle clean test shadowJar

На этом этапе приложение уже можно использовать, запуская традиционным образом.

Осталось написать Dockerfile, его привожу целиком. Сборка и запуск разделены и производятся в два этапа:

# syntax = docker/dockerfile:experimentalFROM gradle:jdk15 as builderWORKDIR /appCOPY src ./srcCOPY build.gradle.kts ./build.gradle.ktsRUN --mount=type=cache,target=./.gradle gradle clean test shadowJarFROM openjdk:15-alpine as backendWORKDIR /rootCOPY --from=builder /app/*.jar ./app

Работать сервис будет в контейнере с jdk (а не jvm), ради простоты ручной диагностики с помощью jstack/jmap и других поставляемых с jdk инструментов.
Сконфигурируем запуск приложения при помощи Docker Compose:

version: "3.9"services:  backend:    build: .    command: java -jar app $BACKEND_OPTIONS    ports:      - "80:80"

Теперь мы можем запускать наш сервис на целевой машине, без дополнительных зависимостей в виде Jdk/Gradle, при помощи простой команды

docker-compose up

Как деплоить сервис в облако? Выбрал Digital Ocean по причине дешевой стоимости и простоты управления. Благодаря тому что мы только что сконфигурировали сборку и запуск в контейнере, можно выбрать наш репозиторий с проектом в разделе Apps Platform и... все! Файлы конфигурации Docker будут подцеплены автоматически, мы увидим логи сборки, а после этого получим доступ к веб адресу, логам приложения, консоли управления, простым метрикам потребления памяти и процессорного времени. Выглядит это удовольствие примерно так и стоит 5$ в месяц:

При последующих изменениях в master ветке репозитория, передеплой запустится автоматически. Очень удобно. И наконец, все описанное в статье, подробно задокументировано в README.md файле шаблона проекта, чтобы после создания последующая сборка и деплой не вызывали сложностей.

Исползьовать описаный шаблон чтобы получить готовый репозиторий, можно просто нажав кнопочку "Use this template"на GitHub:
github.com/demidko/Projekt

Или, если вам нужен варинт с портабельным jvm:
github.com/demidko/Projekt-portable

Интересно услышать предложения, комментарии и критику.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru