Как разработчик JAVA, процессы могут страдать от более длительного времени запуска и временами относительно большого использования памяти 😞. Мы будем искать интересное решение этой проблемы.

В этой статье мы рассмотрим простое приложение Spring Boot, а затем преобразуем его в собственный образ с помощью GraalVM.

Если вы не знакомы с GraalVM, не волнуйтесь. Мы обсудим это через некоторое время. На данный момент просто имейте в виду, что это JVM, которая обеспечивает компиляцию заблаговременно в сочетании с компиляцией точно в срок во время выполнения .

Давайте сначала обсудим приложение Spring Boot, которое мы собираемся кодировать сегодня. (Здесь мы будем использовать Maven, но вы также можете использовать Gradle).

Приложение предоставит две конечные точки REST, каждая из которых будет принимать запросы HTTP GET.

  • Первая конечная точка должна предоставлять информацию, соответствующую пользователю Github (/ users / {githubUserName}).
  • Вторая конечная точка должна предоставлять информацию, соответствующую участникам репозитория Github
    (/ members / {githubOrgName} / {githubRepoName}).

GithubController можно определить следующим образом -

Мы автоматически подключили класс GithubClient к контроллеру и используем его для получения сведений о пользователе или участнике.

Здесь мы используем RestTemplate для вызова API Github.

Теперь давайте посмотрим на User класс DTO, который будет использоваться в качестве ответа REST.

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

Github API накладывает ограничение на скорость, из-за которого вы не можете делать более 60 запросов в час с заданного IP-адреса. Мы можем увеличить этот предел скорости, используя токены аутентификации Github.

Давайте определим GithubProperties как Spring Boot ConfigurationProperties.

Итак, теперь мы можем добавить свойство с именем github.token в application.properties / application.yaml. Поскольку используются аннотации @ Validated и
@ Pattern, при запуске приложения будет обеспечено соответствие свойства указанному регулярному выражению.

Теперь, как использовать этот токен при попытке вызвать API Github? Что ж, давайте реализуем перехватчик Spring RestTemplate.

Здесь intercept функция GithubAppTokenInterceptor добавляет Authorization заголовок запроса с закодированным значением предоставленного токена.

Функция intercept из RateLimitHeaderInterceptor извлекает заголовок ответа
X-RateLimit-Remaining и предоставляет оператор log для предоставления информации об оставшемся пределе скорости.

Для использования этих двух перехватчиков нам просто нужно предоставить их при инициализации объекта restTemplate.

Последняя часть кода - это точка входа в приложение.

Код, который мы обсуждали до сих пор, можно найти здесь -



Теперь соберите с помощью mvn clean install. Затем запустите команду mvn spring-boot:run, и приложение запустится на порту 8080.

Нажатие http: // localhost: 8080 / users / shivamgarg7276 дает -

{
    "login": "shivamgarg7276",
    "name": "Shivam Garg",
    "company": "Nutanix",
    "avatarUrl": "https://avatars.githubusercontent.com/u/49524850?v=4",
    "blogUrl": "https://www.linkedin.com/in/shivam-garg-067b46141/",
    "numPublicRepos": 1,
    "htmlUrl": "https://github.com/shivamgarg7276"
}

Итак, запуск моей машины занял около 1.5 sec, а потребление памяти было около 200 MB. Это решает задачу, но мы увидим, как мы можем значительно улучшить это с помощью GraalVM.

Что такое GraalVM и почему это будущее приложений JAVA?

«GraalVM - байтовый код в битовый код» 😀😀

GraalVM - это высокопроизводительный компилятор полиглотов, который помогает достичь:

  1. Увеличьте пропускную способность приложений и уменьшите задержку
  2. Компилировать приложения в небольшие автономные двоичные файлы
  3. Легко используйте несколько языков и библиотек

Его можно использовать как для Java JIT, так и для компиляции AOT.

