結合阿里雲 FC 談談我對 FaaS 的理解

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進入主題之前,先從背景簡述下最近前端界的熱點詞彙 Serverless,其實,Serverless 這個概念在其他領域已經提出來很久了。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Serverless"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"概念"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Serverless 直譯爲無服務器,代表一種"},{"type":"text","marks":[{"type":"strong"}],"text":"無服務器架構"},{"type":"text","text":"(也被稱爲“"},{"type":"text","marks":[{"type":"strong"}],"text":"無服務器計算"},{"type":"text","text":"”),並不表示不需要物理服務器,而是指不需要關注和管理服務器,直接使用服務即可,其實就是一種"},{"type":"text","marks":[{"type":"strong"}],"text":"服務外包"},{"type":"text","text":"或者說"},{"type":"text","marks":[{"type":"strong"}],"text":"服務託管"},{"type":"text","text":",這些服務由第三方供應商提供。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具體來說,Serverless 就是指服務端邏輯由開發者實現,運行在無狀態的計算容器中,由"},{"type":"text","marks":[{"type":"strong"}],"text":"事件驅動"},{"type":"text","text":",完全"},{"type":"text","marks":[{"type":"strong"}],"text":"被第三方管理"},{"type":"text","text":",而業務層面的狀態則記錄在"},{"type":"text","marks":[{"type":"strong"}],"text":"數據庫或存儲資源"},{"type":"text","text":"中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前國內一些大型公司如阿里、騰訊、滴滴都已經將 Serverless 逐步在業務中落地(案例分享:"},{"type":"text","marks":[{"type":"strong"}],"text":"2020.06.19 ServerlessDays · China Online"},{"type":"text","text":" (https:\/\/cloud.tencent.com\/developer\/salon\/live-1224))。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Serverless 與 FaaS 的聯繫"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Serverless = "},{"type":"text","marks":[{"type":"strong"}],"text":"FaaS + BaaS"},{"type":"text","text":" ,是目前界內比較公認的定義:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS(Function as a Service):函數即服務"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"負責"},{"type":"text","marks":[{"type":"strong"}],"text":"服務端業務邏輯場景"},{"type":"text","text":",需要開發者自己實現,服務的粒度比微服務更小,小到以函數爲單位"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"事件驅動"},{"type":"text","text":"的 Serverless 服務,毫秒級彈性伸縮"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"無法進行內存或數據共享,是"},{"type":"text","marks":[{"type":"strong"}],"text":"無狀態的"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"無需運維"},{"type":"text","text":",部署、運維等都由雲平臺提供"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"BaaS(Backend as Service):後端即服務"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/e1\/e139bf73ebf8d53dc3b244231163bb01.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"負責"},{"type":"text","marks":[{"type":"strong"}],"text":"通用服務場景"},{"type":"text","text":",不需要開發者自己開發,由雲廠商提供,比如數據庫、身份驗證、消息隊列、對象存儲等服務"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"是"},{"type":"text","marks":[{"type":"strong"}],"text":"有狀態"},{"type":"text","text":"的"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"筆者認爲,單看 FaaS 或者 BaaS,都是一種 Serverless ,只是一般我們完整的應用需要兩者結合才能實現。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"好,下面正式介紹 FaaS。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"FaaS"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作爲一個前端,我們平日裏很難接觸到服務器、運維方面的操作。假設現在給你一個任務,讓你自己開發一個有前後端交互的應用,並從 0 到 1 進行部署,是不是覺得光靠自己根本搞不定,這個任務有點難。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"傳統應用的部署,我們需要做很多工作:準備服務器、配置環境、購買域名、配置 Nginx、……。應用發佈之後,我們還要考慮運維的問題,線上監控,擴縮容,容災等等等等。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在,我們運用 FaaS 去開發部署的話,以上都不用考慮,只需要專注於業務邏輯開發即可,因爲"},{"type":"text","marks":[{"type":"strong"}],"text":"其它一切都託管給 FaaS 平臺"},{"type":"text","text":"幫我們處理了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"概念"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS  是無服務器計算的一種形式。通過 FaaS,可以快速構建任何類型的應用和服務,它具有開發敏捷特性、自動彈性伸縮能力、免運維和完善的監控設施。因此:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"開發者只需專注於業務邏輯開發,無需管理服務器、運行環境等 IT 基礎設施"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS 平臺會爲我們準備好計算資源,以彈性、可靠的方式運行我們的代碼,實現毫秒級"},{"type":"text","marks":[{"type":"strong"}],"text":"彈性伸縮"},{"type":"text","text":",輕鬆應對峯值壓力"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶只需根據函數的實際執行時間"},{"type":"text","marks":[{"type":"strong"}],"text":"按量付費"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,相比傳統開發模式,大大提高了開發和交付效率,是未來雲服務發展的大趨勢。自 2014 年始,在 AWS Lambda 之後,Google、IBM、Microsoft、阿里、騰訊、華爲等國內外雲廠商相繼推出雲函數計算平臺 FaaS。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"快速創建 FaaS 應用"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"函數計算開發方式有很多種,比如:Fun 工具、函數計算 FC 平臺、Serverless VScode、雲開發平臺。本文藉助"},{"type":"text","marks":[{"type":"strong"}],"text":"阿里雲函數計算平臺"},{"type":"text","text":"(https:\/\/fc.console.aliyun.com\/fc\/overview\/cn-shanghai),通過其提供的模版快速創建、部署一個 Web 應用,向大家更清楚地展示 FaaS 是什麼。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文直接基於模版創建,用戶也可以選擇自己上傳應用代碼直接部署 Web 應用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/36\/362b67e94d10e17c0fcb906ef2f0916d.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們選擇有前後端交互、數據增刪改查等行爲的 "},{"type":"text","marks":[{"type":"strong"}],"text":"Todo List 應用"},{"type":"text","text":",它是一個"},{"type":"text","marks":[{"type":"strong"}],"text":"前後端一體化"},{"type":"text","text":"(前後端代碼共屬一個項目中開發、調試、部署,高效且節省資源) FaaS 應用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/f3\/f36b11250edf862d1de5a882cd713ad2.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"服務\/函數"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"服務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個應用可以拆分爲多個服務。從資源使用維度出發,一個服務可以由多個函數組成。先創建服務,再創建函數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到 TodoList 應用部署成功後創建好的服務,我們可以對該服務進行配置、刪除、查看指標等操作,還可以對其下的函數進行配置、刪除。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/bd\/bdea67ee47b9b1bfc961fd0041313fd7.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"函數是系統調度和運行的單位。函數必須從屬於服務,同一個服務下可以有多個函數,同一個服務下的所有函數共享相同的設置,例如服務授權、日誌配置,但彼此相互獨立,互不影響。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"函數代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS 對"},{"type":"text","marks":[{"type":"strong"}],"text":"多種語言"},{"type":"text","text":"都有良好的支持性,比如阿里雲支持 Node.js、Python、PHP、Java 等等,開發者可以使用自己熟悉的語言,根據平臺提供的函數接口形式編寫代碼。這也意味着,團隊協作時,大家可以利用多種語言混合開發複雜應用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"點擊代碼執行,可以看到這裏有一個在線編輯器,裏面就是模板生成的代碼,可以在此處進行運行、調試。該應用前端頁面用 React 實現,後端服務基於 Node 的 Express 框架。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/68\/68d719bef97752ed74d43ef48b60f116.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"函數入口"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"template.yml"}]},{"type":"text","text":" 是我們的"},{"type":"text","marks":[{"type":"strong"}],"text":"函數信息配置文件"},{"type":"text","text":",告訴雲廠商我們的代碼入口函數、觸發器類型等操作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/bc\/bcc99142295dfae848af66c8cfcfc2c5.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"函數入口爲 "},{"type":"codeinline","content":[{"type":"text","text":"src\/index.handler"}]},{"type":"text","text":" ,即 "},{"type":"codeinline","content":[{"type":"text","text":"src\/index.js"}]},{"type":"text","text":" 服務端代碼文件中的 handler 方法,該文件代碼如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"const { Server } = require('@webserverless\/fc-express')\nconst express = require('express');\nconst fs = require('fs');\nconst path = require('path');\nconst bodyParser = require('body-parser');\n\n\/\/ initial todo list\nlet todos = [\n  {\n    id: '123',\n    text: 'Go shopping',\n    isCompleted: false,\n  },\n  {\n    id: '213',\n    text: 'Clean room',\n    isCompleted: true,\n  },\n];\n\n\nconst staticBasePath = path.join('public', 'build');\n\nconst app = express();\n\n\/\/ index.html\napp.all(\"\/\", (req, resp) => {\n  resp.setHeader('Content-Type', 'text\/html');\n  resp.send(fs.readFileSync('.\/public\/build\/index.html', 'utf8'));\n});\n\n\/\/ 靜態資源文件:js、css、圖片\n\/\/ static js resources  \napp.all('\/*.js', (req, resp) => {\n  const filePath = path.join(staticBasePath, req.path);\n  resp.setHeader('Content-Type', 'text\/javascript');\n  resp.send(fs.readFileSync(filePath, 'utf8'));\n});\n\n\/\/ static css resources\napp.all('\/*.css', (req, resp) => {\n  const filePath = path.join(staticBasePath, req.path);\n  resp.setHeader('Content-Type', 'text\/css');\n  resp.send(fs.readFileSync(filePath, 'utf8'));\n});\n\n\/\/ static svg resources\napp.all('\/*.svg', (req, resp) => {\n  const filePath = path.join(staticBasePath, req.path);\n  resp.setHeader('Content-Type', 'image\/svg+xml');\n  resp.send(fs.readFileSync(filePath, 'utf8'));\n});\n\n\/\/ static png resources\napp.all('\/*.png', (req, resp) => {\n  const filePath = path.join(staticBasePath, req.path);\n  resp.setHeader('Content-Type', 'image\/png');\n  resp.send(fs.readFileSync(filePath, 'utf8'));\n});\n\napp.all('\/manifest.json', (req, resp) => {\n  const filePath = path.join(staticBasePath, req.path);\n  resp.setHeader('Content-Type', 'application\/json');\n  resp.send(fs.readFileSync(filePath, 'utf8'));\n});\n\n\/\/ 增刪改查對應的api接口\n\/\/ list api\napp.get('\/api\/listTodos', (req, resp) => {\n  resp.send(JSON.stringify(todos));\n});\n\n\/\/ create api\napp.get('\/api\/createTodo', (req, resp) => {\n  const { todo: todoStr } = req.query;\n  const todo = JSON.parse(todoStr);\n  todos.push({\n    id: todo.id,\n    text: todo.text,\n    isCompleted: todo.isCompleted,\n  });\n  resp.send(JSON.stringify(todos));\n});\n\n\/\/ update api\napp.get('\/api\/updateTodo', (req, resp) => {\n  const { todo: todoStr } = req.query;\n  const targetTodo = JSON.parse(todoStr);\n  const todo = todos.find((todo) => todo.id === targetTodo.id);\n  if (todo) {\n    todo.isCompleted = targetTodo.isCompleted;\n    todo.text = targetTodo.text;\n  }\n  resp.send(JSON.stringify(todos));\n});\n\n\/\/ remove api\napp.get('\/api\/removeTodo', (req, resp) => {\n  const { id } = req.query\n  \/\/ TODO: Implement methods to filter todos, filtering out item with the same id\n  \/\/ todos = todos.filter();\n  const todosIndex = todos.findIndex((todo) => todo.id === id);\n  if (todosIndex !== -1) {\n    todos.splice(todosIndex, 1);\n  } \n  resp.send(JSON.stringify(todos));\n});\n\nconst server = new Server(app);\n\n\/\/ 向外暴露了 http觸發器入口\n\/\/ http trigger entry\nmodule.exports.handler = function(req, res, context) {\n  server.httpProxy(req, res, context);\n};\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到,我們不需要自己起服務,FaaS 平臺會爲我們管理。這個文件,有兩個重要的部分:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.函數入口 handler,也是 HTTP 觸發器入口,下文會詳細介紹"}]}]}]},{"type":"codeblock","attrs":{"lang":"typescript"},"content":[{"type":"text","text":"\/\/ http trigger entry\nmodule.exports.handler = function(req, res, context) {\n  server.httpProxy(req, res, context);\n};"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.Web Service 和 API,通過路由調用相應的服務,比如請求路徑爲\"\/\"時,會返回 Web 應用的 Html 頁面;請求\"\/api\/*\"時,調用接口返回數據"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"觸發器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前面說過,FaaS 是一種"},{"type":"text","marks":[{"type":"strong"}],"text":"事件驅動"},{"type":"text","text":"的計算模型,即函數的執行是由事件驅動的,沒有事件觸發,函數就不運行。與傳統開發模式不同,函數不需要自己啓動一個服務去監聽數據,而是通過綁定一個(或者多個)觸發器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"觸發器"},{"type":"text","text":"就是觸發函數執行的方式,我們需要爲函數創建指定的觸發器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS 應用的觸發器有多種(不同雲廠商的觸發器會有所區別),但基本都支持 HTTP、對象存儲、定時任務、消息隊列等觸發器,其中 HTTP 觸發器是最常見的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以阿里雲函數計算爲例,介紹幾個代表類型:"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"觸發器類型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":"
名稱描述
HTTP 觸發器1.HTTP 觸發器通過發送 HTTP 請求觸發函數執行,主要適用於快速構建 Web 服務等場
2.HTTP 觸發器支持 HEAD、POST、PUT、GET 和 DELETE 方式觸發函數
3.可以通過綁定自定義域名爲 HTTP 函數映射不同的 HTTP 訪問路徑
4.開發人員可以快速使用 HTTP 觸發器搭建 Web Service和 API
OSS 觸發器(對象存儲)1.OSS 事件能觸發相關函數執行,實現對 OSS 中的數據進行自定義處理
日誌服務觸發器1.當日志服務定時獲取更新的數據時,通過日誌服務觸發器,觸發函數消費增量的日誌數據,並完成對數據的自定義加工
定時觸發器1.在指定的時間點自動觸發函數執行
API 網關觸發器1.API 網關作爲事件源,當有請求到達後端服務設置爲函數計算的 API 網關時,API 網關會觸發函數的執行。函數計算會將執行結果返回給 API 網關
2.與 HTTP 觸發器類似,可應用於搭建 Web 應用。相較於 HTTP 觸發器,您可以使用 API 網關進行 IP 白名單或黑名單設置等高級操作"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"開發者在調試時,如果不配置觸發器,也可以使用控制檯、命令行工具 或者 SDK 等方式直接調用函數執行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們點開 TodoList 的觸發器,可以看到創建的 "},{"type":"text","marks":[{"type":"strong"}],"text":"HTTP 觸發器"},{"type":"text","text":",WEB 用戶通過 HTTP 請求即可觸發函數的執行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/07\/079a2c3a759a99203e26734afddd7597.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意這裏的提示語:打開鏈接,會下載一個 Html 附件,這時我們打開,因爲找不到靜態資源文件,應用不能正常運行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/8e\/8e15b415089a14b47b9f430b8a3d9db4.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以點擊"},{"type":"text","marks":[{"type":"strong"}],"text":"自定義域名"},{"type":"text","text":"去用平臺爲我們創建的"},{"type":"text","marks":[{"type":"strong"}],"text":"臨時域名"},{"type":"text","text":"打開:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/9f\/9fd0d0f2e8423edc4ae241fb74a65cbe.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到,頁面和功能都正常了。我們查看、新增、更新、刪除,在控制檯裏可以看到發起的請求和返回結果"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/1f\/1f003682f4f17b015e6db7357c73c3c3.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/da\/da09735ffcd524c5d2ff5e73d05c3382.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/21\/21a106b9c614d1dc31034408bf61c36b.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP 觸發器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該應用 "},{"type":"text","marks":[{"type":"strong"}],"text":"HTTP 觸發器的入口函數"},{"type":"text","text":"形式如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"\/\/ http trigger entry\nmodule.exports.handler = function(req, res, context) {\n  server.httpProxy(req, res, context);\n};"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"配置 HTTP 觸發器的函數可以通過 HTTP 請求被觸發執行。此時函數可以看做一個 Web Server,對 HTTP 請求進行處理,並將處理結果返回給調用端"},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"訪問 Html 頁面、請求靜態資源文件,以及請求接口,都是通過 HTTP 請求去觸發相應函數的執行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以在這裏進行調試:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/92\/922940f0dee33f941d7c8890a5b914f6.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"FaaS 框架"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前市面上已經有一些較爲成熟的開源 FaaS 框架,比如 OpenFaaS、Funktion、Kubeless、Fission等等,本文向大家介紹阿里雲今年正式發佈的 "},{"type":"text","marks":[{"type":"strong"}],"text":"Midway FaaS框架"},{"type":"text","text":" (https:\/\/github.com\/midwayjs\/midway),它是用於構建 Node.js 雲函數的 Serverless 框架,它提供了函數的本地"},{"type":"text","marks":[{"type":"strong"}],"text":"開發、調用、測試整個鏈路"},{"type":"text","text":"。它可以開發新的 Serveless 應用,也提供方案將傳統應用遷移至各雲廠商的雲函數。阿里內部已經使用一年多了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們可以運用腳手架 "},{"type":"codeinline","content":[{"type":"text","text":"@midwayjs\/faas-cli"}]},{"type":"text","text":" 提供的能力在"},{"type":"text","marks":[{"type":"strong"}],"text":"本地快速創建、調試、Mock、部署"},{"type":"text","text":"一個 FaaS 應用。Serverless 有一個很大的"},{"type":"text","marks":[{"type":"strong"}],"text":"弊端"},{"type":"text","text":",就是"},{"type":"text","marks":[{"type":"strong"}],"text":"和雲服務商平臺強綁定"},{"type":"text","text":",但是 Midway Serverles 是防平臺鎖定的,它能"},{"type":"text","marks":[{"type":"strong"}],"text":"一套代碼能夠運行在不同的平臺和運行時之上"},{"type":"text","text":",Midaway Faas 的部署可以"},{"type":"text","marks":[{"type":"strong"}],"text":"跨雲廠商"},{"type":"text","text":",默認部署到阿里雲 FC,我們也可以修改部署到其它平臺,如騰訊雲 SCF、AWS Lambda。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Midway FaaS 體系也與雲工作臺進行了結合,使用了和本地同樣的能力,這裏選擇登錄 "},{"type":"text","marks":[{"type":"strong"}],"text":"阿里雲開發平臺"},{"type":"text","text":" (https:\/\/workbench.aliyun.com\/application),用示例庫模版再次創建一個 TodoList 應用進行演示,只不過這個是用 Midway FaaS 構建的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/dc\/dc37299818000dbe150cb670ede10816.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"代碼目錄結構"},{"type":"text","text":"可以簡單抽取爲:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"|-- src\n|  |-- apis \/\/函數代碼\n|    |-- config \/\/針對不同環境創建配置文件\n|    |-- configuration.ts \/\/擴展能力配置\n|    |-- index.ts \/\/ 函數代碼入口文件,裏面包括多個函數\n|  |-- components \/\/ 前端組件\n|  |-- index.tsx \/\/ 前端頁面入口文件(該應用前端基於React,若是Vue,則是App.vue)\n|-- f.yml \/\/ 函數信息配置文件\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"f.yml 配置文件"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"service: serverless-hello-world\n\n\/\/ 服務提供商\nprovider:\n  name: aliyun\n  runtime: nodejs10 \/\/運行時環境及版本信息\n\n\/\/ 函數具體信息(包括函數入口、觸發器等等)\nfunctions:\n  render:\n    handler: render.handler \n    events:\n      - apigw:\n          path: \/*\n  list:\n    handler: todo.list \n    events:\n      - apigw:\n          path: \/api\/list\n  update:\n    handler: todo.update\n    events:\n      - apigw:\n          path: \/api\/update\n  remove:\n    handler: todo.remove\n    events:\n      - apigw:\n          path: \/api\/remove\n  add:\n    handler: todo.add\n    events:\n      - apigw:\n          path: \/api\/add\n          \n\/\/ 構建的配置信息\npackage:\n  include:\n    - build \/\/打包目錄\n  artifact: code.zip \/\/打包名稱\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"函數代碼中一個函數對應一個 API 接口:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/cc\/cc1d70fa4a36e07c5932fbfc37b3460e.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"安裝依賴後,我們 "},{"type":"codeinline","content":[{"type":"text","text":"npm run dev"}]},{"type":"text","text":",阿里云爲我們創建了一個臨時域名用於調試:"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/86\/86e650e931f4c29eb573db4e68d54c92.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到請求的這些資源和接口數據:"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/a8\/a89810f17069c666e4f0fbfe702c4d7d.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一鍵部署,非常方便。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/45\/4520dfa1c31d90dcddd7d607b8be11fb.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"收費標準"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"傳統應用我們的服務是一直佔用資源的,而 FaaS 在資源空閒時不收費,"},{"type":"text","marks":[{"type":"strong"}],"text":"按需付費"},{"type":"text","text":",可以大大節省開支。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"收費標準:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"調用函數次數"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"函數運行時間"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲每月都有免費額度,所以在個人日常使用時基本不需要付費。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/54\/5452b7b101bce31afdb70d880a785e3d.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(PS:但還是要特別注意,部署的應用不用時一定要及時下線,否則可能會收取費用,還有開通的服務、功能也一定要仔細留意一下收費標準,比如可能想解決冷啓動的問題,會開通預留實例功能,如果我們不用的話,一定要注意手動釋放,否則即使它沒有執行任何請求,也會從啓動開始不斷收費,費用可不小)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"冷啓動"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再說說 FaaS 目前備受關注的一個問題——"},{"type":"text","marks":[{"type":"strong"}],"text":"冷啓動"},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS 中的函數"},{"type":"text","marks":[{"type":"strong"}],"text":"首次調用"},{"type":"text","text":"、"},{"type":"text","marks":[{"type":"strong"}],"text":"更新函數或長時間未調用時重新調用函數"},{"type":"text","text":"時,平臺會初始化一個函數實例,這個過程就是"},{"type":"text","marks":[{"type":"strong"}],"text":"冷啓動"},{"type":"text","text":",平均耗時在幾百毫秒。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"延遲問題"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS 因爲冷啓動,不能立即調用函數,調用延遲會給應用性能帶來影響,針對冷啓動的延遲問題,各大雲服務商非常關注,正在想辦法不斷優化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與冷啓動相呼應的是熱啓動,"},{"type":"text","marks":[{"type":"strong"}],"text":"熱啓動"},{"type":"text","text":"指函數調用時不用重新創建新的函數實例,而是直接複用之前的函數實例。因爲 FaaS 函數若在一段時間內沒有被事件觸發運行,雲服務商就會回收運行函數的容器資源,銷燬函數實例,所以,在未被回收的這段時間內再次調用函數就是熱啓動;銷燬後,重新創建就是冷啓動。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"延遲原因"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"冷啓動具體做了哪些操作呢?以阿里云爲例,大致包括了調度實例、下載解壓代碼、啓動容器、啓動運行時,這一過程結束後,函數纔開始執行。所以冷啓動的啓動消耗時間受到很多因素的影響:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"編程語言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有專門研究對比,不同語言的冷啓動時間不同"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代碼大小"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個過程在冷啓動過程中相對比較耗時,可能幾十毫秒,也可能幾秒,看代碼體積大小"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器創建"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個過程的耗時取決於雲服務商"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"配置等"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"如何優化"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"各大雲廠商都已經有了一些優化方案的最佳實踐,需要開發者和雲廠商共同努力:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"減少代碼體積:"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"開發者可以通過精簡代碼,刪除無用依賴,加速下載函數代碼過程"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如騰訊雲對代碼做了兩級的緩存,可以有效降低下載代碼時間"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"資源複用,縮短函數執行時間"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"選擇冷啓動時間較少的語言"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"選擇合適的內存:函數內存越大,冷啓動表現越優"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"避免不必要的配置"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"降低冷啓動頻率"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用定時觸發器定時訪問函數,這樣可以防止函數實例一段時間沒被使用被銷燬"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 initializer 函數入口,函數計算會異步調用初始化接口,消除初始化用戶代碼的時間"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"預留實例"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"執行時長"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FaaS 還有一個侷限性,就是平臺會限制函數的執行時間,超出時間後執行代碼的進程會被強行銷燬,所以 FaaS 不適合長時間運行的應用。例如 AWS Lambda 函數不允許運行超過 15 分鐘(以前只有 5 分鐘),如果超過就會中斷。使用時,應該根據自己的預期執行時間來設置超時值,防止函數的運行時間超出預期,並且建議調用函數的 Client 端的 timeout 要稍稍大於函數設置的 timeout,這樣才能防止執行環境不會意外退出。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"FaaS 工作流程"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相信大家讀到這裏,應該差不多可以明白 FaaS 的工作流程了,我們總結一下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"開發者編寫"},{"type":"text","marks":[{"type":"strong"}],"text":"函數代碼"},{"type":"text","text":",可以在線編輯或者本地上傳,完成後,FaaS 平臺爲我們部署應用,創建"},{"type":"text","marks":[{"type":"strong"}],"text":"函數服務"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"客戶端通過設置的"},{"type":"text","marks":[{"type":"strong"}],"text":"觸發器"},{"type":"text","text":",通知"},{"type":"text","marks":[{"type":"strong"}],"text":"函數服務"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"若存在"},{"type":"text","marks":[{"type":"strong"}],"text":"函數實例"},{"type":"text","text":",則直接在該執行環境中調用函數;沒有,則先經過"},{"type":"text","marks":[{"type":"strong"}],"text":"冷啓動"},{"type":"text","text":"(調度實例、下載代碼、啓動實例、啓動運行時),再執行函數"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"函數根據用戶請求量動態擴容響應請求,將內容返回給用戶。函數執行完後,若一段時間內無事件觸發,函數實例就會被銷燬,FaaS 應用快速縮容到 0"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/02\/02b8cd00917911a1c4e3ca0c7c5df662.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"對前端的影響"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Serverless 現在這麼熱,它對前端到底有什麼影響呢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"整個實踐下來發現,FaaS 幫我們前端擴展了能力邊界,作爲前端,我們自己一個人也能快速完成前後端開發以及部署工作,完全不用關心服務器以及運維方面我們不擅長的問題。前端也有機會參與服務端業務邏輯開發,更深入業務,創造更大的價值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"結語"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文結合阿里雲 FC、Midway FaaS 框架快速創建 FaaS 應用的實踐,向大家展示了什麼是 FaaS,FaaS 的工作流程,優缺點,展現了 FaaS 顛覆傳統開發模式的魅力。現在 FaaS 的應用場景非常廣泛,Web 應用及小程序等移動應用、AI 及機器學習、物聯網、實時數據處理、……、等等。Serverless 時代,生產效率大大提高,每個人都有更多機會創造無限可能,讓我們一起爲未來加油!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"頭圖:Unsplash"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作者:雪霽"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文:https:\/\/mp.weixin.qq.com\/s\/cZm1sdMB7Cid48KD-0mpkA"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文:結合阿里雲 FC 談談我對 FaaS 的理解"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"來源:政採雲前端團隊 - 微信公衆號 [ID:Zoo-Team]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轉載:著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章