Vert.x нативный образ потрясающий!

Ссылка на оригинал - https://www.jetdrone.xyz/2018/08/10/Vertx-native-image-10mb.html, автор публикации - Paulo Lopes

Я уже некоторое время работаю с GraalVM, главным образом, над аспектом Polyglot , но некоторая работа была проделана в поддержке нативных изображений. Сегодня я хотел бы поделиться тем, что сейчас это возможно, спойлер: запустить Docker изображение с размером от 38MB и 10MB из памяти!

Немного истории

С серией 3.x Eclipse Vert.x была проделана большая работа по уменьшению количества загрузчиков классов , магии отражения(именно поэтому, например, нет аннотаций). Это обычно рассматривается как противоречащий смысл в мире Java, но это окупается, так как мы уже можем делать некоторые удивительные вещи, не задумываясь о хакерах или обходных путях, чтобы обойти ограничения субстрата.

Доказательство концепции

В качестве подтверждения концепции я решил создать небольшое приложение на основе презентации, которую я сделал около 2 лет назад на JavaZone. Приложение делает следующее:

  • Запустите клиент WebSocket для сбора в реальном времени неподтвержденных транзакций биткойнов.
  • Подключение к Postgres с победителем Techempower Benchmarks # 16 пг-реактивным-клиента.
  • По неподтвержденной транзакции сохраните ее в postgres.
  • На сохранить публикацию в UTX карту восстановленного значения vert.x eventbus
  • Запустите HTTP-сервер, обслуживающий одностраничное приложение
  • При запуске сервера подключите шину событий от сервера к веб-браузеру, используя sockjs
  • В браузере визуализируйте значения UTX в реальном времени по мере их поступления с веб-сокета сервера .

Как вы можете видеть, здесь уже много чего происходит: серверы, клиенты , веб-сокеты , события . Я мог бы продолжать добавлять больше материала, но это PoC правильно!

Покажи мне код

Теперь, когда у нас есть идея, мы должны реализовать ее, как я уже сказал, это был римейк старой презентации, поэтому код для меня был почти готов. Вот как это оказалось:

final Vertx vertx = Vertx.vertx();
final EventBus eb = vertx.eventBus();
final PgPool postgres = PgClient.pool(...);

BlockChainClient.create(vertx)
  .connect(self -> {
    self.subscribeUnconfirmed(json -> {
      postgres.preparedQuery(
        "INSERT INTO UTX (data) VALUES ($1)",
        Tuple.of(Json.create(json)), ar -> {
          int utxValue = 0;
          if (json.containsKey("out")) {
            // reduce step
            for (Object o : json.getJsonArray("out")) {
              utxValue += ((JsonObject) o).getInteger("value", 0);
            }
          }
          eb.publish("data.updates", utxValue);
      });
    });
  });

final Router app = Router.router(vertx);

app.route("/eventbus/*").handler(SockJSHandler.create(vertx));
app.route().handler(StaticHandler.create("static"));

vertx.createHttpServer()
  .requestHandler(app)
  .listen(Integer.getInteger("port", 8080));

Обработка ошибок и конфигурация опущены для краткости.

Это очень простое приложение, и на самом деле именно так вы и будете кодировать его с помощью Vert.x, я не делал никаких попыток заставить его работать на Graal SVM.

Построение

Сборка кода тривиальна, но у сборки изображения возникли некоторые проблемы. К счастью, проблемы просты и могут быть решены с помощью простого файла замены Java.

Таким образом, создание нативного изображения было так просто:

native-image \
  -Djava.net.preferIPv4Stack=true \
  -Dvertx.disableDnsResolver=true \
  -H:IncludeResources="(META-INF/services|webroot)/.*" \
  -H:+ReportUnsupportedElementsAtRuntime \
  -H:ReflectionConfigurationFiles=./src/main/svm/reflection.json \
  -jar "target/bitcoin-viewer.jar"

Итак, что важно увидеть здесь, сначала я укажу, что я предпочитаю стек IPV4 от виртуальной машины (но это не является обязательным требованием). Во-вторых, я отключаю распознаватель DNS Vert.x по той причине, что он не работает корректно с SVM, и vert.x откатится к преобразователю DNS по умолчанию на виртуальной машине (блокирующему), который работает нормально. Затем я указываю, какие ресурсы я бы хотел сохранить в своем fatjar, и указываю файл замещения.

