Почему бессерверные функции на основе Java имеют холодный запуск, если JVM использует JIT-компилятор?

#aws-lambda #jvm #azure-functions #serverless #cloudflare-workers

Вопрос:

Поздним вечером в пятницу мысли после прочтения материала о том, как рабочие функции Cloudflare на основе v8 «без холодного запуска» — короче говоря, из-за компилятора кода Javascript на движке V8-я задаюсь вопросом, почему этот тип бессерверных функций без холодного запуска, похоже, существует только для Javascript.

Связано ли это только с тем, что с архитектурной точки зрения, когда функции AWS Lambda / Azure были запущены, они были спроектированы как своего рода еще более упрощенная модель Kubernetes, где каждая функция существует в своем собственном контейнере? Я бы предположил, что это была более простая модель разделения кода разных клиентов, чем все, что выделяет magic sauce v8 под капотом.

Таким образом, учитывая, что Java компилируется в байт-код для JVM, который использует JIT-компиляцию (если он не оптимизирует и не компилирует в машинный код определенные функции с высоким уровнем использования), возможно ли поэтому также технически не иметь функций холодного запуска Java без сервера? До тех пор, пока существует какой-либо способ загрузки байт-кода каждого клиента по мере их вызова на сервере облачного провайдера.

Каковы практические задачи для того, чтобы это стало реальностью? Я не большой эксперт во всем этом, но могу себе представить, возможно:

  1. Скомпилированный байт-код не предназначен для загрузки таким образом — он должен быть единственным кодом, выполняемым в JVM
  2. Оптимизация JVM написана не для поддержки кратковременной загрузки нескольких функций и рассматривает весь загруженный код как одну массивную программу
  3. JVM после запуска не поддерживает загрузку дополнительного байт-кода.

Ответ №1:

В принципе, вы, вероятно, могли бы разработать Java-ориентированную бессерверную среду выполнения, в которой отдельные функции динамически загружаются по требованию, и таким образом вы могли бы добиться довольно хорошего времени холодного запуска. Однако есть две серьезные причины, по которым это может работать не так хорошо, как JavaScript:

  1. Хотя Java предназначена для JIT-компиляции, она не была оптимизирована для времени запуска почти так же интенсивно, как V8. Сегодня JVM чаще всего используется на больших постоянно работающих серверах, где скорость запуска не так важна. V8, с другой стороны, всегда был ориентирован на среду браузера, в которой код загружается и выполняется во время ожидания пользователя, поэтому минимизация задержки запуска имеет решающее значение. (На самом деле может быть интересно взглянуть на альтернативную среду выполнения Java, такую как Dalvik для Android, у которой было гораздо больше оснований для приоритизации скорости запуска. Может быть, это может стать основой действительно быстрой среды Java без сервера!)
  2. Безопасность. V8 и другие среды выполнения JavaScript с самого начала разрабатывались с учетом враждебного кода, и на них было проведено огромное количество исследований в области безопасности. Java тоже пыталась нацелиться на это, в самые первые дни, с помощью «апплетов», но такое использование Java так и не прижилось. В наши дни безопасная песочница не является основной проблемой Java. Из-за этого, вероятно, слишком рискованно запускать несколько Java-приложений, которые не доверяют друг другу в одном контейнере. Итак, вы возвращаетесь к созданию отдельного контейнера для каждого приложения.