日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Serverless工程實(shí)踐|Serverless應(yīng)用開發(fā)觀念的轉(zhuǎn)變

前言:在 Serverless 架構(gòu)下,雖然更多精力是關(guān)注業(yè)務(wù)代碼,但是實(shí)際上對(duì)一些配置和成本也是需要關(guān)注的,并且必要的時(shí)候還需要根據(jù)配置與成本對(duì) Serverless 應(yīng)用進(jìn)行配置和代碼優(yōu)化。

創(chuàng)新互聯(lián)專注于譙城企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),購(gòu)物商城網(wǎng)站建設(shè)。譙城網(wǎng)站建設(shè)公司,為譙城等地區(qū)提供建站服務(wù)。全流程按需規(guī)劃網(wǎng)站,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

Serverless 應(yīng)用開發(fā)觀念的轉(zhuǎn)變

Serverless 架構(gòu)帶來(lái)的除了一種新的架構(gòu)、一種新的編程范式,還包括思路上的轉(zhuǎn)變,尤其是開發(fā)過(guò)程中的一些思路轉(zhuǎn)變。有人說(shuō)要把 Serverless 架構(gòu)看成一種天然的分布式架構(gòu),需要用分布式架構(gòu)的思路去開發(fā) Serverless 應(yīng)用。誠(chéng)然,這種說(shuō)法是正確的。但是在一些情況下,Serverless 還有一些特性,所以要轉(zhuǎn)變開發(fā)觀念。

1、文件上傳方法

在傳統(tǒng) Web 框架中,上傳文件是非常簡(jiǎn)單和便捷的,例如 Python 的 Flask 框架:

f = request.files['file']f.save('my_file_path')
但是在 Serverless 架構(gòu)下,文件卻不能直接上傳,原因如下:

一般情況下,一些云平臺(tái)的API網(wǎng)關(guān)觸發(fā)器會(huì)將二進(jìn)制文件轉(zhuǎn)換成字符串,不便直接獲取和存儲(chǔ);
一般情況下,API 網(wǎng)關(guān)與 FaaS 平臺(tái)之間傳遞的數(shù)據(jù)包有大小限制,很多平臺(tái)限制數(shù)據(jù)包大小為 6MB 以內(nèi);
FaaS 平臺(tái)大多是無(wú)狀態(tài)的,即使存儲(chǔ)到當(dāng)前實(shí)例中,也會(huì)隨著實(shí)例釋放而使文件丟失。
所以,傳統(tǒng) Web 框架中常用的上傳文件方案不太適合在 Serverless 架構(gòu)中直接使用。在 Serverless 架構(gòu)中,上傳文件的方法通常有兩種:一種是轉(zhuǎn)換為 Base64 格式后上傳,將文件持久化到對(duì)象存儲(chǔ)或者 NAS 中,但 API 網(wǎng)關(guān)與 FaaS 平臺(tái)之間傳遞的數(shù)據(jù)包有大小限制,所以此方法通常適用于上傳頭像等小文件的業(yè)務(wù)場(chǎng)景。

另一種上傳方法是通過(guò)對(duì)象存儲(chǔ)等平臺(tái)來(lái)上傳,因?yàn)榭蛻舳酥苯油ㄟ^(guò)密鑰等來(lái)將文件直傳到對(duì)象存儲(chǔ)是有一定風(fēng)險(xiǎn)的,所以通常是客戶端發(fā)起上傳請(qǐng)求,函數(shù)計(jì)算根據(jù)請(qǐng)求內(nèi)容進(jìn)行預(yù)簽名操作,并將預(yù)簽名地址返給客戶端,客戶端再使用指定的方法上傳,上傳完成之后,通過(guò)對(duì)象存儲(chǔ)觸發(fā)器等來(lái)對(duì)上傳結(jié)果進(jìn)行更新等,如下圖所示。

在 Serverless 架構(gòu)下文件上傳文件示例

以阿里云函數(shù)計(jì)算為例,針對(duì)上述兩種常見的上傳方法通過(guò) Bottle 來(lái)實(shí)現(xiàn)。在函數(shù)計(jì)算中,先初始化對(duì)象存儲(chǔ)相關(guān)的對(duì)象等:

