亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

詳解基于 Node.js 的輕量級云函數功能實現

2024-05-06 16:53:05
字體:
來源:轉載
供稿:網友

導語

在萬物皆可云的時代,你的應用甚至不需要服務器。云函數功能在各大云服務中均有提供,那么,如何用“無所不能”的 node.js 實現呢?

一、什么是云函數?

云函數是誕生于云服務的一個新名詞,顧名思義,云函數就是在云端(即服務端)執行的函數。各個云函數相互獨立,簡單且目的單一,執行環境相互隔離。使用云函數時,開發者只需要關注業務代碼本身,其它的諸如環境變量、計算資源等,均由云服務提供。

二、為什么需要云函數?

程序員說不想買服務器,于是便有了云服務;
程序員又說連 server 都不想寫了,于是便有了云函數。

Serverless 架構

通常我們的應用,都會有一個后臺程序,它負責處理各種請求和業務邏輯,一般都需要跟網絡、數據庫等 I/O 打交道。而所謂的無服務器架構,就是把除了業務代碼外的所有事情,都交給執行環境處理,開發者不需要知道 server 怎么跑起來,數據庫的 api 怎么調用——一切交給外部,在“溫室”里寫代碼即可。

FaaS

而云函數,正是 serverless 架構得以實現的途徑。我們的應用,將是一個個獨立的函數組成,每一個函數里,是一個小粒度的業務邏輯單元。沒有服務器,沒有 server 程序,“函數即服務”(Functions as a Service)。

三、如何實現?

由于本實現是應用在一個 CLI 工具里面的,函數聲明在開發者的項目文件里,因而大致過程如下:

Node.js,輕量級,云函數

1、函數聲明與存儲聲明

我們的目標是讓云函數的聲明和一般的 js 函數沒什么兩樣:

module.exports = async function (ctx) {  return 'hahha' }};

由于云函數的執行通常伴隨著接口的調用,所以應該要能支持聲明 http 方法:

module.exports = { method: 'POST', handler: async function (ctx) {  return 'hahha' }};

存儲