Для компиляции AOT он использует технологию Native Image Builder или native-image для предварительной компиляции кода Java в автономный исполняемый файл. Он обрабатывает все классы приложения и их зависимости, в том числе из JDK. Он статически анализирует эти данные, чтобы определить, какие классы и методы доступны во время выполнения приложения.

Вы можете установить GraalVM в своей системе, используя шаги, которые я выделил здесь -



Бета-версия Spring Native

Некоторое время назад команда Spring анонсировала проект Spring Native Beta , позволяющий компилировать приложения Spring в собственные образы с помощью GraalVM.

Обещают, что потребление памяти будет намного ниже, а запуск будет практически мгновенным.

Теперь давайте переключимся и внесем некоторые изменения в наше исходное приложение Spring Boot, чтобы преобразовать его в собственное исполняемое приложение Spring. 😉

После установки GraalVM на свой компьютер вам необходимо внести эти изменения в исходное приложение -

  • Добавьте зависимость org.springframework.experimental:spring-native-image maven.
<dependency>
  <groupId>org.springframework.experimental</groupId>
  <artifactId>spring-native</artifactId>
  <version>0.9.2</version>
</dependency>
  • Добавить плагин Spring AOT
<plugin>
  <groupId>org.springframework.experimental</groupId>
  <artifactId>spring-aot-maven-plugin</artifactId>
  <version>0.9.2</version>
  <executions>
    <execution>
      <id>test-generate</id>
      <goals>
        <goal>test-generate</goal>
      </goals>
    </execution>
    <execution>
      <id>generate</id>
      <goals>
        <goal>generate</goal>
      </goals>
    </execution>
  </executions>
</plugin>
  • Добавить профиль GraalVM native-image, запускающий плагин на package фазе
<profiles>
  <profile>
    <id>native-image</id>
    <build>
      <plugins>
        <plugin>
          <groupId>org.graalvm.nativeimage</groupId>
          <artifactId>native-image-maven-plugin</artifactId>
          <version>21.0.0.2</version>
          <configuration>
            <!-- The native image build needs to know the entry point to your application -->
            <mainClass>com.example.graal.restserver.main.RestApplicationWithAOT</mainClass>
            <buildArgs>
              <buildArg>--enable-https</buildArg>
            </buildArgs>
          </configuration>
          <executions>
            <execution>
              <goals>
                <goal>native-image</goal>
              </goals>
              <phase>package</phase>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

Здесь предоставляется аргумент mainClass, который указывает на точку входа приложения, то есть на класс, помеченный SpringBootApplication.
Кроме того, buildArgs имеет --enable-https, поскольку мы вызываем URL-адреса Github на основе HTTPS с помощью RestTemplate.

Изменения кода, которые мы обсуждали до сих пор, можно найти здесь -



Вы можете собрать модуль, просто используя эту команду -
mvn -Pnative-image clean package

Это создаст собственный исполняемый файл, содержащий приложение Spring Boot, в папке target модуля.

Просто вызовите -
target/com.example.graal.restserver.main.restapplicationwithaot

Это запустит сервер Spring Boot на порту 8081.

Если вы сейчас видите, время запуска на моей машине было 0.093 sec 😳 😯

Это было очень быстро.

Кроме того, потребление памяти ниже 40 MB. 👌

Вы также можете создать оптимизированный образ контейнера с помощью GraalVM + Spring Native, который легко развертывается и включает минимальный уровень ОС.

Заключение

Очевидно, вам следует протестировать на своей машине, чтобы сравнить эти числа. Но это ясно демонстрирует истинную мощь GraalVM и причину, по которой это будет будущее приложений Java. 😄

Как отмечают некоторые отраслевые эксперты -

Есть много аспектов нативного образа, которые я еще не обсуждал и сделаю в следующих частях этого поста. Мы рассмотрим некоторые угловые случаи, требующие расширенной настройки конфигурации, а также некоторые другие оптимизации.

Посмотрите интересные вещи на https://www.graalvm.org/.

Вы можете высказать свое мнение и дать предложения в комментариях.

Спасибо 😊

Изменить: ознакомьтесь с частью 2 этой статьи -