大家好,我是万天。接下来以最简单的方式介绍Node.js是如何实现异步资源上下文共享的,以及异步资源上下文共享对我们有什么用。异步资源上下文共享是指在网络请求生命周期或异步资源调用链中共享上下文数据。在回答这个问题之前,我们首先要了解什么是异步资源。异步资源异步资源可以理解为带有回调的对象,例如但不限于Promises、Timeouts、TCPWrap、UDP等,详见异步资源类型列表。官方定义如下:一个异步资源代表一个带有关联回调的对象。这个回调可能会被调用多次,例如net.createServer()中的'connection'事件,或者像fs.open()中那样只调用一次。也可以在调用回调之前关闭资源。AsyncLocalStorage本节介绍AsyncLocalStorage,Node.js官方提供的异步上下文共享方案。该特性在16.4.0之前还是实验特性,16.4.0之后已经稳定。AsyncLocalStorage可以在一系列异步操作中共享数据。AsyncLocalStorage实例asyncLocalStorage有以下主要方法:disable()禁用asyncLocalStorage;getStore()返回当前上下文存储,必须通过asyncLocalStorage.run()或asyncLocalStorage.enterWith()异步初始化;enterWith(store)通过这个方法传入contextstore,在后续的所有异步调用中都可以获取到;示例:conststore={id:1};//用给定的存储对象替换之前的存储asyncLocalStorage.enterWith(store);asyncLocalStorage.getStore();//返回存储对象someAsyncOperation(()=>{asyncLocalStorage.getStore();//返回相同的对象});run(store,callback[,...args])指定上下文存储和回调函数生效后,store只能在回调函数中获取。exit(callback[,...args])asyncLocalStorage.run()函数的第一个参数是存放异步调用中我们需要访问的共享数据,第二个参数是一个异步函数。下面举例演示如何使用AsyncLocalStorage实现异步资源上下文共享:output:runA8f19ebef-58d7-4b1a-8b9b-46d158beb5d22022/5/2420:26:17thisisalogmessagerunB8f19ebef-58d7-4b1a-8b9b-46d158beb5d22022/5/2420:26:17这是一条日志消息在通过asyncLocalStorage.run运行的同一个异步函数中,将运行函数runA和函数runB,并且runA和runB可以访问相同的上下文数据.性能问题AsyncLocalStorage为我们在Node.js中轻松实现异步资源上下文共享提供了极大的遍历,但是每次异步资源操作都会触发AsyncHooks,这必然会对我们Node应用的性能造成一定的影响。那么影响有多大呢?根据Kuzzle的实测,使用AsyncLocalStorage会造成大约8%的额外性能损失。当然,不同的业务场景可能会有不同的表现。如果关注这部分性能,也可以在自己的业务中加入对比测试,测试具体的性能影响。----用AsyncLocalStorageLog登录classicdifferencereq/s26132842~8%应用场景在其他多线程语言中,每个HTTP创建一个新的线程,每个线程都有自己的内存。您可以将全局状态存储在线程内存中,并在您的代码中的任何位置访问它。在Node.js中,由于Node.js是单线程的并且在所有HTTP请求之间共享内存,因此每个HTTP请求不能持有一个相互隔离的全局状态。AsyncLocalStorage可以有效隔离不同异步操作之间的状态,在HTTP请求跟踪、APM工具、上下文日志跟踪、基于请求的全链路日志跟踪等场景中发挥着非常重要的作用。参考资料AsyncLocalStorageDocsSimpleContextPassingWithAsyncLocalStorageinNode.jsNodeAsyncLocalStoragesharesstatuswithasynchronousresourcesAsynclocalstorage使用Node.js的AsyncHooks模块跟踪异常资源UsingAsyncHooksforRequestContextHandlinginNode.js_Gettingper-requestJSwithasynchookAsynchookAsynchookAsynchookJScontextinHooks:通往具有持久执行上下文的领域之旅|Node.TLV20NodeAsyncLocalStoragesharesstatuswithasynchronousresourcesInNode.jsUsingasynchookstohandleHTTPrequestcontext中的
