Лямбда/бессерверное встроенное требование по сравнению с требованием заголовка

Фон

Я создаю API, используя AWS Lambda и API Gateway. Вместо того, чтобы разбивать каждую конечную точку API на отдельные лямбда-функции, я оборачиваю их в единую библиотеку и использую библиотеку aws-serverless-express.

Вопрос

Учитывая, что только часть всего API может использоваться в одном выполнении Lambda, с точки зрения использования памяти (для сокращения затрат) есть ли разница между:

var myModule = require("mymodule");

...

function handleSomething1()
{
    myModule.doSomething();
}

function handleSomething2()
{
    ...
}

or

function handleSomething()
{
    require("mymodule").doSomething();
}

function handleSomething2()
{
    ...
}

Так, например, один запрос API может привести к вызову только handleSomething2 до отключения функции Lambda. В этом случае мы эффективно тратим память, вызывая var myModule = require("mymodule"); сверху?

Я полагаю, что более прямой вопрос заключается в том, когда я var myModule = require("mymodule") действительно ли среда выполнения node.js выделяет память для myModule в этот момент? Или это фактически бесполезна, пока я действительно не сделаю что-нибудь с myModule?


person Jim Heising    schedule 20.07.2017    source источник


Ответы (2)


Вы всегда должны использовать асинхронные методы и вызовы функций в Node. Однако Node.js всегда выполняется синхронно, и для требуемого модуля могут потребоваться другие необходимые модули, что является дорогостоящим процессом.

Даже для контекста Lambda это остается прежним, поскольку, если вы определяете 'require' вне функции, она будет инициирована при холодном запуске Lambda и не будет повторно запускаться для последующих вызовов горячего запуска.

Подробнее о повторном использовании контейнера Lambda ссылка.

person Ashan    schedule 20.07.2017
comment
Что вы имеете в виду под: it will be initiated upon Cold start of Lambda and not re-run for subsequent Hot start calls? Node кэширует требование, но Lambda не имеет состояния. Каждое выполнение (холодное или горячее) запускается без предварительного уведомления, поэтому требование будет инициировано при холодном и горячем запуске. - person Zanon; 21.07.2017
comment
Когда лямбда-функция вызывается, она загружается в контейнер, и код вне обработчика будет инициирован с последующим запуском обработчика. Функция Lambda будет работать еще около 5 минут после обработки первоначального запроса, ожидая дальнейших запросов. Если в течение этого времени поступает новый запрос, он будет запускать только код внутри функции-обработчика. - person Ashan; 21.07.2017
comment
Где вы видите 5-минутную часть? Насколько я понимаю, функция Lambda прекратит работу, как только сможет. Я считаю, что 5 минут — это максимальное время, в течение которого может работать один обработчик, но в большинстве случаев он останавливается, как только ему больше нечего делать. - person Jim Heising; 21.07.2017
comment
Выставление счетов за функцию Lambda прекратится, как только будет вызван обратный вызов, но функция Lambda будет работать с отставанием (HOT), чтобы она могла обработать другой запрос. Ознакомьтесь со следующими вопросами и ответами по Stackoverflow для получения дополнительной информации stackoverflow.com/questions/34216248/ - person Ashan; 21.07.2017
comment
Интересный. Он говорит... это может длиться до 5 минут. Но по моему опыту, обычно это намного короче. Интересно, может ли это быть связано с объемом оперативной памяти, которую вы выделяете для него. - person Jim Heising; 21.07.2017
comment
В этом я не совсем уверен, однако, по моему опыту, это занимает около 5 минут, так как я использую расписание Lambda, чтобы поддерживать его ГОРЯЧИМ. - person Ashan; 21.07.2017

require() — это синхронная операция, которая происходит в момент ее выполнения. В вашем примере, если функция не выполняется, то модуль не будет добавлен в память.

Вы можете уменьшить использование памяти с помощью своей стратегии, но будет ли это значительным? Будьте осторожны, не беспокойтесь слишком сильно о микрооптимизации, поскольку рекомендуемая практика (или, по крайней мере, стандартная практика) в Node — требовать наличия модулей в начале, а не в середине кода.

person Zanon    schedule 21.07.2017
comment
В вашем примере я предполагаю, что вы имеете в виду второй? Я понимаю, что наилучшая практика заключается в том, чтобы модули требовались в начале, но эта наилучшая практика была разработана до того, как бессерверные архитектуры стали обычным явлением. Я предполагаю, что последующий вопрос может быть следующим: нужно ли обновлять лучшие практики, когда вы думаете о запуске node.js на Lambda? - person Jim Heising; 21.07.2017
comment
Да, я имею в виду второй пример; Да, в бессерверном контексте многое меняется, в том числе то, что можно считать передовым опытом. Тем не менее, я по-прежнему ожидаю прочитать код Node.js с требованиями в верхней части файла, поэтому я знаю, где выполняются все запросы синхронизации, и знаю, что остальная часть файла будет выполнять только асинхронные запросы. Как я уже сказал, вы можете использовать эту стратегию, чтобы избежать загрузки ненужного кода, но подтвердите, действительно ли это будет иметь какое-либо значение, и это не плохой случай микрооптимизации. - person Zanon; 21.07.2017