Совместное использование контекста асинхронного ресурса означает совместное использование данных контекста в рамках жизненного цикла сетевого запроса или цепочки вызовов асинхронных ресурсов.
Прежде чем ответить на этот вопрос, мы должны сначала понять, что такое асинхронные ресурсы.
Асинхронные ресурсы можно понимать как объекты с обратными вызовами, такие как обещания, таймауты, TCPWrap, UDP и т. д., помимо прочего. Подробности см. в списке типов асинхронных ресурсов.
Официальное определение следующее:
Асинхронный ресурс представляет собой объект со связанным обратным вызовом. Этот обратный вызов может вызываться несколько раз, например, событие соединения в net.createServer(), или только один раз, как в fs.open. () Ресурс также можно закрыть до вызова обратного вызова.
Здесь мы представляем AsyncLocalStorage, решение для асинхронного совместного использования контекста, официально предоставляемое Node.js. Эта функция все еще была экспериментальной функцией до версии 16.4.0 и стабильна с версии 16.4. .0.
AsyncLocalStorage может совместно использовать данные в цепочке асинхронных операций.
Экземпляр AsyncLocalStorage asyncLocalStorage имеет следующие основные методы:
например:
const store = { id: 1 }; // Заменяет предыдущее хранилище данным объектом хранилища asyncLocalStorage.enterWith(магазин); asyncLocalStorage.getStore(); // Возвращает объект хранилища. someAsyncOperation(() => { asyncLocalStorage.getStore(); // Возвращает тот же объект. });
Первый параметр функции asyncLocalStorage.run() предназначен для хранения общих данных, к которым нам необходимо получить доступ при асинхронном вызове, а второй параметр — асинхронная функция.
Ниже приведен пример, демонстрирующий использование AsyncLocalStorage для реализации асинхронного совместного использования контекста ресурса:
Вывод:
runA 8f19ebef-58d7-4b1a-8b9b-46d158beb5d2 2022/5/24 20:26:17 это сообщение журнала. runB 8f19ebef-58d7-4b1a-8b9b-46d158beb5d2 2022/5/24 20:26:17 это сообщение журнала.
В той же асинхронной функции, выполняемой через asyncLocalStorage.run, будут выполняться функции runA и функция runB, а runA и runB могут выполняться. иметь доступ к одним и тем же контекстным данным.
AsyncLocalStorage предоставляет нам отличный способ легко реализовать асинхронное совместное использование контекста ресурсов в Node.js, но каждая асинхронная операция с ресурсом вызывает асинхронные перехватчики, которые неизбежно окажут определенное влияние на производительность нашего Node-приложения. Так насколько велико влияние?
Согласно фактическим измерениям Kuzzle, использование AsyncLocalStorage приведет к дополнительной потере производительности примерно на 8%. Конечно, разные бизнес-сценарии могут иметь разную производительность. Если вас беспокоит эта часть производительности, вы также можете добавить в свой бизнес сравнительное тестирование, чтобы проверить конкретное влияние на производительность.
---- | Журнал с помощью AsyncLocalStorage | Журнал классической | разницы |
---|---|---|---|
в запросах/с | 2613 | 2842 | ~8% |
В других многопоточных языках каждый HTTP создает новый поток, и каждый поток имеет собственную память. Вы можете хранить глобальное состояние в памяти потока и получать глобальное состояние из любого места вашего кода.
В Node.js, поскольку Node.js является однопоточным и разделяет память между всеми HTTP-запросами, каждый HTTP-запрос не может хранить глобальное состояние, изолированное друг от друга.
AsyncLocalStorage может эффективно изолировать состояние между различными асинхронными операциями и играет очень важную роль в таких сценариях, как отслеживание HTTP-запросов, инструменты APM, отслеживание контекстного журнала и отслеживание журнала полных ссылок на основе запросов.