由于有 method 等配置,因此編譯的時候,需要把上述聲明文件 require 進來,此時,handler 字段是一個 Function 類型的對象??梢哉{用其 toString 方法,得到字符串類型的函數體:

const f = require('./func.js');const method = f.method;const body = f.handler.toString();// async function (ctx) {// return 'hahha'// }

有了字符串的函數體,存儲就很簡單了,直接存在數據庫 string 類型的字段里即可。

2、函數執行

url

如果用于前端調用,每個云函數需要有一個對應的 url,以上述聲明文件的文件名為云函數的唯一名稱的話,可以簡單將 url 設計為:

/f/:funcname

構造獨立作用域(重點)

在 js 世界里,執行一個字符串類型的函數體,有以下這么一些途徑:

  • eval 函數
  • new Function
  • vm 模塊

那么要選哪一種呢?讓我們回顧云函數的特點:各自獨立,互不影響,運行在云端。

關鍵是將每個云函數放在一個獨立的作用域執行,并且沒有訪問執行環境的權限,因此,最優選擇是 nodejs 的 vm 模塊。關于該模塊的使用,可參考官方文檔。

至此,云函數的執行可以分為三步:

  • 從數據庫獲取函數體
  • 構造 context
// ctx 為 koa 的上下文對象 const sandbox = {  ctx: {   params: ctx.params,   query: ctx.query,   body: ctx.request.body,   userid: ctx.userid,  },  promise: null,  console: console } vm.createContext(sandbox);

執行函數得到結果

const code = `func = ${funcBody}; promise = func(ctx);`;vm.runInContext(code, sandbox);const data = await sandbox.promise;

NPM社區的 vm2 模塊針對 vm 模塊的一些安全缺陷做了改進,也可用此模塊,思路大抵相同。

3、引用

雖然說原則上云函數應當互相獨立,各不相欠,但是為了提高靈活性,我們還是決定支持函數間的相互引用,即可以在某云函數中調用另外一個云函數。

聲明

很簡單,加個函數名稱的數組字段就好:

module.exports = { method: 'POST', use: ['func1', 'func2'], handler: async function (ctx) {  return 'hahha' }};

注入

也很簡單,根據依賴鏈把函數都找出來,全部掛載在 ctx 下就好,深度優先或者廣度優先都可以。

if (func.use) {  const funcs = {};  const fnames = func.use;  for (let i = 0; i < fnames.length; i++) {    const fname = fnames[i];    await getUsedFuncs(ctx, fname, funcs);  }  const funcCode = `{    ${Object.keys(funcs).map(fname => `${fname}:${funcs[fname]}`).join('/n')}  }`;  code = `ctx.methods=${funcCode};$[code]`;} else {  code = `ctx.methods={};$[code]`;}// 獲取所有依賴的函數const getUsedFuncs = async (ctx, funcName, methods) => {  const func = getFunc(funcName);  methods[funcName] = func.body;  if (func.use) {    const uses = func.use.split(',');    for (let i = 0; i < uses.length; i++) {      await getUsedFuncs(ctx,uses[i], methods);    }  }}

依賴循環

既然可以相互依賴,那必然會可能出現 a→b→c→a 這種循環的依賴情況,所以需要在開發者提交云函數的時候,檢測依賴循環。

檢測的思路也很簡單,在遍歷依賴鏈的過程中,每一個單獨的鏈條都記錄下來,如果發現當前遍歷到的函數在鏈條里出現過,則發生循環。

const funcMap = {};flist.forEach((f) => {  funcMap[f.name] = f;});const chain = [];flist.forEach((f) => {  getUseChain(f, chain);});function getUseChain(f, chain) {  if (chain.includes(f.name)) {    throw new Error(`函數發生循環依賴:${[...chain, f.name].join('→')}`);  } else {    f.use.forEach((fname) => {      getUseChain(funcMap[fname], [...chain, f.name]);    });  }}

4、性能

上述方案中,每次云函數執行的時候,都需要進行一下幾步:

  • 獲取函數體
  • 編譯代碼
  • 構造作用域和獨立環境
  • 執行

步驟3,因為每次執行的參數都不一樣,也會有不同請求并發執行同一個函數的情況,所以作用域 ctx 無法復用;步驟4是必須的,那么可優化點就剩下了1和2。

代碼緩存

vm 模塊提供了代碼編譯和執行分開處理的接口,因此每次獲取到函數體字符串之后,先編譯成 Script 對象:

// ...get codeconst script = new vm.Script(code);

執行的時候可以直接傳入編譯好的 Script 對象:

// ...get sandboxvm.createContext(sandbox);script.runInContext(sandbox);const data = await sandbox.promise;

函數體緩存

簡單的緩存,不需要很復雜的更新機制,定一個時間閾值,超過后拉取新的函數體并編譯得到 Script 對象,然后緩存起來即可:

const cacheFuncs = {};// ...get scriptcacheFuncs[funcName] = {  updateTime: Date.now(),  script,};// cache time: 60 secconst cacheFunc = cacheFuncs[cacheKey];if (cacheFunc && (Date.now() - cacheFunc.updateTime) <= 60000) {  const sandbox = { /*...*/ }  vm.createContext(sandbox);  cacheFunc.script.runInContext(sandbox);  const data = await saandbox.promise;  return data;} else {  // renew cache}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人精品999| 精品国产自在精品国产浪潮| 亚洲免费av网址| 精品亚洲夜色av98在线观看| 欧美午夜www高清视频| 中文字幕精品一区久久久久| 日本中文字幕成人| 国产精品久久久久福利| 国产精品视频中文字幕91| 欧美大片欧美激情性色a∨久久| 日本19禁啪啪免费观看www| 成人福利视频网| 亚洲色图狂野欧美| 日韩欧美中文第一页| 日韩av三级在线观看| 欧美重口另类videos人妖| 91深夜福利视频| 成人国产精品一区| 亚洲第一中文字幕在线观看| 日韩中文字幕在线看| 久久久国产一区| 日韩一区二区av| 人九九综合九九宗合| 深夜精品寂寞黄网站在线观看| 国产不卡av在线免费观看| 久久精品中文字幕电影| 久久中国妇女中文字幕| 国产亚洲精品久久久| 中文字幕欧美国内| 在线看日韩av| 国产午夜精品美女视频明星a级| 亚洲欧美日韩一区二区三区在线| 国产精品嫩草视频| 亚洲国产天堂久久国产91| 日韩精品久久久久久久玫瑰园| 亚洲成人久久久| 国产精品久久久久久久久久久不卡| 国产成人精品a视频一区www| 欧美电影在线观看网站| 亚洲欧美成人一区二区在线电影| 国产精品爽黄69| 欧美日韩爱爱视频| 久久久国产一区二区| 欧美激情亚洲另类| 亚洲天堂男人天堂| 国产精品久久久久久av下载红粉| 成人中文字幕在线观看| 美女久久久久久久| 欧美在线视频导航| 欧美日韩综合视频网址| 国产一区二区三区视频在线观看| 日韩欧美亚洲国产一区| 亚洲理论在线a中文字幕| 久久人人爽亚洲精品天堂| 中文字幕不卡在线视频极品| 欧美国产日韩视频| 日韩国产一区三区| 日韩小视频网址| 91精品在线播放| 国产精品免费一区二区三区都可以| 国产拍精品一二三| 97超级碰碰人国产在线观看| 欧美电影免费观看电视剧大全| 亚洲人成在线电影| 欧美精品videossex88| 欧美www视频在线观看| 日韩高清免费观看| 成人欧美在线观看| 国产一区二区免费| 国产亚洲xxx| 久久精品影视伊人网| 欧美高清在线视频观看不卡| 日韩在线观看成人| 亚洲精品色婷婷福利天堂| 欧美肥臀大乳一区二区免费视频| 91精品国产高清自在线| 57pao成人国产永久免费| 日韩欧美国产一区二区| 欧美性xxxxx极品| 日韩精品欧美激情| 一区二区三欧美| 国产精品视频一区二区高潮| 亚洲欧美日韩中文在线| 亚洲欧美制服第一页| 欧美有码在线观看| 亚洲精品中文字幕女同| 日韩电影免费在线观看中文字幕| 最近2019年中文视频免费在线观看| 久久99久久亚洲国产| 一道本无吗dⅴd在线播放一区| 欧美日韩久久久久| 中文字幕国产精品久久| 欧美日韩中文字幕在线| 精品视频9999| 久久久久久久久久久人体| 国产日韩亚洲欧美| 日韩av在线免费观看| 最近2019中文字幕mv免费看| 2019日本中文字幕| 国产成人精品日本亚洲| 精品露脸国产偷人在视频| 狠狠躁天天躁日日躁欧美| 日韩av在线看| 亚洲第一男人天堂| 欧美乱妇高清无乱码| 成人在线激情视频| 欧美日韩国产第一页| 国产精品美女呻吟| 色婷婷综合成人av| 久久精品国产精品| 国产日韩欧美在线看| 国内精品美女av在线播放| 国产色综合天天综合网| 91精品国产色综合久久不卡98口| 久久久久久香蕉网| 91人成网站www| 亚洲电影免费观看高清完整版在线观看| 2019中文字幕免费视频| 成人网址在线观看| 51久久精品夜色国产麻豆| 日本精品久久久| 青青草成人在线| 亚洲最大av在线| 亚洲日韩中文字幕在线播放| 全亚洲最色的网站在线观看| 亚洲精品成人久久电影| 日韩激情视频在线| 欧美成人免费va影院高清| 欧美成年人视频网站欧美| 影音先锋欧美精品| 国内免费精品永久在线视频| 国产精品av在线| 亚洲欧洲美洲在线综合| 亚洲国产成人精品久久久国产成人一区| 美女久久久久久久久久久| 亚洲精品mp4| 欧美一级免费视频| 日韩欧美精品网站| 日韩精品免费在线视频| 亚洲香蕉伊综合在人在线视看| 欧美日本啪啪无遮挡网站| 久久精品99国产精品酒店日本| 亚洲国产精品免费| 亚洲人成啪啪网站| 这里只有精品在线观看| 亚洲视频电影图片偷拍一区| 亚洲福利精品在线| 久久精品成人一区二区三区| 狠狠做深爱婷婷久久综合一区| 欧美一区深夜视频| 日韩精品免费一线在线观看| 欧美激情一级欧美精品| 午夜精品福利在线观看| 亚洲成色777777在线观看影院| 精品亚洲夜色av98在线观看| 国产91在线播放九色快色| 亚洲色图国产精品| 亚洲国产精品va在线看黑人| 91色中文字幕| 亚洲九九九在线观看| 国产精品视频男人的天堂| 久久久久久久久久久亚洲| 亚洲毛片一区二区| 国产91免费观看|