共计 5560 个字符,预计需要花费 14 分钟才能阅读完成。
腾讯云云函数最近新公布了 Node.js 12.16 的 runtime,也是国内首家反对 Node.js 12.x 的支流云服务商。
Node.js 版本的降级带来了新的个性以及性能方面的晋升,有趣味的同学能够参考国外一博主总结的文章《Node.js 12: The future of server-side JavaScript》理解具体内容。
其中比拟重要的一点是启动速度晋升,通过 v8 code cache 的反对,构建时提前为内置库生成代码缓存,晋升 30% 的启动耗时。
腾讯云云函数为了让 Serverless 更加合乎 Node.js 原生的应用体验,针对 Node.js runtime 做了针对性的优化。
借这个机会,我想和大家分享一下如何应用腾讯云云函数来开发 Node.js 利用以及 scf 的 Node.js runtime 实现的原理。
入口函数的参数
首先咱们看一下最根本的 Node.js 入口函数:
exports.main_handler = (event, context, callback) => {
console.log(“Hello World”);
console.log(event);
console.log(context);
callback(null, event);
};
runtime 会将三个参数传递到处理程序办法。
第一个参数是 event,用来传递触发事件数据
蕴含来自调用程序的信息。调用程序在调用时将该信息作为 JSON 格局字符串传递,事件构造因服务而异。
定时触发器的 event 对象就包含了触发的工夫,触发器的名称
{Message: “”, Time: “2020-05-08T14:30:00Z”, TriggerName: “time_5”, Type: “Timer”}
apigateway 触发器的 event 对象透传了 http 申请的残缺内容以及 apigateway 定制化的 http 申请头部信息
{“headerParameters”:{},”headers”:{…},”httpMethod”:”GET”,”path”:”/params_log”,”pathParameters”:{},”queryString”:{},”queryStringParameters”:{},”requestContext”:{“httpMethod”:”ANY”,”identity”:{},”path”:”/params_log”,”serviceId”:”service-9khp96qy”,”sourceIp”:”120.229.9.165″,”stage”:”release”}}
cos 触发器的 event 对象包含了触发执行的具体 cos 操作以及 cos 对象 undefined{“Records”:[{“cos”:{“cosBucket”:{“appid”:”1251133793″,”name”:”test”,”region”:”gz”},”cosNotificationId”:”unkown”,”cosObject”:{“key”:”/1251133793/test/xxx.png”,”meta”:{“Content-Type”:”image/png”,”x-cos-request-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″,”reqid”: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,
environment: “{“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: “…”
从下面的内容能够看到,该对象蕴含的内容有:
函数配置信息,比方设置的内容大小,超时工夫等
执行身份认证信息。如果设置了函数的运行角色(角色必须要蕴含对应操作的受权策略),在环境变量中会注入 secretId,secretKey,sessionToken,在拜访第三方云服务,比方 cos、自定义监控数据上报时就能够应用这几个值间接调用云 api,而不必在代码外面去 hard code 各种密钥信息
环境变量:包含了用户自定义的环境变量以及一些零碎环境变量
执行环境根本信息:包含了以后函数调用的地区,用户的 appId,uin
第三个参数 callback 是一个可选参数,在非异步函数中返回执行后果
回调函数采纳两个参数:一个 Error 和一个返回。返回对象必须与 JSON.stringify 兼容。异步函数将疏忽 callback 的返回,必须通过 return、throw exception 或者 promise 来解决返回或谬误
const https = require(‘https’)
let url = “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))
})
}
函数返回
咱们来看一下,针对异步场景(async 函数)和非异步场景,云函数怎么把返回值传递进来
异步函数
对于异步函数,能够应用 return 和 throw 来发送返回或谬误。函数必须应用 async 关键字。在异步函数中,第三个参数 callback 没有定义
示例:异步函数
const https = require(‘https’)
let url = “https://cloud.tencent.com/”
const httpRequest = url => {
const promise = new Promise(function(resolve, reject) {
https
.get(url, res => {resolve(res.statusCode)
})
.on('error', e => {reject(Error(e))
})
})
return promise
}
exports.handler = async function(event, context) {
try{
const result = await httpRequest(url)
// 在 async 函数中 callback 未定义
// callback(null, result)
return result
}catch(e) {
throw e
}
}
同步函数
还是下面的例子,发动一个 http 申请,如果用同步函数实现,参照以下示例
示例:同步函数,callback 返回
const https = require(‘https’)
let url = “https://cloud.tencent.com/”
exports.handler = function(event, context, callback) {
https.get(url, (res) => {
// 只能通过 callback 返回,return 会被疏忽
callback(null, res.statusCode)
}).on(‘error’, (e) => {
callback(Error(e))
})
}
返回的机会
失常的 Node.js web framework 在 response 返回后,异步逻辑还是持续在执行的。而 Serverless 场景下,因为机制和 framework 的差异,对于曾经返回 responese 的状况,一种是等着异步都解决完再来返回,这样保障了一次调用的完整性。另外一种就是在返回后就间接完结当次调用,间接挂起异步解决。
腾讯云云函数针对 Node.js 的异步场景,实现了返回和完结拆散的非凡机制。
入口函数的同步执行过程实现及返回后,云函数的调用将立即返回,并将代码的返回信息返回给函数调用方
同步流程解决并返回后,代码中的异步逻辑能够继续执行和解决,直到异步事件执行实现后,云函数的理论执行过程才实现和退出。
默认状况下,函数执行会期待所有异步执行完结才算一次调用完结,但也给用户提供了敞开事件循环期待的选项,用户能够敞开事件循环期待来自行管制函数的返回机会。通过在 callback 回调执行前设置 context.callbackWaitsForEmptyEventLoop = false,能够使云函数在执行返回后立即解冻过程,不再期待异步循环内的事件
比方一下示例代码,代码外面发动了一个异步 http 申请,另外有一个 2s 后执行的 setTimeout
const https = require(‘https’)
let url = “https://cloud.tencent.com/”
const httpRequest = url => {
const promise = new Promise(function(resolve, reject) {
https
.get(url, res => {resolve(res.statusCode)
})
.on('error', e => {reject(Error(e))
})
})
return promise
}
exports.main_handler = async function(event, context) {
// 设置该选项为 false 会不期待异步队列执行完,而是在返回后间接解冻 process
//context.callbackWaitsForEmptyEventLoop = false
try{
const result = await httpRequest(url)
setTimeout(() => {console.log('timeout log')
}, 2000)
return result
}catch(e) {
throw e
}
}
在 http 申请实现后,会立刻返回给调用方,不会期待 setTimeout 的异步实际执行完。而在返回后,程序会继续执行,直到 setTimeout 的事件执行完才算本次调用完结。
在设置了 context.callbackWaitsForEmptyEventLoop = false 后,在 return 后过程会被解冻,setTimeout 外面的执行逻辑会被挂起
残缺流程图
以下是单实例内 runtime 运行的残缺流程图
流程图
针对 Node.js 利用,有以下几个实际倡议
日志:runtime 重写了 console 的几个次要办法,而且是在 require 用户文件之后,所以用户自定义日志选项会有效
缓存复用:在入口函数外能够定义变量,存储能够复用的缓存对象,比方数据库的连贯等
Node.js 的模块实现逻辑中,如果一个 module 被 require 过,该模块就会被 cache 到内存中,再次被 require 时不会从新初始化。针对这一个性,如果实例始终再复用,那么在入口文件中,入口函数外定义的变量都不会被销毁,能够达到复用的成果
内置局部 npm 包,能够间接应用,具体参照文档。部署云函数代码时举荐 npm install –production,缩小代码包的体积,晋升上传速度和执行速度
执行角色:配置执行角色,从 context 中能够获取长期的密钥信息,能够用了拜访有相应权限的第三方服务,而不必在代码内写死密钥信息
观看 Tencent Serverless Hours 线上分享会第一期回放请戳:
Serverless Framework 30 天试用打算
咱们诚邀您来体验最便捷的 Serverless 开发和部署形式。在试用期内,相关联的产品及服务均提供免费资源和业余的技术支持,帮忙您的业务疾速、便捷地实现 Serverless!
One More Thing
3 秒你能做什么?喝一口水,看一封邮件,还是 —— 部署一个残缺的 Serverless 利用?复制以下链接至 PC 浏览器拜访:
china.serverless.com/express
3 秒极速部署,立刻体验史上最快的 Serverless HTTP 实战开发!
http://www.feedcool.cn/book/7…
以上为全部内容