初始化對(duì)象存儲(chǔ)相關(guān)的對(duì)象等:

 
 
 
 
  1. AccessKey = {   "id": '',   "secret": ''}OSSConf = {    'endPoint': 'oss-cn-hangzhou.aliyuncs.com',    'bucketName': 'bucketName',    'objectSignUrlTimeOut': 60}#獲取/上傳文件到OSS的臨時(shí)地址auth = oss2.Auth(AccessKey['id'], AccessKey['secret'])bucket = oss2.Bucket(auth, OSSConf['endPoint'], OSSConf['bucketName'])#對(duì)象存儲(chǔ)操作getUrl = lambda object, method: bucket.sign_url(method, object, OSSConf['object    SignUrlTimeOut'])getSignUrl = lambda object: getUrl(object, "GET")putSignUrl = lambda object: getUrl(object, "PUT")#獲取隨機(jī)字符串randomStr = lambda len: "".join(random.sample('abcdefghijklqrstuvwxyz123456789    ABCDEFGZSA' * 100, len)) 

第一種上傳方法,通過(guò) Base64 上傳之后,將文件持久化到對(duì)象存儲(chǔ):

 
 
 
 
  1. #文件上傳# URI: /file/upload# Method: POST@bottle.route('/file/upload', "POST")def postFileUpload():    try:    pictureBase64 = bottle.request.GET.get('picture', '').split("base64,")[1]    object = randomStr(100)    with open('/tmp/%s' % object, 'wb') as f:        f.write(base64.b64decode(pictureBase64))        bucket.put_object_from_file(object, '/tmp/%s' % object)        return response({        "status": 'ok',        })    except Exception as e:    print("Error: ", e)    return response(ERROR['SystemError'], 'SystemError') 

第二種上傳方法,獲取預(yù)簽名的對(duì)象存儲(chǔ)地址,再在客戶端發(fā)起上傳請(qǐng)求,直傳到對(duì)象存儲(chǔ):

 
 
 
 
  1. #獲取文件上傳地址# URI: /file/upload/url# Method: GET@bottle.route('/file/upload/url', "GET")def getFileUploadUrl():    try:        object = randomStr(100)        return response({                    "upload": putSignUrl(object),                "download": 'https://download.xshu.cn/%s' % (object)             })         except Exception as e:           print("Error: ", e)              return response(ERROR['SystemError'], 'SystemError') 

HTML 部分:

 
 
 
 
  1.                  

    Web端上傳文件

          
      
      
          

                  方案1:上傳到函數(shù)計(jì)算進(jìn)行處理再轉(zhuǎn)存到對(duì)象存儲(chǔ),這種方法比較直觀,問題是 FaaS 平臺(tái)與 API 網(wǎng)關(guān)處有數(shù)據(jù)包大小上限,而且對(duì)二進(jìn)制文件處理并不好。              

                            
        
       
         

                        方案2:直接上傳到對(duì)象存儲(chǔ)。流程是先從函數(shù)計(jì)算獲得臨時(shí)地址并進(jìn)行數(shù)據(jù)存儲(chǔ)(例如將文件信息存到 Redis 等),然后再?gòu)目蛻舳藢⑽募蟼鞯綄?duì)象存儲(chǔ),之后通過(guò)對(duì)象存儲(chǔ)觸發(fā)器觸發(fā)函數(shù),從存儲(chǔ)系統(tǒng)(例如已經(jīng)存儲(chǔ)到Redis)讀取到信息,再對(duì)圖像進(jìn)行處理。          

                             
 

