腾讯云函数近日发布了Node.js12.16运行时,也是国内第一家支持Node.js12.x的主流云服务商。Node.js版本的升级带来了新的特性和性能提升。有兴趣的同学可以参考国外博主总结的文章《Node.js 12: The future of server-side JavaScript》了解详情。其中比较重要的一点就是启动速度的提升。v8代码缓存的支持,在构建时为内置库提前生成代码缓存,启动时间提升30%。为了让Serverless更符合原生Node.js的用户体验,腾讯云云函数针对Node.js运行时做了针对性的优化。借此机会,给大家分享一下如何使用腾讯云函数开发Node.js应用,以及scf的Node.js运行时实现原理。入口函数的参数首先,我们来看最基本的Node.js入口函数:exports.main_handler=(event,context,callback)=>{console.log("HelloWorld");控制台日志(事件);安慰。日志(上下文);回调(空,事件);};运行时会将三个参数传递给处理程序方法。第一个参数是事件,用于传递包含来自调用程序的信息的触发事件数据。调用者在调用时将此信息作为JSON格式的字符串传递,事件结构因服务而异。定时触发器的事件对象包括触发时间、触发器名称{Message:"",Time:"2020-05-08T14:30:00Z",TriggerName:"time_5",Type:"Timer"}apigateway触发器的事件对象透传http请求的完整内容和apigateway自定义的http请求头信息{"headerParameters":{},"headers":{...},"httpMethod":"GET",“路径”:“/params_log”,“pathParameters”:{},“queryString”:{},“queryStringParameters”:{},“requestContext”:{“httpMethod”:“ANY”,“identity”:{},"path":"/params_log","serviceId":"service-9khp96qy","sourceIp":"120.229.9.165","stage":"release"}}cos触发器的事件对象包括具体的cos触发执行操作和cos对象undefined{"Records":[{"cos":{"cosBucket":{"appid":"1251133793","name":"test","re??gion":"gz"},“cosNotificationId”:“未知”,“cosObject”:{“key”:“/1251133793/test/xxx.png”,“meta”:{“Content-Type”:“image/png”,“x-cos-请求ID“:”NWViNTZmMmFfOTJhODQwYV80MGZmXzI0Y2ZkYmM="},"size":6545739,"url":"...","vid":""},"cosSchemaVersion":"1.0"},"event":{"eventName":"cos:ObjectCreated:Put","eventQueue":"qcs:0:scf:ap-guangzhou:appid/1251133793:default.params_log.$DEFAULT","eventSource":"qcs::cos","eventTime":1588948779,"eventVersion":"1.0","re??qid":1038862404,"requestParameters":{"requestHeaders":{"Authorization":"..."},"requestSourceIP":"120.229.9.165"},"reservedInfo":""}}]}第二个参数context,函数运行时信息我们来看一个完整的context的内容:callbackWaitsForEmptyEventLoop:true,getRemainingTimeInMillis:200,memory_limit_in_mb:128,time_limit_in_ms:3000,环境:"{"SCF_NAMESPACE":"demo","TENCENTCLOUD_SECRETID":"...","TENCENTCLOUD_SECRETKEY":"...TENCENTCLOUD_SESSIONTOKEN":"。.."}"function_name:"params",function_version:"$LATEST",namespace:"demo",request_id:"ab42b693-8bfd-4dc1-b228-60360a63e06c",tencentcloud_appid:"...",tencentcloud_region:"ap-chengdu",tencentcloud_uin:"..."从上面的内容我们可以看出这个对象的内容包括:函数配置信息,比如设置的内容大小,超时时间等执行标识CertificationInf形成如果设置了函数的运行角色(角色中必须包含对应操作的授权策略),会在环境变量中注入secretId、secretKey、sessionToken,可以在访问第三方云服务时使用,比如cos和自定义监控数据上报这些值直接调用云端API,而不是硬编码在代码中。各种关键信息环境变量:包括用户自定义的环境变量和一些系统环境变量。执行环境基本信息:包括当前函数调用的区域,用户的appId,uin的第三个参数callback为可选参数,在非异步函数中返回执行结果。回调函数有两个参数:错误和返回。返回的对象必须与JSON.stringify兼容。异步函数会忽略回调的返回,返回或错误必须通过return、throwexception或promise来处理consthttps=require('https')leturl="https://cloud.tencent.com/"exports.main_handler=function(event,context,callback){https.get(url,(res)=>{callback(null,res.statusCode)}).on('error',(e)=>{callback(Error(e))})}函数返回我们来看看云函数对于异步场景(asyncfunctions)和非异步场景是如何将返回值传出去的。异步函数对于异步函数,return和throw可用于发送返回或错误。函数必须使用async关键字。异步函数中第三个参数callback未定义示例:异步函数consthttps=require('https')leturl="https://cloud.tencent.com/"consthttpRequest=url=>{constpromise=newPromise(function(resolve,reject){https.get(url,res=>{resolve(res.statusCode)}).on('error',e=>{reject(Error(e))})})returnpromise}exports.handler=asyncfunction(event,context){try{constresult=awaithttpRequest(url)//callbackisundefinedinasyncfunction//callback(null,result)returnresult}catch(e){该throwe}}同步函数还是上面的例子,发起一个http请求,如果是用同步函数实现的,参考下面的例子:同步函数,回调返回consthttps=require('https')leturl="https://cloud.tencent.com/"exports.handler=function(event,context,callback){https.get(url,(res)=>{//只能通过callback返回,return会忽略callback(无l、res.statusCode)}).on('error',(e)=>{callback(Error(e))})}正常Node.jsweb框架返回response时返回,异步逻辑继续执行.在serverless场景下,由于机制和框架的不同,对于response已经返回的情况,一种是等待异步处理完成再返回,保证了一次调用的完整性。另一种是返回后直接结束当前调用,直接挂起异步处理。腾讯云函数针对Node.js异步场景,实现了一种特殊的回返分离机制。入口函数的同步执行过程完成并返回后,云函数的调用会立即返回,并将代码的返回信息返回给函数调用方进行同步过程处理并返回,代码中的异步逻辑可以继续执行和处理,直到异步事件执行完成后,云函数的实际执行过程完成并退出。默认情况下,函数执行会等待所有异步执行结束后才会结束一次调用,但它也为用户提供了关闭事件循环等待的选项,用户可以通过关闭事件循环等待来控制返回时机自己的功能。通过在callback回调执行前设置context.callbackWaitsForEmptyEventLoop=false,云函数可以在执行返回后立即冻结进程,不再等待异步循环中的事件。比如示例代码中,代码中发起了一个异步的http请求,2s后又执行了一个setTimeoutconsthttps=require('https')leturl="https://cloud.tencent.com/"consthttpRequest=url=>{constpromise=newPromise(function(resolve,reject){https.get(url,res=>{resolve(res.statusCode)}).on('error',e=>{reject(Error(e))})})returnpromise}exports.main_handler=asyncfunction(event,context){//设置这个选项为false不会等待异步队列完成,返回后直接冻结进程//context.callbackWaitsForEmptyEventLoop=falsetry{constresult=awaithttpRequest(url)setTimeout(()=>{console.log('timeoutlog')},2000)returnresult}catch(e){throwe}}将返回http请求完成后立即给调用者,不会等待setTimeout的异步实现完成。返回后程序会继续执行,直到setTimeout事件执行完毕才调用结束。设置context.callbackWaitsForEmptyEventLoop=false后,return后进程会被冻结,setTimeout中的执行逻辑会被挂起以下做法建议日志:runtime重写了console的几个主要方法,而且是require用户文件后,所以用户定义的日志选项将无效。缓存复用:可以在入口函数外定义变量,存储可以复用在Node.js模块的实现逻辑中,比如数据库连接,如果需要一个模块,该模块会缓存在内存中,不会被调用再次需要时重新初始化。对于这个特性,如果实例一直被复用,那么在入口文件中,入口函数外定义的变量不会被销毁,可以达到复用的效果。一些内置的npm包可以直接使用。有关详细信息,请参阅文档。部署云函数代码时推荐使用npminstall--production,减少代码包大小,提高上传速度和执行速度执行角色:配置执行角色,从上下文中获取临时关键信息,可用于接入相应权限第三方服务,而不是在代码中硬编码关键信息观看腾讯ServerlessHours在线分享会第一期回放,请点击:ServerlessFramework30天试用计划诚邀您体验开发和部署无服务器的最便捷方式。试用期间,相关产品和服务免费提供资源和专业的技术支持,帮助您的企业快速轻松实现Serverless!再做一件事你能在3秒内做什么?喝一口水,阅读一封电子邮件,或者——部署一个完整的无服务器应用程序?复制以下链接到PC浏览器访问:china.serverless.com/express3秒极速部署,即刻体验史上最快的serverlessHTTP实战开发!http://www.feedcool.cn/book/7...以上是全部内容