После завершения вы можете увидеть:

-rwxrwxr-x.  1 plopes plopes 24603024 10 aug 11:45 bitcoin-viewer

Ваша заявка сейчас просто 24,6MB !

Dockerize

Graal SVM опирается на Glibc, так что это означает, что вы можете запустить его на многих изображениях, таких как Ubuntu , Fedora , Centos ... но эти изображения довольно большие, так почему бы не Alpine ?

Альпийские образы созданы против musl-libc, и это проблема. К счастью, проект alpine задокументировал, как заставить glibcработать на alpine, и на докер-хабе уже есть несколько изображений frolvlad/alpine-glibc.

Итак, давайте перейдем в докер?

# GraalVM docker image used for AoT compilation
FROM panga/graalvm-ce:latest AS build-aot
# Add maven wrapper
ADD mvnw app/
ADD mvnw.cmd app/
ADD .mvn app/.mvn/
# Add settings.xml to allow snapshots
ADD settings.xml root/.m2/
# Add pom
ADD pom.xml app/
# Add sources
ADD src app/src/
# Set working dir
WORKDIR /app
# Build (java side)
RUN ./mvnw -Pnative-image package
# Build image
RUN native-image \
    --no-server \
    -Djava.net.preferIPv4Stack=true \
    -Dvertx.disableDnsResolver=true \
    -H:IncludeResources="(META-INF/services|webroot)/.*" \
    -H:+ReportUnsupportedElementsAtRuntime \
    -H:ReflectionConfigurationFiles=./src/main/svm/reflection.json \
    -jar "target/bitcoin-viewer.jar"
# Create new image from alpine
FROM frolvlad/alpine-glibc:alpine-3.8
RUN apk add --no-cache ca-certificates
# Copy generated native executable from build-aot
COPY --from=build-aot /app/bitcoin-viewer /bitcoin-viewer
# Set the entrypoint
ENTRYPOINT [ "/bitcoin-viewer" ]

Результаты

Поэтому, когда мы запускаем наше приложение и postgres и запускаем, docker stats мы видим:

CONTAINER ID  NAME            CPU %  MEM USAGE / LIMIT    MEM %
c7f5e7af56fe  vertx-bitcoin   0.61%  5.133MiB / 15.54GiB  0.03%
a3536684f175  postgres        1.26%  11.27MiB / 15.54GiB  0.07%

Я бы сказал, что это удивительное сложное приложение, работающее в 5 МБ оперативной памяти !!! с мгновенным запуском!

А насчет размеров изображения, бега docker imagesмы видим:

REPOSITORY      TAG      IMAGE ID       CREATED             SIZE
vertx-bitcoin   latest   3b8b487b8ad8   43 minutes ago      37.9MB

Таким образом, общий размер составляет 38 МБ!

Java теперь жизнеспособная технология Serveless, и мы можем согласиться с тем, что Java не медленная и не раздутая, верно ?!

Не нашли ответ на свой вопрос? Возможно, вы найдете решение проблемы на нашем канале в Youtube! Здесь мы собрали небольшие, но эффективные инструкции. Смотрите и подписывайтесь на наш youtube-канал!

Смотреть на Youtube

Руководства и обзоры

1 Что нужно восстановить?

Видео

MP4, AVI и HD видео хранятся на телефоне и / или по ошибке удаляются вместе с фотографиями и другими медиафайлами.

Контакты

Номера телефонов друзей и знакомых из приложения «Контакты Android», журналы вызовов; Восстановление SIM-карты.

Фото

Удалены файлы JPG / PNG из Галереи Android; фото, загруженные на мобильный, файлы повреждены после восстановления.

Смс и сообщения

Чаты WhatsApp и Facebook, текстовые сообщения в соцсетях, информация на сим-карте

2 Где пропали файлы?

На sd-карте

Фотографии и документы хранятся на SD-картах. Часто на них случайно удаляются файлы

На телефоне

Программы для восстановления не распознают внутреннее хранилище телефона как диск, но есть другие решения.

На USB флешке

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

На HDD или SSD

Несмотря на то, что настольные платформы становятся все менее популярными, проблема потери файлов всегда оставалась.