聊一聊Serverless

Serverless是什麼

從單詞角度理解,server譯爲服務,less譯爲少,Serverless能夠理解爲無服務或輕服務。前端

從語義角度理解,之因此叫輕服務,是由於和傳統的PaaS(平臺即服務)相比,用戶不須要關心服務器的部署與配置。但這並不意味着不須要服務器,只是這些東西皆由雲平臺來提供。java

從架構角度理解,Serverless=FaaS+事件驅動+BaaS=無服務器計算(Serverless computing)node

  • Faas:Function as a Service,函數即服務
  • 事件驅動:經過事件觸發的形式去完成函數的調用,處理請求和響應(如定時任務/http請求…)
  • Baas:Backend as a Service 後端即服務

雲計算髮展過程

下圖爲雲計算髮展的整個過程,同時也是Serverless的發展過程,共分爲四個階段。python

在這裏插入圖片描述

物理機階段:此時若是進行一個網站的開發是極爲麻煩的,不只須要購置物理機,還要手動安裝各類運行環境,開發,部署,測試,上線。除此以外,還要在物理層面上解決電,網,硬件磨損等各類問題。數據庫

IaaS階段:IaaS指的是基礎設施即服務。隨着虛擬化技術的不斷髮展,出現了不少基於虛擬化的雲廠商和產品,如阿里雲ESC。這個階段,無需自建機房,採購以及配置硬件設施,雲平臺會提供這些基礎設施。也正因如此,那些物理層面的電,硬件磨損什麼的,用戶無需關注。編程

PaaS階段:PaaS指的是平臺即服務。所謂的平臺,實際上是結合業務發展,在IaaS基礎上,將一些如數據庫,中間件等通用功能作成服務。虛擬化技術可讓用戶沒必要關心硬件問題,後來出現的容器技術可讓用戶沒必要關心運行環境差別的問題。容器技術出現後,意味着服務器上部署的再也不是應用,而是容器。當容器多了後,可經過k8s進行管理。後端

Serverless階段:這個階段是真正解放生產,專一業務的階段。在FaaS層面,應用由諸多個獨立的函數組成,每一個函數實現各自的業務邏輯。在數據獲取層面,BaaS 將後端能力封裝成了服務,並以接口的形式提供給FaaS。事實上,數據庫的增刪改查恰好對應Restful API的POST/DELETE/PUT/GET。數組

Serverless的優點

專一業務,快速迭代性能優化

首先,雲平臺從開發人員手中接過服務部署,配置等運維工做,開發人員壓力減少,只需關注業務開發自己便可。其次,傳統開發模式下,一個完整的開發流程須要通過先後端並行開發,後端部署,聯調測試,上線等過程,比較繁雜。而Serverless可讓前端人員跨過server直接和數據庫交互(FaaS+BaaS),極大地簡化了開發流程。服務器

節省維護和運營成本

服務提供方無需在業務上線前預估資源,也無需單獨購置服務器。Serverless會根據實際請求數量進行自動擴縮容,實行按需計費。在空閒狀況下,憑藉短期內完成冷啓動的優點,Serverless能夠縮容的極致爲0,即無任何計算消耗,這也是PaaS作不到的。從這點上考慮,那些天天大部分時間都沒有流量或者有不多流量的應用是極爲適合Serverless落地的。

在這裏插入圖片描述

Serverless的不足

狀態管理能力弱(針對FaaS)

爲了保證能夠自動擴縮容,FaaS應用就必須是無狀態的。有狀態的服務就要考慮數據的存儲,須要BaaS的支持。

調試困難

本地環境和雲環境始終是有區別的,有些報錯信息只能在雲環境查看,並且某些問題不太容易定位是本地環境仍是雲環境的產生的。

雲函數

定義

雲函數能夠看做是Serverless的產品之一,每個函數均可以看做是一個服務。

與此同時,雲函數也具有FaaS能力,是FaaS模式的具體實現。

觸發器

觸發器用於觸發某一類事件,不一樣雲平臺支持的觸發器類型也可能不一樣,但基本上每一個雲平臺都會包含HTTP觸發器和定時觸發器兩大類型。

HTTP觸發器對於客戶端而言,就是一個可訪問的數據接口。

定時任務類型的觸發器,會在指定時間週期內執行某一任務。

爲限制頻繁調用,幾乎全部雲平臺都會對定時的時間粒度進行限制,如最小一分鐘。

體驗

在這裏插入圖片描述

冷啓動

定義

在Serverless computing世界中,函數是按需運行的,若是沒有請求,就不會有函數實例佔用函數服務資源。這種僅在必要時運行函數的整個執行過程,被稱爲冷啓動。

下圖爲冷啓動包含的階段以及雲廠商和開發者各自所負責的部分。

在這裏插入圖片描述

  • 下載代碼: FaaS 平臺自己不會存儲代碼,這也是爲了可以縮容到0。上傳或本身編寫的代碼實際上會被放在存儲服務中,在冷啓動過程當中會從存儲服務中獲取函數代碼後下載。
  • 啓動容器: 代碼下載完成後,FaaS 會根據函數的配置,啓動對應容器。也正是經過容器技術,FaaS 可保證每一個函數的獨立性。
  • 初始化運行環境: 分析代碼依賴、執行用戶初始化邏輯、初始化入口函數以外的代碼等。
  • 運行代碼: 調用入口函數執行代碼。這個階段比較特別,多是冷啓動,也多是熱啓動。

