Serverless функции на Kotlin: AWS Lambda от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в Serverless функции на Kotlin с AWS Lambda

Serverless-архитектура стремительно набирает популярность благодаря своей масштабируемости, экономичности и простоте развертывания. AWS Lambda — один из ведущих сервисов для запуска бессерверных функций, и хотя чаще всего его ассоциируют с JavaScript, Python или Java, язык Kotlin также отлично подходит для этой задачи. Благодаря полной совместимости с JVM и лаконичному синтаксису, Kotlin позволяет писать чистый, безопасный и производительный код для облачных функций.

В этой статье мы пройдем путь от создания простейшей Lambda-функции на Kotlin до ее деплоя, тестирования и мониторинга в AWS. Вы узнаете, как настроить проект с Gradle, обрабатывать события API Gateway, работать с AWS SDK и оптимизировать холодный старт.

Основы: создание первой Lambda-функции на Kotlin

Настройка проекта и зависимости

Для начала создадим новый Gradle-проект. Убедитесь, что у вас установлены JDK 11+ и Gradle 7+. В файле build.gradle.kts подключим необходимые зависимости:

plugins {
    kotlin("jvm") version "1.9.22"
    id("io.github.justinhj.kotlin-lambda") version "0.2.0"
}

dependencies {
    implementation("com.amazonaws:aws-lambda-java-core:1.2.3")
    implementation("com.amazonaws:aws-lambda-java-events:3.11.4")
    implementation("com.google.code.gson:gson:2.10.1")
}

tasks.withType {
    archiveFileName.set("lambda-function.zip")
}

Плагин kotlin-lambda упрощает сборку и деплой, а библиотеки aws-lambda-java-core и aws-lambda-java-events предоставляют интерфейсы для обработчиков и событий.

Простейший обработчик

Создадим класс HelloHandler, который реализует интерфейс RequestHandler:

import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler

class HelloHandler : RequestHandler {
    override fun handleRequest(input: Map<String, String>, context: Context): String {
        val name = input["name"] ?: "World"
        context.logger.log("Processing request for $name")
        return "Hello, $name! Ваша функция на Kotlin работает!"
    }
}

Этот обработчик принимает JSON-объект с полем name и возвращает приветствие. Для деплоя соберите проект командой ./gradlew buildZip и загрузите полученный JAR в консоль AWS Lambda.

Продвинутые сценарии: работа с событиями и AWS SDK

Обработка событий API Gateway

Часто Lambda используется как бэкенд для REST API. Для этого потребуется обрабатывать формат событий API Gateway. Создадим класс ApiGatewayHandler:

import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent

class ApiGatewayHandler : RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    override fun handleRequest(request: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent {
        val response = APIGatewayProxyResponseEvent()
        val body = """
            {
                "message": "Привет от Kotlin Lambda!",
                "method": "${request.httpMethod}",
                "path": "${request.path}"
            }
        """.trimIndent()
        response.statusCode = 200
        response.body = body
        response.headers = mapOf("Content-Type" to "application/json")
        return response
    }
}

Теперь ваша функция может отвечать на HTTP-запросы, передавать заголовки и статус-коды. В консоли AWS при создании функции выберите триггер API Gateway HTTP API.

Работа с Amazon S3 через Kotlin

Serverless-функции часто взаимодействуют с другими сервисами AWS. Покажем пример чтения файла из S3:

import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.GetObjectRequest
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler

class S3ReaderHandler : RequestHandler<Map<String, String>, String> {
    private val s3 = S3Client.builder().build()

    override fun handleRequest(input: Map<String, String>, context: Context): String {
        val bucket = input["bucket"] ?: throw IllegalArgumentException("Missing bucket")
        val key = input["key"] ?: throw IllegalArgumentException("Missing key")
        val request = GetObjectRequest.builder().bucket(bucket).key(key).build()
        val content = s3.getObjectAsBytes(request).asUtf8String()
        return "Content from S3: $content"
    }
}

Не забудьте добавить зависимость software.amazon.awssdk:s3:2.21.0 в build.gradle.kts и настроить IAM-роль с доступом к S3.

Оптимизация холодного старта и мониторинг

Уменьшение времени холодного старта

Холодный старт (cold start) — главный враг serverless-приложений на JVM. Вот несколько способов его минимизировать:

  • Используйте SnapStart — функция AWS, которая делает снапшот состояния JVM после инициализации. Включите её в консоли Lambda.
  • Сократите размер JAR — используйте Shadow JAR (плагин shadow) и исключите ненужные зависимости.
  • Ленивая инициализация — создавайте тяжелые объекты (например, S3Client) внутри companion object, чтобы они инициализировались только один раз:
class OptimizedHandler : RequestHandler<Map<String, String>, String> {
    companion object {
        private val s3 by lazy { S3Client.builder().build() }
    }

    override fun handleRequest(input: Map<String, String>, context: Context): String {
        // используем s3
    }
}
  • Увеличьте память — больше памяти (например, 1024 MB) часто улучшает производительность CPU и сокращает время старта.

Логирование и мониторинг

Для отладки используйте встроенный логгер context.logger. Для продакшена рекомендуется подключить X-Ray или CloudWatch Logs:

context.log                

Блоги

Рекомендаций по книгам