通過(guò) Base64 上傳的客戶端 JavaScript 實(shí)現(xiàn):

 
 
 
 
  1. function UpladFileFC() {      const oFReader = new FileReader();      oFReader.readAsDataURL(document.getElementById("fileFc").files[0]);       oFReader.onload = function (oFREvent) {          const xmlhttp = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new                    ActiveXObject("Microsoft.XMLHTTP"))           xmlhttp.onreadystatechange = function () {                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {                            alert(xmlhttp.responseText)            }              }                const url = "https://domain.com/file/upload"           xmlhttp.open("POST", url, true);              xmlhttp.setRequestHeader("Content-type", "application/json");               xmlhttp.send(JSON.stringify({                   picture: oFREvent.target.result             }));     }} 

 客戶端通過(guò)預(yù)簽名地址,直傳到對(duì)象存儲(chǔ)的客戶端 JavaScript 實(shí)現(xiàn):

 
 
 
 
  1. function doUpload(bodyUrl) {      const xmlhttp = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new Active               XObject("Microsoft.XMLHTTP"));        xmlhttp.open("PUT", bodyUrl, true);      xmlhttp.onload = function () {           alert(xmlhttp.responseText)      };       xmlhttp.send(document.getElementById("fileOss").files[0]);    }        function UpladFileOSS() {    const xmlhttp = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new Active        XObject("Microsoft.XMLHTTP"))    xmlhttp.onreadystatechange = function () {        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {                        const body = JSON.parse(xmlhttp.responseText)                     if (body['url']) {                  doUpload(body['url'])               }        }        }        const getUploadUrl = 'https://domain.com/file/upload/url'       xmlhttp.open("POST", getUploadUrl, true);     xmlhttp.setRequestHeader("Content-type", "application/json");     xmlhttp.send();} 

整體效果如圖中所示。

Serverless 架構(gòu)下文件上傳實(shí)驗(yàn) Web 端效果

此時(shí),我們可以在當(dāng)前頁(yè)面進(jìn)行不同類型的文件上傳方案實(shí)驗(yàn)。

2、文件讀寫與持久化方法

應(yīng)用在執(zhí)行過(guò)程中,可能會(huì)涉及文件的讀寫操作,或者是一些文件的持久化操作。在傳統(tǒng)的云主機(jī)模式下,可以直接讀寫文件,或者將文件在某個(gè)目錄下持久化,但是在 Serverless 架構(gòu)下并不是這樣的。

由于 FaaS 平臺(tái)是無(wú)狀態(tài)的,并且用過(guò)之后會(huì)被銷毀,因此文件并不能直接持久化在實(shí)例中,但可以持久化到其他的服務(wù)中,例如對(duì)象存儲(chǔ)、NAS 等。

同時(shí),在不配置 NAS 的情況下,F(xiàn)aaS 平臺(tái)通常情況下只具備 /tmp 目錄可寫權(quán)限,所以部分臨時(shí)文件可以緩存在 /tmp 文件夾下。

3、慎用部分 Web 框架的特性

(1) 異步

函數(shù)計(jì)算是請(qǐng)求級(jí)別的隔離,所以可以認(rèn)為這個(gè)請(qǐng)求結(jié)束了,實(shí)例就有可能進(jìn)入一個(gè)靜默狀態(tài)。而在函數(shù)計(jì)算中,API 網(wǎng)關(guān)觸發(fā)器通常是同步調(diào)用(以阿里云函數(shù)計(jì)算為例,通常只在定時(shí)觸發(fā)器、OSS 事件觸發(fā)器、MNS 主題觸發(fā)器和 IoT 觸發(fā)器等幾種情況下是異步觸發(fā))。

這就意味著當(dāng) API 網(wǎng)關(guān)將結(jié)果返給客戶端的時(shí)候,整個(gè)函數(shù)就會(huì)進(jìn)入靜默狀態(tài),或者被銷毀,而不是繼續(xù)執(zhí)行完異步方法。所以通常情況下像 Tornado 等框架就很難在 Serverless 架構(gòu)下發(fā)揮其異步的作用。當(dāng)然,如果使用者需要異步能力,可以參考云廠商所提供的異步方法。

以阿里云函數(shù)計(jì)算為例,阿里云函數(shù)計(jì)算為用戶提供了一種異步調(diào)用能力。當(dāng)函數(shù)的異步調(diào)用被觸發(fā)后,函數(shù)計(jì)算會(huì)將觸發(fā)事件放入內(nèi)部隊(duì)列,并返回請(qǐng)求 ID,而不會(huì)返回具體的調(diào)用情況及函數(shù)執(zhí)行狀態(tài)。如果用戶希望獲得異步調(diào)用的結(jié)果,可以通過(guò)配置異步調(diào)用目標(biāo)來(lái)實(shí)現(xiàn),如圖所示。