熱啓動

FaaS有兩種模式,一種是用完即毀,對應從0到1的冷啓動。

另外一種是常駐內存,對應函數實例可複用的熱啓動(串行)。

常駐不是永久,若是一段時間內沒有事件觸發,函數實例仍是會被銷燬的。

熱啓動雖然在必定程度上能夠提升請求處理效率和應用性能,但某些狀況下也要特別注意,熱啓動可能不是咱們想要的。

在某些涉及時間的場景,咱們須要將時間的生成放在入口函數中用以保證每次函數執行後時間從新計算。若是這部分代碼放在入口函數以外,那麼在最初冷啓動後,熱啓動使用的一直就是舊的時間,且不會更新。

請求響應鏈路

解釋完冷啓動後,再來看一下完整的請求響應鏈路。

在這裏插入圖片描述

  1. 用戶發起請求,觸發器接收
  2. 事件驅動,觸發器通知函數服務處理http請求
  3. 函數服務進行函數實例檢查,有則調用,沒有則從函數代碼倉庫拉取後建立再調用
  4. 函數將處理完的結果交給觸發器
  5. 觸發器將其響應到客戶端用戶
  6. 一段時間內若無事件觸發,FaaS應用縮容至0

函數實例

每個函數實例背後都是一個容器。FaaS 經過容器來隔離每一個函數實例,保證函數的獨立性。

以下圖所示,容器內最主要的是運行環境,包含編程語言,內置模塊,FaaS 內置依賴和函數代碼。

在這裏插入圖片描述

  • 編程語言:建立FaaS應用所指定的語言,如Node
  • 內置模塊:所選編程語言的內置模塊,如fs之於Node
  • FaaS 內置依賴:FaaS平臺爲便於開發者開發提供的某些默認依賴
  • 函數代碼:本身編寫的代碼

不一樣語言冷啓動時長排名

不一樣語言的冷啓動時長是有差別的,下圖爲不一樣語言的冷啓動時長排名。

橫座標爲分配的內存空間,縱座標爲平均冷啓動時長,單位ms

在這裏插入圖片描述

從上圖咱們能夠看到兩個關鍵信息:

  • 分配的內存空間越大,冷啓動時長越短
  • Nodejs冷啓動時間是最短的

首次調用超時

  • 冷啓動快慢時長差距仍是很明顯的,從毫秒級到秒級甚至分鐘級皆有可能。
  • 對於Node這種可以短期內完成冷啓動的語言來講,必定程度上就是FaaS應用敢縮容到0的底氣。
  • 可是像java這種冷啓動時間比較久的語言,就有可能出現首次調用超時的問題。

性能優化

Serverless性能瓶頸主要在冷啓動耗時上,因此性能優化也是從這方面入手。

預熱:其本質是將冷啓動提早。使用熱啓動的方式對要執行的函數進行提早觸發,用以完成耗時的冷啓動過程。這樣在某個流量峯值,運行的代碼就都是熱啓動的形式,處理效率和應用性能提升。

減少代碼體積: 函數應用實例收縮到0後,當有新的請求到來,須要下載代碼。若是代碼體積太大,這個過程就會十分耗時。經過壓縮,按需引入等方式對代碼進行精簡,可減小冷啓動耗時。

提升併發配額: 默認狀況下一個函數實例只能處理一個請求,但可經過提升併發配額進而提升函數的處理能力。如額度爲3,則一個函數實例如今可處理三個請求,相比以前少了兩次冷啓動的過程。 併發限制數量取決於分配的內存大小,對於騰訊雲來講,128內存下,最大併發爲900。

在這裏插入圖片描述

選擇冷啓動耗時少的語言 : 如node,python

SFF

BFF(Backend For Frontend)和SFF(Serverless For Frontend)解決的是同一個問題,做爲先後端數據通訊的中間層,把後端返回的不符合前端預期的元數據轉成前端預期的數據格式。

出現這種非預期格式的元數據,大可能是微服務致使的(一個後端接口數據來自多個後端應用)。

相比BFF,SFF用完即毀的特色體現的更明顯:請求-轉換-響應-空閒-縮容爲0。

從這點考慮Serverless也適合用於中間層數據處理。

在這裏插入圖片描述

BaaS

FaaS適用於那些無狀態場景,而涉及數據存儲等有狀態的場景,就須要BaaS的支持。

舉個例子,計算PV(page view).

let pv = 0;

function handler(event) {

  pv++;

  return pv;

}

對於FaaS來講,這種統計其實並不精準。若是一段時間沒有新的事件觸發,函數執行完後,它的運行環境就會被銷燬,函數實例收縮爲0。當下一次請求過來時,函數應用會建立一個新的實例,該實例會初始化一個新的運行環境,以前的狀態不會被保留。

這種狀況下,就須要BaaS的配合了。BaaS服務於FaaS ,可讓FaaS經過接口調用形式來使用 BaaS,完成存儲數據,好比阿里雲的表格存儲(至關於一個NoSQL數據庫)。

const tablestore = require('tablestore');

async function handler(event) {

  let pv = await tablestore.get();

  pv += 1;

  await tablestore.save(pv);

  return pv;

}

這樣入庫後,即便FaaS應用收縮爲0,統計數據也不會受到影響。

再會

情如風雪無常,

倒是一動既殤。

感謝你這麼好看還來閱讀個人文章,

我是冷月心,下期再見。

推薦閱讀

相關文章
相關標籤/搜索