做者 | 宋文龍(聞可) 阿里雲全球技術服務部高級交付專家html
什麼是無服務計算
無服務器計算(Serverless Computing)在構建和運行應用時無需管理服務器等基礎設施。它描述了一個細粒度的部署模型,在該模型中,應用被拆解爲一個或多個細顆粒度的函數,在雲端託管環境中被觸發運行,而後根據須要執行、擴展容量而且計費。各大雲廠商 Amazon、微軟、Google、IBM、阿里雲、騰訊雲、華爲雲相繼推出 Serverless 產品。node
無服務計算自己是一個概念或者理論模型,落地到具體技術上主要有函數即服務(FaaS)以及後端即服務(BaaS)兩種形式,阿里雲提供函數即服務 FaaS 產品。mongodb
阿里雲對於 FaaS 的定義以下:docker
函數計算是事件驅動的全託管計算服務。使用函數計算,您無需採購與管理服務器等基礎設施,只需編寫並上傳代碼。函數計算爲您準備好計算資源,彈性地、可靠地運行任務,並提供日誌查詢、性能監控和報警等功能。數據庫
關於 FaaS 的詳細介紹官方文檔已經講的很清楚,本文再也不贅述。本文重點討論無服務計算的應用場景以及應用實踐。json
無服務計算應用場景
1. 無服務計算的優點
無服務計算有不少優勢,我的認爲其中最主要的有三點:後端
- 使用無服務計算,用戶無需考慮基礎設施,能夠更加專一於業務邏輯;
- 無服務計算支持彈性伸縮,按需使用,按量計費,很是適合流量不穩定、有明顯波峯波谷的業務;
- 無服務計算是雲原生產品,能夠無縫對接各類雲上產品,做爲黏合劑串聯各類雲原生產品。
下圖說明了阿里雲 FaaS 產品的核心優點:api
2. 無服務計算應用場景
前面探討了無服務計算的優點,那麼無服務計算都有哪些典型的應用場景呢?安全
在此分享筆者以前在項目中構建無服務應用的兩個案例:bash
- 雲端視頻轉碼:
- 技術方案:設備端捕獲短視頻,上傳到雲端存儲(例如阿里雲 OSS),雲端存儲監測到文件上傳後觸發無服務計算函數函數,函數中調用 FFmpeg 給視頻加水印、加特效,將視頻轉碼後再轉存到雲端存儲上,同時通知業務服務更改視頻狀態。
- 方案優點:設備端視頻上傳頻率很不穩定,可能有一段時間全部設備空閒,也有可能某一段時間幾千臺設備同時上傳,而視頻轉碼是比較消耗資源的,若是經過普通服務器提供轉碼能力並要確保全部視頻都能在預期時間內轉碼完成的話,必須按最高併發量配置服務器資源,這些服務器成本是至關可觀的。即便雲服務器採用 Auto Scalling 策略,也需常備部分服務器,沒法作到不使用時零運行成本,並且雲服務 Auto Scalling 觸發及啓動時間也是分鐘級的,很難達到服務能力秒級快速伸縮。
- 物聯網設備監控:
- 技術方案:設備端經過雲原生 IoT 服務上報狀態,雲原生 IoT 服務收到消息後觸發無服務計算函數,函數中對 IoT 原始消息作簡單清洗後轉發到後端服務作進一步業務處理,例如:發推送消息給設備管理 App,固然也能夠經過函數將 IoT 消息轉存到 NoSQL 數據庫。
- 方案優點:端側設備活躍時間不固定,若是想經過其餘後端服務監控設備狀態, 該服務必須保持 7*24 小時在線,架構和應用都須要確保高可用。並且設備併發量也是不穩定的,要考慮服務伸縮架構。還有一點須要考慮的是,雲端資源經過事件或者規則直接喚起無服務計算函數比價方便,只須要簡單配置便可,而對接自定義服務則要複雜得多。
基於項目經歷以及我的理解,筆者認爲無服務計算主要有如下幾種典型的應用場景:
- 可分解成獨立運行單元的 CPU 密集計算型任務;
- 構建彈性伸縮 Web 後臺應用;
- 無縫粘合調度雲上資源;
- 快速低成本上線敏捷應用。
3. 無服務計算不適合作什麼
前面列舉了不少無服務計算的優勢以及運用在一些場景中的好處,不少人確定以爲無服務計算太好用了,太想用了,這個場景可否用無服務計算?那個業務可否用無服務計算代替?
這裏筆者可能要先潑一瓢冷水:無服務計算很好用,但不必定到處好用。固然這瓢冷水以及接下來的一些總結只是基於我的理解, 歡迎拍磚。
我的認爲無服務計算其實只適合應用在一些邏輯相對簡單、外部依賴相對較少、不須要複雜編排治理、沒有極致性能要求的業務,主要緣由以下:
- 無服務計算在服務編排以及服務治理方面是比較弱的,雖然主流雲廠商都提供無服務計算的函數編排產品(例如阿里雲的 Serverless 工做流,AWS 的 Step Functions 等),但想要實現函數的限流降級、調用鏈追蹤、自動註冊發現等比較複雜的編排治理以及可探測性仍是須要作不少額外的工做,彌補這些不足所要作的工做遠大於無服務計算自己節省的工做量。這點也是和無服務計算無需運維、配置簡單、開箱即用的思想是背道而馳的。
- 無服務計算應用運行所依託的底層服務器以及運行環境對用戶是透明的,用戶沒法選擇,也沒法優化。例如在筆者以前的視頻轉碼方案中,有些特效處理若是運行在 GPU 服務器上是能夠大幅加速的,可是在無服務計算中只能依靠 CPU 計算。
- 無服務計算程序運行的環境是高度標準化的,有些依賴於特定運行環境、特定服務器版本、甚至特定硬件資源的依賴是很難確保兼容性的。若是有些應用尤爲是原有技術資產受到運行環境制約的話,儘可能仍是迴歸到傳統的雲服務器部署方案。
- 無服務計算的彈性伸縮並不是沒有上限,和普通應用同樣,無服務應用在實際生產系統中也須要考慮併發達到上限的狀況。雖然全部廠商的無服務計算產品都能根據併發量彈性伸縮,但這個彈性自己仍是靠底層硬件資源支撐的,通常來說各廠商的無服務計算產品都會有默認的併發上限設置,雖然經過工單申請能夠調整,但也不能調整爲無限量。若是帳號下有多個無服務應用,須要對不一樣應用作的流量分配或者限制,而且考慮某一應用訪問流量達到併發上限的狀況。
4. 無服務可否替代微服務
筆者認爲這二者應該不是一個維度的概念,微服務更多的是一種服務構建的架構思想,而無服務更偏重於一種服務部署和運行的技術方案,例如:微服務架構中某一個接口是能夠經過無服務方式實現的。
固然,涉及到具體技術層面,經過 SpringCloud 或者 Dubbo 對外提供 RESTful 接口服務,仍是將無服務函數掛載到 API 網關下對外提供 RESTful 服務,這兩種技術方案確實是能夠放到一塊兒比較的。至於選擇哪一種技術實現,我的認爲主要取決於運用場景和業務複雜度,前面總結了無服務計算的優點和不必定那麼好用的場景。下面是我的的建議:
- 若是應用中須要複雜的服務編排、服務治理、調用鏈追蹤、統一的配置管理、自動註冊發現等能力,建議仍是採用「傳統的」微服務技術方案;
- 相反,若是隻須要構建一個「短平快」的應用,採用無服務計算方案會讓你好體驗到極大的便利。正如筆者接下來將要分享的案例,就是採用無服務技術構建一個簡單的 Web 後臺應用。
阿里雲 FaaS 實戰
前面談了比較多抽象的概念和見解, 下面結合筆者經歷的一個實際案例展現如何使用阿里雲 FaaS 產品構建一個無服務應用,尤爲是實現 FaaS 應用的自動構建、自動部署。
1. 項目背景介紹
某外企客戶須要將一個爲用戶提供產品諮詢的服務從某友商無服務平臺遷移到阿里雲 FaaS。這個應用原部署於友商海外平臺,基於 Nodejs 開發,經過 API Gateway 暴露 RESTful 接口,數據存儲採用友商雲原生 NoSQL 數據庫。
遷移改造主要涉及如下三部分工做:
- 阿里雲產品適配選型
- 代碼邏輯改造
- 應用部署工具選擇及腳本編寫
其中第三部分構建、部署腳本改造是這次遷移工做的重點,接下來逐一展開說明。
2. 阿里雲產品適配選型
友商的無服務計算及網關在阿里雲上均有對應產品,在此不展開比較。
友商雲原生 NoSQL 數據庫爲該平臺獨有產品,通過和客戶討論認爲,徹底能夠用其餘 NoSQL 產品代替,加之現有開發人員更熟悉 MongoDB 技術棧,最後數據存儲選型爲阿里云云原生 MongoDB。
如下爲總體遷移方案示意圖:
3. 代碼邏輯改造
用戶編寫無服務應用代碼時,原則上只須要關注代碼邏輯便可,主體代碼邏輯部分大致上差別不大,比較明顯的差別主要體如今事件處理入口函數寫法上。參考FaaS 代碼示例改造針對 API 網關事件的處理函數:
module.exports.handler = function(event, context, callback) { var response = {}; callback(null, response); };
4. 應用部署工具選擇及腳本編寫
- 應用構建及部署工具選擇
客戶原來採用第三方工具 Serverless (https://www.serverless.com/) 實現無服務計算應用的構建和部署。Serverless 框架雖然宣稱支持幾乎全部主流雲廠商的無服務產品,但通過調研後發現其對某友商支持是最全面的,有不少代碼示例或者工程腳手架,幾乎是開箱即用。但該工具對阿里雲的支持比較有限,示例也相對較少。通過評估,咱們決定採用阿里雲本身的工具 Funcraft。
Funcraft 如何安裝配置請參考產品文檔,此處不展開討論。接下來主要展現如何經過 Funcraft 腳本實現服務、函數、網關、日誌、鑑權等相關資源的部署及配置。
- 編寫腳本
編寫腳本前,先看一下目標系統的部署架構以及 Funcraft 要實現的功能藍圖:
Funcraft 腳本及配置說明詳見如下代碼:
yaml ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: demoService: #資源名稱, 根據須要命名 Type: 'Aliyun::Serverless::Service' Properties: #屬性設置 Description: 'This is a faas demo ' #資源描述 Policies: #安全策略,系統自動根據策略爲函數建立角色 - AliyunOSSFullAccess - AliyunRAMFullAccess - AliyunLogFullAccess - AliyunApiGatewayFullAccess - AliyunFCFullAccess - AliyunMongoDBFullAccess - AliyunVPCFullAccess - AliyunECSNetworkInterfaceManagementAccess #特別說明,配置此策略才能建立彈性網卡進而打通函數以及VPC內鏈接 VpcConfig: #容許函數訪問的VPC配置 VpcId: 'vpc-xxxxxx' VSwitchIds: ['vsw-xxxxxx'] SecurityGroupId: 'sg-xxxxxx' LogConfig: #日誌服務配置 Project: sls-demo Logstore: logstore-demo demoFunction: #函數名稱 Type: 'Aliyun::Serverless::Function' #資源類型爲服務,服務內能夠掛載多個函數 Properties: Handler: index.handler #事件處理入口 Runtime: nodejs10 #程序運行環境 CodeUri: './src' #程序代碼相對於當前腳本的路徑 EnvironmentVariables: #環境變量設置, MONGO_URL: mongodb://userx:pwdx@dds-xxx.mongodb.rds.aliyuncs.com:3717/demoDb #Mongo內網鏈接地址 RESULT_TABLE_NAME: demo_table demoGroup: # Api Group Type: 'Aliyun::Serverless::Api' #資源類型爲API,每一個API分組下能夠掛載多個API接口 Properties: StageName: RELEASE #發佈環境 DefinitionBody: '/v1/recommendervera/[resultId]': # request path get: # http method x-aliyun-apigateway-api-name: demo_api # api name x-aliyun-apigateway-fc: # 當請求該 api 時,要觸發的函數, arn: acs:fc:cn-shanghai:xxx:services/demoService.LATEST/functions/demoFunction timeout: 3000 x-aliyun-apigateway-request-parameters: #設置參數類型 - apiParameterName: 'resultId' location: 'Path' #傳參方式,此處爲在URI請求路徑中傳餐 parameterType: 'String' required: 'REQUIRED' #設置爲必選參數 '/v1/recommendervera/': # request path post: # http method x-aliyun-apigateway-api-name: demo_api_post # api name x-aliyun-apigateway-fc: # 當請求該 api 時,要觸發的函數, arn: acs:fc:cn-shanghai:xxxx:services/demoService.LATEST/functions/demoFunction timeout: 3000 x-aliyun-apigateway-auth-type: APP #設置鑑權類型,此處設置爲簡單的APP code類型鑑權 x-aliyun-apigateway-app-code-auth-type: HEADER #鑑權加密方式,此處設置爲經過Header傳遞受權後的app
- 資源準備
服務、函數、API 網關均可以經過以上Funcraft 腳本一站式建立完成,日誌、MongoDB、鑑權所需應用等外部資源須要提早建立或者配置好。
這裏特別要說明的是:函數經過內網連接 MongoDB 時,須要經過配置容許函數訪問 MongoDB 所在 VPC 及交換機,併爲函數訪問建立一個獨立的安全組用於配置彈性網卡,而且將此安全組加入到 MongoDB 的白名單中,進而打通函數計算與 VPC 之間的網絡聯通。
前面提到的 VPC、交換機以及安全組已經提早建立好並配置在 Funcraft 腳本中了,下面看看在實際的 MongoDB 資源中如何配置白名單安全組:
5. 構建和部署
以上腳本資源都準備好後,就能夠執行 fun build 命令進行構建了。構建時,工具會讀取指定代碼目錄下的 package.json 文件加載相關插件依賴及配置。
構建執行命令示例:
bash $ fun build using template: template.yml start building function dependencies without docker building demoService/demoFunction running task: flow NpmTaskFlow running task: CopySource running task: NpmInstall Build Success Built artifacts: .fun/build/artifacts Built template: .fun/build/artifacts/template.yml Tips for next step ====================== * Invoke Event Function: fun local invoke * Invoke Http Function: fun local start * Deploy Resources: fun deploy
構建完成後, 執行 fun deploy 命令部署到雲端。示例以下:
bash $ fun deploy using template: .fun/build/artifacts/template.yml using region: cn-shanghai using accountId: ***********3452 using accessKeyId: ***********1fap using timeout: 60 Collecting your services information, in order to caculate devlopment changes... Resources Changes(Beta version! Only FC resources changes will be displayed): ┌──────────────┬──────────────────────────────┬────────┬──────────────────────┐ │ Resource │ ResourceType │ Action │ Property │ ├──────────────┼──────────────────────────────┼────────┼──────────────────────┤ │ │ │ │ Description │ │ │ │ ├──────────────────────┤ │ │ │ │ Policies │ │ demoService │ Aliyun::Serverless::Service │ Add ├──────────────────────┤ │ │ │ │ VpcConfig │ │ │ │ ├──────────────────────┤ │ │ │ │ LogConfig │ ├──────────────┼──────────────────────────────┼────────┼──────────────────────┤ │ │ │ │ Handler │ │ │ │ ├──────────────────────┤ │ │ │ │ Runtime │ │ demoFunction │ Aliyun::Serverless::Function │ Add ├──────────────────────┤ │ │ │ │ CodeUri │ │ │ │ ├──────────────────────┤ │ │ │ │ EnvironmentVariables │ └──────────────┴──────────────────────────────┴────────┴──────────────────────┘ ? Please confirm to continue. Yes Waiting for service demoService to be deployed... make sure role 'aliyunfcgeneratedrole-cn-shanghai-demoService' is exist role 'aliyunfcgeneratedrole-cn-shanghai-demoService' is already exist attaching policies ["AliyunOSSFullAccess","AliyunRAMFullAccess","AliyunLogFullAccess","AliyunApiGatewayFullAccess","AliyunFCFullAccess","AliyunMongoDBFullAccess","AliyunVPCFullAccess","AliyunECSNetworkInterfaceManagementAccess"] to role: aliyunfcgeneratedrole-cn-shanghai-demoService attached policies ["AliyunOSSFullAccess","AliyunRAMFullAccess","AliyunLogFullAccess","AliyunApiGatewayFullAccess","AliyunFCFullAccess","AliyunMongoDBFullAccess","AliyunVPCFullAccess","AliyunECSNetworkInterfaceManagementAccess"] to role: aliyunfcgeneratedrole-cn-shanghai-demoService attaching police 'AliyunECSNetworkInterfaceManagementAccess' to role: aliyunfcgeneratedrole-cn-shanghai-demoService attached police 'AliyunECSNetworkInterfaceManagementAccess' to role: aliyunfcgeneratedrole-cn-shanghai-demoService Waiting for function demoFunction to be deployed... Waiting for packaging function demoFunction code... The function demoFunction has been packaged. A total of 1675 files were compressed and the final size was 2.1 MB function demoFunction deploy success service demoService deploy success Waiting for api gateway demoGroup to be deployed... URL: GET http://xxx-cn-shanghai.alicloudapi.com/v1/recommender/[resultId] stage: RELEASE, deployed, version: 20200715144450426 stage: PRE, undeployed stage: TEST, undeployed URL: POST http://xxx-cn-shanghai.alicloudapi.com/v1/recommender/ stage: RELEASE, deployed, version: 20200715144453967 stage: PRE, undeployed stage: TEST, undeployed api gateway demoGroup deploy success
腳本正常執行後,能夠在雲端看到相關函數及 API 已經部署完成而且能夠正常運行了。
接下來能夠將以上 Funcraft 命令及腳本能夠加入到 Jenkins、Gitlab 等工具流水線中,結合代碼版本管理工具實現函數應用的持續集成、持續發佈。
總結
隨着無服務計算產品和技術的進一步成熟,會有愈來愈多的用戶選擇無服務計算技術;隨着阿里雲的進一步發展壯大,也會有愈來愈多用戶採用阿里雲 FaaS 構建無服務應用。
本文探討了無服務計算的應用場景,而且結合實際應用案例,講解了如何用 FaaS 構建無服務 Web 後臺應用,並實現自動構建、自動部署,但願以上探討和經驗可以幫到你們。
做者簡介
宋文龍,花名聞可,阿里雲全球技術服務部高級交付專家,有多年雲原生應用開發架構經驗以及多年高性能服務器研發經驗。目前專一於運用阿里雲中間件技術、結合阿里巴巴中臺架構經驗爲客戶構建符合行業須要的業務中臺解決方案並完成交付。
課程推薦
爲了更多開發者可以享受到 Serverless 帶來的紅利,這一次,咱們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發者入門的 Serverless 公開課,讓你即學即用,輕鬆擁抱雲計算的新範式——Serverless。
點擊便可免費觀看課程:https://developer.aliyun.com/learning/roadmap/serverless
Serverless 公衆號,發佈 Serverless 技術最新資訊,聚集 Serverless 技術最全內容,關注 Serverless 趨勢,更關注你落地實踐中的遇到的困惑和問題。