函數(shù)異步功能原理簡(jiǎn)圖

(2) 定時(shí)任務(wù)

在 Serverless 架構(gòu)下,應(yīng)用一旦完成當(dāng)前請(qǐng)求,就會(huì)進(jìn)入靜默狀態(tài),甚至實(shí)例會(huì)被銷毀,這就導(dǎo)致一些自帶定時(shí)任務(wù)的框架沒有辦法正常執(zhí)行定時(shí)任務(wù)。函數(shù)計(jì)算通常是由事件觸發(fā),不會(huì)自主定時(shí)啟動(dòng)。例如 Egg 項(xiàng)目中設(shè)定了一個(gè)定時(shí)任務(wù),但是在實(shí)際的函數(shù)計(jì)算中如果沒有通過(guò)觸發(fā)器觸發(fā)該函數(shù),該函數(shù)不會(huì)被觸發(fā),也不會(huì)從內(nèi)部自動(dòng)啟動(dòng)來(lái)執(zhí)行定時(shí)任務(wù),此時(shí)可以使用定時(shí)觸發(fā)器,通過(guò)定時(shí)觸發(fā)器觸發(fā)指定方法來(lái)替代定時(shí)任務(wù)。

4、要注意應(yīng)用組成結(jié)構(gòu)

(1) 靜態(tài)資源與業(yè)務(wù)邏輯

在 Serverless 架構(gòu)下,靜態(tài)資源更應(yīng)該在對(duì)象存儲(chǔ)與 CDN 的加持下對(duì)外提供服務(wù),否則所有的資源都在函數(shù)中。通過(guò)函數(shù)計(jì)算對(duì)外暴露,不僅會(huì)讓函數(shù)的業(yè)務(wù)邏輯并發(fā)度降低,也會(huì)造成更多的成本。尤其是將一些已有的程序遷移到 Serverless 架構(gòu)上,例如 WordPress 等,更要注意將靜態(tài)資源與業(yè)務(wù)邏輯進(jìn)行拆分,否則在高并發(fā)情況下,性能與成本都將會(huì)受到比較嚴(yán)峻的考驗(yàn)。

(2) 業(yè)務(wù)邏輯的拆分

在眾多云廠商中,函數(shù)的收費(fèi)標(biāo)準(zhǔn)都是依靠運(yùn)行時(shí)間、配置的內(nèi)存以及產(chǎn)生的流量收費(fèi)的。如果一個(gè)函數(shù)的內(nèi)存設(shè)置不合理,會(huì)導(dǎo)致成本成倍增加。想要保證內(nèi)存設(shè)置合理,更要保證業(yè)務(wù)邏輯結(jié)構(gòu)的可靠性。

以阿里云函數(shù)計(jì)算為例,一個(gè)應(yīng)用有兩個(gè)對(duì)外接口,其中有一個(gè)接口的內(nèi)存消耗在 128MB 以下,另一個(gè)接口的內(nèi)存消耗穩(wěn)定在 3000MB 左右。這兩個(gè)接口平均每天會(huì)被觸發(fā) 10000 次,并且時(shí)間消耗均在 100 毫秒。如果兩個(gè)接口寫到一個(gè)函數(shù)中,那么這個(gè)函數(shù)可能需要將內(nèi)存設(shè)置在 3072MB,同時(shí)用戶請(qǐng)求內(nèi)存消耗較少的接口在冷啟動(dòng)情況下難以得到較好的性能;如果兩個(gè)接口分別寫到函數(shù)中,則兩個(gè)函數(shù)內(nèi)存分別設(shè)置成 128MB 以及 3072MB 即可,如表所示。

通過(guò)上表可以明確看出合理、適當(dāng)?shù)夭鸱謽I(yè)務(wù)會(huì)在一定程度上節(jié)約成本。上面例子的成本節(jié)約近 50%。


網(wǎng)站題目:Serverless工程實(shí)踐|Serverless應(yīng)用開發(fā)觀念的轉(zhuǎn)變
文章URL:http://www.dlmjj.cn/article/dhgejcg.html