Статьи

Запуск приложения Spring Boot без сервера с помощью AWS

В нескольких предыдущих статьях я рассказывал, как настроить приложение Spring Boot и запустить его в AWS Elastic Beanstalk . Хотя это отличный шаг для перехода от физического сервера к облачному, существует еще лучший шаг! Собираюсь без сервера . Это означает, что нет затрат на какой-либо сервер и нет необходимости в обслуживании или настройке серверов! Звучит хорошо, правда? Благодаря AWS Lambda и AWS API Gateway AWS значительно упрощает работу без серверов. В этом посте я опишу, что понадобилось моему приложению Spring Boot, работающему на Elastic BeanStalk, для запуска той же функциональности без сервера.

Первым шагом, который я предпринял, было избавление от зависимостей Spring Boot, так как нам больше не нужен этот контейнер. Я заменил их на зависимости для Spring Core и Spring Configuration. Также были изменены плагины для создания фляги, которую можно использовать для AWS Lambda.
Самые важные части пома пошли из этого:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
...
  <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>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
  </dependency>
  ...
  ...
  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
  </plugin>
  ...

К этому:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>
  ...
  ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <configuration>
      <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  ...

Следующим шагом является изменение кода Java таким образом, чтобы функциональность RestController вызывалась путем реализации интерфейса AWS Lambda:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
public class LambdaFunctionHandler implements RequestHandler<InvoiceRequest, InvoiceResponse> {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(EasyInvoiceController.class);
 
    private EasyInvoiceController easyInvoiceController;
 
    @Override
    public InvoiceResponse handleRequest(InvoiceRequest input, Context context) {
 
        easyInvoiceController = Application.getBean(EasyInvoiceController.class);
        InvoiceResponse result = null;
        try {
            result = easyInvoiceController.generate(input);
        } catch (ExecutionException e) {
            LOGGER.error(e);
        } catch (InterruptedException e) {
            LOGGER.error(e);
        }
        return result;
    }
}

С этим классом (и некоторой простой конфигурацией Spring) функциональность RestController, которая сначала была вызвана с входящим HTTP-запросом, теперь вызывается Lambda-запросом.
В моем случае я также смог избавиться от своего кода Spring Security, поскольку мне не нужно было защищать входящий запрос в лямбда-коде, поскольку это будет сделано в шлюзе API.

Следующий шаг — загрузить функциональность Lambda (сгенерированный файл JAR в целевой папке) и убедиться, что он работает, протестировав его. Я использовал средство загрузки S3 и добавил несколько переменных среды:

скриншот-на-ноябрь-27-20-09-45

Последний шаг — вызов Lambda из шлюза API путем определения API. Смотрите на скриншот для примера:

скриншот-на-ноябрь-30-08-21-35

Я должен сказать, что эта безсерверная архитектура может работать не во всех случаях использования, но, по крайней мере, ее следует учитывать при разработке новых приложений / (микро) сервисов или при любых изменениях в архитектуре.
Еще одно замечание: мне потребовалось немало усилий, чтобы заставить API Gateway работать с Lambda, которую я создал, но я все еще думаю, что это отличное решение для определенных случаев.