**本文來自騰訊雲技術沙龍,本次沙龍主題為Serverless架構開發與SCF部署實踐 **
演講嘉賓:黃文俊,曾負責企業級儲存、企業級容器平臺等產品的架構與開發,目前主要負責SCF騰訊無伺服器雲函式產品相關。對容器平臺、微服務架構、無伺服器架構以及DevOps等多種熱門技術領域均有涉獵。
大家好,自我介紹一下,目前我是騰訊雲無伺服器雲函式產品負責人。我做了很多年後端開發。今天是從一個程式設計師角度講解一下我們怎麼樣用Serverless架構。
我將本次講解分為幾塊:第一,Serverless架構介紹;第二,對雲函式產品介紹;第三,Serverless使用場景。
講Serverless架構之前我們可以來看一下整個雲的發展過程,在沒有云之前大家可能都是用的物理伺服器,早期時候大家都用的物理機託管方式,採購一些伺服器在機房裡託管,這個時候大家前期要選擇物理機型號,要做好IDC網路;如果出了問題還要請IDC人員幫你操作。這些裝置的投入和運維成本還是很高的。
雲時代到來之後,由於虛擬化技術的運用,我們用上了雲主機。雲主機是大家直接在雲上做虛擬機器購買,開通就可以使用。這時候我們稱之為IaaS(基礎設施即服務),這種情況下就無需物理機運營,直接放到雲平臺來做。而之後隨著容器技術的發展,我們有了容器平臺,或者叫PaaS(平臺即服務)。在容器平臺到來之後實際上還存在一部分基礎設施運維問題,但是這時候基礎設施逐漸下沉到運維人員進行操作;而從應用開發者角度來看,他們已經不用再去關心虛擬機器,或者作業系統。在這種情況下,應用開發人員更多的去關注應用所需要的計算資源或者儲存資源的使用。繼續向前發展,我們到了FaaS(函式即服務)。這時候運維人員不需要關注底層的運維,而是按需執行的能力。業務開發人員能夠進一步做與業務相關的事情。
接下來我們來看一下Serverless架構是什麼。Serverless從物理機或虛擬機器的使用上進行了分離,更關注上層業務的執行情況。Serverless架構包含兩塊:函式即服務和後端即服務。函式即服務提供的是計算能力。原有的計算能力,無論是容器也好,虛擬機器也好都承載在一定的作業系統之上,函式即服務把計算能力進行了進一步抽象,我們在後文再繼續進行展開。另外,Serverless還有後端即服務,比如物件儲存,資料庫應用,快取服務,我們也可以稱之為Serverless,因為這些服務也能夠在雲上提供開通即服務,開通即使用的能力。在使用這些產品時同樣不需要關注它的伺服器是什麼樣的,它的伺服器部署在哪裡,而是服務開通就可以使用了,後面的運維工作都交給了雲,所以不用感知它的最底層伺服器,因此我們也可以把它稱之為Serverless。這種服務就稱之為Serverless後端即服務。這兩個合起來可以稱為Serverless架構。
函式即服務的工作原理是什麼樣的?在Serverless上是怎樣提供計算能力的?大家原來使用容器或者虛擬機器的時候都可以知道,我們把程式碼上傳到容器或者上傳到虛擬機器,然後啟動一個程式,程式碼就可以執行,它就可以接受外部的請求,做一些實時的響應。Serverless和原有的容器或虛擬機器不同,實現的是計算託管服務,Serverless使用者首先要做的,是把我們稱為雲函式的程式碼,提交到平臺上進行程式碼託管;然後要做的是配置觸發器。為什麼需要配置觸發器?因為雲函式的執行方式是觸發式執行,有觸發的時候,程式碼才會真正執行起來。所以配置觸發器意味著我們給它設定了一個觸發源,也就是定義了在什麼事件下程式碼才真正執行起來。使用者程式碼託管到平臺之後,事件沒有到來之前,它僅僅是程式碼檔案和配置儲存,程式碼並沒有執行。什麼情況下執行?是當事件觸發真正到來的時候,雲函式才會真正啟動一個例項,這個例項就意味著一個計算單元。計算單元被拉起後,這個事件就被傳到這個計算單元中進行計算處理。如果這個觸發源的事件很多,併發很高的情況下,平臺會根據事件的堆積情況,或者事件到達的速度,自動把同一份程式碼和配置拉起多個例項進行併發處理。因此可以看到Serverless的執行是按需執行,意味著只有在事件到來的情況下,程式碼才會被拉起,才會執行起來。
自動併發,是指雲函式平臺會根據事件堆積情況自動的進行併發,自動拉起多個例項進行處理。而原有的容器或者虛擬機器如果要進行併發的話還是要有一定的手工參與,比如啟動更多的容器,或者加入更多的虛擬機器來承載高併發的請求。而函式即服務是完全自動的執行。
按需執行帶來的另外一個特點,是程式碼在執行起來之後上才會佔用計算資源。函式即服務的費用也是根據按需執行來的,也就是函式執行的時候才進行計費;而沒有使用的情況下不會計費。實際上大多數網際網路業務只有白天的時候,甚至六點之後大家下班之後業務才會迎來高峰,而到凌晨之後實際上沒有多少請求的,因此函式即服務能夠很好的滿足波峰波谷來削峰填谷的能力。
從上面的原理可以看出函式即服務的一些特點,比如說程式碼託管,雲函式平臺所提供的直接就是執行環境,也就是支援各種開發語言的環境;對於開發者或者函式服務使用者來說,並沒有感知到它下面的伺服器在哪裡,而是由函式平臺完成了函式執行的排程。因此實際來講不需要運維,包括作業系統優化,伺服器維護等等這些都是由平臺進行承載。
而秒級部署意味著函式在真正的被請求的時候才執行。而這個請求才執行代表著當請求到達平臺的時候函式才會被實時拉起並執行。執行完成後如果沒有後續請求,例項也會退還。
由於函式執行是事件觸發的,而事件其實包含很多種類,有各種觸發器都可以對接雲函式。有越多的觸發器對接,雲函式所能提供的場景也就越多。
對於開發者來說,使用雲函式的情況下,他真正關注的是應該業務,是使用程式碼去聚焦他的業務邏輯,例如是拿到這個事件後該進行什麼樣的邏輯操作,進行什麼樣的業務儲存,而不需要去關注怎麼使用業務程式碼實現高併發,怎麼樣實現高請求的承載能力。因此這裡看到函式即服務能夠為應用開發者帶來一些便利,而自動併發本身也是函式即服務所具有的特點。
而對於騰訊雲無伺服器雲函式,在最開始開發產品的時候,我們目標也是一樣,就是把計算進行託管。在計算託管的情況下,我們使用計算就像我們使用騰訊雲物件儲存一樣,在使用的時候不用關心最底層的運維,不用關心虛擬機器或者物理機是否安全。和物件儲存進行對比也能看到,我們計算也是按照實際使用情況進行計費。當然現在雲函式還處於免費期,大家可以隨時使用。
從使用方法來說,雲函式本身,或者說函式即服務這種產品本身的使用方法都是很簡單的。我們在開發的時候更多的關注於核心程式碼的編寫。核心程式碼的意思實際上就是真正的業務邏輯。而且業務邏輯裡不需要考慮高併發,因為由剛才給出來的函式即服務這種計算特點來看的話,在高併發請求的時候是通過多個例項處理進行,因此業務程式碼在編寫的時候,就關注單個事件的處理就行。因此,第一步的核心的就是編寫核心業務程式碼,就是用程式碼要實現什麼樣的業務。後續就是配置觸發方式。配置觸發方式就是把函式程式碼和觸發源對接起來。和雲平臺上其他的產品進行對接,需要什麼樣的事件,處理什麼樣的事件,進行什麼樣的邏輯處理,做好這樣的觸發源對接後,函式就能夠在事件產生的情況下執行。
因此,從整個使用方法來看的話,大家真正要做的是兩步:第一,編寫程式碼,第二,配置好觸發。而對於底層的基礎設施,環境配置這塊都不需要大家操心的。
目前,騰訊雲函式從執行環境來說目前已經支援了Python、Nodejs、PHP、Golang、Java等語言的開發執行環境。
接下來是觸發器,因為觸發器越多,雲函式所能去使用的場景其實也越多,我們已經實現的觸發器有定時觸發器;騰訊雲物件儲存服務,包括檔案的上傳、刪除等時間;CMQ 訊息佇列服務;API 閘道器服務,這個是通過serverless 架構實現 API 服務的一款重要觸發器;另外,還有ckafka,這個是騰訊雲提供的kafka能力。目前kafka算是一個開源產品,我們騰訊雲把它包裝後放到雲上來,也是相容標準的kafka協議。因此在很多情況下直接遷移到騰訊雲不需要任何修改。因為kafka本身作為訊息傳遞的載體,跟騰訊原有的訊息佇列類似,由訊息來執行雲函式。
下面介紹一下在什麼場景下Serverless可以落地?第一,在Serverless場景中最常用到的就是API服務。大家知道實現一個API服務,無論是把API給到瀏覽器應用,還是給到手機APP使用,還是給到小程式應用,給到它們的時候是以API實現的。要實現這個要有WEB伺服器接收連線,對接後端的業務程式碼,如果你要再進行檔案儲存,後端的結構化儲存,或者有一些快取需要讀寫,你的應用伺服器後面可能還要對接相應的檔案儲存,結構化資料庫,後續如果想使用快取,再對接到相應的伺服器或相應產品。如果把現有的API服務向Serverless架構演進,那麼它將怎麼樣呈現呢?
在不改變 API 的情況下,它的前端瀏覽器應用、APP、小程式,都可以無縫對接上來。而使用API閘道器來承接 API 請求,當這個請求來到API閘道器,由它轉發給雲函式,觸發雲函式執行。雲函式執行時執行業務邏輯。實際上雲函式執行時要求無狀態,因此這樣的狀態儲存也需要用到後面的一些儲存,無論做快取也好還是資料庫也好都要用上。因此,雲上提供的產品一樣可以進行對接。像檔案儲存的話可以用物件儲存來進行。資料庫的話一樣的有相應的資料庫產品,結構化還是非結構化資料庫都有相應的產品可以使用。同樣的,快取也有相應的產品做對接。雲函式通過程式碼編寫,直接進行資料庫的讀寫,或者快取的讀寫都是可以的。
從整個服務架構來看的話,我們使用最前面的API閘道器,提供是API能力,甚至進一步能夠直提供有SDK服務,更加的方便開發。SDK提供了各種開發語言來直接進行API呼叫。雲函式在中間起到的是業務邏輯處理的作用,而狀態資料或者其他業務資料的儲存是依賴於後面的檔案儲存或者資料庫進行的。API服務也是Serverless最常用的一種落地形式。
這裡介紹的場景,都是我們客戶在實際使用的場景。在 serverless落地場景中,對物件檔案的處理也很常見。物件檔案處理指的是對物件檔案進行操作後的回撥處理。回撥通常是在物件檔案建立或刪除操作後產生的事件。雲函式可以在獲取到這個事件後進行後續的處理。這裡常見的處理邏輯是下面幾種,比如說圖片處理,針對圖片去生成各種尺寸的縮圖或者進行裁剪,然後再次儲存到物件儲存資料中,之後可以根據不同客戶端的請求展示不同大小的圖片到前端。
檔案批量打包,使用者需要進行檔案篩選和打包的時候可以通過使用雲函式來處理。在上傳檔案後,如果需要選擇哪些檔案來打包,把檔案生成壓縮包以供下載,這都可以由事件處理來進行。
日誌歸檔分析,以及業務系統回撥,也是雲函式所承載的業務邏輯。比如說日誌歸檔分析這種用法,使用者會把每天的前端應用伺服器的日誌上傳到物件儲存中歸檔,歸檔後會觸發雲函式執行,雲函式會拉下這些日誌檔案進行實時分析,它會抽取這些日誌中的錯誤數,或者是其他業務相關或者使用者關注的內容,然後再把它抽取到的資訊或者統計到的資訊寫回資料庫,供使用者後續進行排查、使用。使用者自身API呼叫也是,例如使用者生成的一些視訊檔案上傳到物件儲存,會觸發雲函式,將上傳檔案的資訊通知到使用者的轉碼系統,通過視訊轉碼轉成不同解析度然後再進行儲存。當然轉碼是使用者自身實現的業務系統,這塊通過回撥通知,通知它自身的業務系統。這些就是雲函式在Serverless架構和物件儲存連用的落地場景。
再就是CKafka訊息處理。CKafka目前比較多的應用場景是做日誌儲存和日誌蒐集,例如有多臺應用伺服器在不斷產生日誌的情況下,可以把日誌寫到CKafka,然後CKafka再進行歸檔和後續分析。而 CKafka和雲函式對接是由CKafka收到的資訊來進行觸發的。日誌蒐集後,要歸檔的日誌,一般儲存到物件儲存當中。這種情況CKafka訊息,會被推送給雲函式,雲函式再再把這些訊息寫到物件儲存中去。有些使用者不是寫物件儲存,而是寫資料庫,以資料庫形式歸檔,其實也是一樣的。有的使用場景,需要進行訊息分析,會實時拿到訊息後立刻分析裡面的關鍵字,如果捕捉到了關鍵字,會立刻把這些訊息推送到ckafka 的另一個topic 中,去及時的發出告警給到業務和運維人員。這也是 serverless 的一種用法,就是對訊息的分析和轉發。
訊息佇列和CKafka類似,但是訊息佇列一般不是進行日誌的蒐集,而是進行業務解耦。訊息佇列 CMQ 是騰訊雲提供的一個高可靠金融級訊息佇列,通常進行一些業務級訊息轉發和處理。使用這個產品,實際上做的是業務解耦。雲函式在這裡承載著訊息的邏輯處理過程,它能夠在接收到訊息後對訊息立刻進行業務處理。這個業務處理就是實際的業務邏輯,比如我要根據裡面某個訊息進行判斷,判斷它是否合適,要不要進行後續的轉發,或者轉發到另外的業務系統中去?這就是業務之間執行的邏輯。
同時,我們也可以使用雲函式,再次進行訊息的分派,做狀態轉移。這個狀態轉移和後面訊息轉發都是一樣的,它會識別訊息裡的內容,根據訊息裡的內容進行轉發。這種情況下類似於我們使用雲函式進行邏輯處理,把它轉移到合適的訊息佇列,然後再進行處理。這也是我們所見過直接用雲函式進行訊息派發的使用方式。
最後一種形式現在也不少,就是利用定時器觸發。原本大家更多是在運維場景下使用定時任務,在原有使用 crontab 指令碼的情況下,大家通常還要關心指令碼執行是否成功,這臺虛擬機器是否還在工作。雲函式拋棄了大家使用傳統的虛擬機器或者物理機來去寫crontab指令碼還要確保可靠性的問題。而在實際使用定時器觸發的場景下,這裡也有幾種用法:一種是業務撥測。這個是週期性的去撥測業務是否還在工作,如果出現異常的情況下能夠及時的發出告警,發出郵件或者簡訊告訴到運維或開發人員。
另一個是定時備份,這個是在所需要的週期內,比如每天,或者每兩天對資料庫進行備份,針對資料庫需要做資料匯出,匯出後再將匯出內容以檔案的形式儲存到合適的地方,例如物件儲存中,做好定時備份。
還有一個是定時資料計算。因為有些計算是根據一段時間內的統計之後,進行計算並展示。在實際場景中,我們騰訊雲內部有業務就是在進行定時資料計算,每兩小時做一次統計,然後再把統計資料寫到資料庫做後續業務的展示以及業務分析。
總結:Serverless架構本身給使用者帶來什麼?它實際上就是允許我們更關注業務程式碼,因此可以更快速的構建業務然後上線。現在網際網路開發速度越來越快,因此大家期望的是進一步加快開發和業務真正上線的速度,提高迭代的能力。因此,使用Serverless的話可以更快速讓業務上線,讓我們更快實現我們的想法。而按需使用是我們這個業務在上線之後,在真正產生請求後,業務才會被調動觸發,才會有計算。而如果你的業務產生了爆發式增長,其實也不需要擔心平臺承載能力或者業務擴充套件是否跟得上,因為平臺提供自動擴充套件能力,降低了大家對運維的訴求,大家不用關心很底層的東西,而運維人員也可以更偏重流程化和業務相關的運維。這就是Serverless架構給大家帶來的一些好處。而作為Serverless裡的核心,函式即服務這種產品,是Serverless中所呈現出來的計算型的元件,大家也可以看到它和觸發源和後端的各種產品或服務有緊密關聯,它可以更多的被看做是雲時代的指令碼,類似於黏合劑,把前面的觸發源和後端的各種儲存,資料,服務進行了黏合,真正實現架構落地,才是真正實現業務邏輯落地的能力。
Q&A
Q:雲函式有無限擴充套件能力,但是整個系統也有可能是有限制的,比如它的背後的資料庫和儲存,我能不能設這樣的一個擴充套件上限?
A:這可以設定上限的。目前可以通過提交工單的方式來設定期望的合適上限。擴充套件可以在後臺設定一個合適值,併發例項擴充套件到這個就不會再擴充套件了,避免大量例項連線造成後端的資料庫或儲存超過連線數限制。
Q:實現 API 服務有哪些開發方式?
A:雲函式實現 API 服務的開發方式有好幾種,一個是全部在一個函式裡完成,路徑和方法解析都在函式裡進行。這也是偏傳統的開發方式。另外一種是進行拆解,每個函式處理一個 API 路徑和方法的請求,這種是微服務的開發方式。
而函式和函式之間呼叫也是可以實現。一種是直接使用雲API,一種是使用 API閘道器包裝後的 API。雲函式被觸發呼叫的話,除了介紹的很多觸發器,在不使用這些觸發器的情況下,通過程式碼或者指令碼也可以通過騰訊雲的雲API呼叫。
Q:在事件觸發的時候,就是CMQ事件觸發的時候,是否可以保證函式被執行呢?因為不像API閘道器,呼叫一下函式可以啟動,前端可以感知到。但是CMQ,就是扔到訊息佇列能否保證這個函式被執行呢?
A:因為不像API閘道器是同步呼叫。同步呼叫就是這個呼叫在執行過程中如果出了問題,無論是平臺,比如說資源不足,併發不夠,或者比如使用的超時了,這個時候可以立刻感知到。 而像CMQ或者CKafka都是非同步的,這樣意味著呼叫後你感知不到,這個訊息什麼時候執行,執行結果都沒法感知。這種解決方法有兩種:一種是函式執行後的結果輸出,把訊息處理後的輸出結果再放到另一個訊息佇列中去,讓你外部的業務系統能夠感知到。當然這種對外通知也是非同步通知。同步通知是另外一種,就是函式裡可以對自身業務進行回撥API,可以通過程式碼知道現在的資料處理是什麼樣的結果,處理完後可以立刻回撥到API讓業務系統接收到處理結果。
Q:像COS觸發,拿視訊轉碼來說,這個有可能在300秒內處理不完。現在函式設定時間只能最高300秒,這個有什麼解決方案嗎?
A:為什麼各家的雲平臺,都把這個時間大致定在這個範圍內,就是不希望在雲函式中進行太重的計算。視訊轉碼就屬於太重的計算,而云函式提供的包括CPU能力,記憶體大小都有限,實際上都不太適合在雲函式內進行轉碼。實際上可以用一些視訊服務來實現轉碼,使用雲函式來做這兩者之間的橋樑,例如物件儲存的事件觸發後,雲函式拿到這個事件通過呼叫視訊轉碼服務來轉碼,而不是在雲函式轉碼。目前騰訊雲有這個服務,你可以試試看。
獲取更多詳細資料,請戳以下連結:
相關閱讀
**此文已由作者授權騰訊雲+社群釋出,原文請點選 **
搜尋關注公眾號「雲加社群」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!
海量技術實踐經驗,盡在雲加社群!