基於Serverless架構的Python Blog開發(原生開發與Flask框架結合)

前言

Serverless架構是一個新的概念,也能夠說是一個新的架構或者技術,可是不管他有多新,都不能一會兒完成現有都開發習慣到Serverless架構的過渡,讓現有的工程師放棄現有的Express、Koa、Flask、Django等框架直接在Serverless架構上開發項目,顯然是不可能,就算可能,這也須要時間進行適應和過渡。
那麼在這個過渡的期間咱們是否能夠考慮將現有的框架部署到Serverless架構上?接下來,咱們以Flask框架進行一個簡單的測試:python

  • 測試四種接口:git

    • Get請求(可能涉及到經過路徑傳遞參數)
    • Post請求(經過Formdata傳遞參數)
    • Get請求(經過url參數進行參數傳遞)
    • Get請求(帶有jieba等計算功能)
  • 測試兩種狀況:github

    • 本地表現
    • 經過Flask-Component部署表現
  • 測試兩種性能:flask

    • 傳統雲服務器上的性能表現
    • 雲函數性能表現

首先是測試代碼:api

from flask import Flask, redirect, url_for, request
import jieba
import jieba.analyse

app = Flask(__name__)


@app.route('/hello/<name>')
def success(name):
    return 'hello %s' % name


@app.route('/welcome/post', methods=['POST'])
def welcome_post():
    user = request.form['name']
    return 'POST %s' % user


@app.route('/welcome/get', methods=['GET'])
def welcome_get():
    user = request.args.get('name')
    return 'GET %s' % user


@app.route('/jieba/', methods=['GET'])
def jieba_test():
    str = "Serverless Framework 是業界很是受歡迎的無服務器應用框架,開發者無需關心底層資源便可部署完整可用的 Serverless 應用架構。Serverless Framework 具備資源編排、自動伸縮、事件驅動等能力,覆蓋編碼、調試、測試、部署等全生命週期,幫助開發者經過聯動雲資源,迅速構建 Serverless 應用。"
    print(", ".join(jieba.cut(str)))
    print(jieba.analyse.extract_tags(str, topK=20, withWeight=False, allowPOS=()))
    print(jieba.analyse.textrank(str, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')))
    return 'success'


if __name__ == '__main__':
    app.run(debug=True)

這段測試代碼是比較有趣的,它包括了最經常使用的請求方法、傳參方法,也包括簡單的接口和稍微複雜的接口。服務器

本地表現

本地運行以後,經過Postman進行三個接口簡單測試:架構

  • Post參數傳遞:

  • Get參數傳遞:

經過Flask-Component部署表現

接下來,咱們將這個代碼部署到雲函數中:併發

經過Flask-Component部署,能夠參考Tencent給予的文檔,Github地址https://github.com/serverless...app

Yaml文檔內容:框架

FlaskComponent:
  component: '@gosls/tencent-flask'
  inputs:
    region: ap-beijing
    functionName: Flask_Component
    code: ./flask_component
    functionConf:
      timeout: 10
      memorySize: 128
      environment:
        variables:
          TEST: vale
      vpcConfig:
        subnetId: ''
        vpcId: ''
    apigatewayConf:
      protocols:
        - http
      environment: release

部署完成

接下來測試咱們的目標三個接口

  • Get經過路徑傳參:

  • Post參數傳遞:

  • Get參數傳遞:

經過上面的測試,咱們能夠看出,經過Flask-Component部署的雲函數,也是能夠具有經常使用的幾種請求形式和傳參形式。

能夠這樣說,通常狀況下,用戶的Flask項目能夠直接經過騰訊雲提供的Flask-component快速部署到Serverless架構上,能夠獲得比較良好的運行。

簡單的性能測試

接下來對性能進行一波簡單的測試,首先購買一個雲服務器,將這個部分代碼部署到雲服務器上。
在雲上購買服務器,保守一點買了1核2G


而後配置環境,到服務能夠跑起來:


經過Post設置一下簡單的Tests:

而後對接口進行測試:

很是順利完成了接口測試:

能夠經過接口測試結果進行部分可視化:

同時對數據進行統計:

能夠看到,經過上圖和上表,服務器測的總體響應時間都快於雲函數的響應時間。並且能夠看到函數存在冷啓動,一按出現冷啓動,其響應時間會增加20餘倍。在因爲上述測試,僅僅是很是簡單的接口,接下來咱們來測試一下稍微複雜的接口,使用了jieba分詞的接口,由於jieba分詞接口存在:
測試結果:

可視化結果:

經過對Jieba接口的測試,能夠看到雖然服務器也會有因分詞組件進行初始化而產生比較慢的響應時間,可是總體而言,速度依舊是遠遠低於雲函數。
那麼問題來了,是函數自己的性能有問題,仍是增長了Flask框架+APIGW響應集成以後纔有問題?
接下來,作一組新的接口測試,在函數中,直接返回內容,而不進行額外處理,看看函數+API網關性能和正常狀況下的服務器性能對比

能夠看出雖然最小和平均耗時的區別不是很大,可是最大耗時基本上是持平。能夠看出來,框架的加載會致使函數冷啓動時間長度變得異常可怕。
接下來經過Python代碼,對Flask框架進行併發測試:
對函數進行3次壓測,每次併發300:

===========task end===========
total:301,succ:301,fail:0,except:0
response maxtime: 1.2727971077
response mintime 0.573610067368

===========task end===========
total:301,succ:301,fail:0,except:0
response maxtime: 1.1745698452
response mintime 0.172255039215

===========task end===========
total:301,succ:301,fail:0,except:0
response maxtime: 1.2857568264
response mintime 0.157210826874

對服務器進行3次壓測,一樣是每次併發300:

===========task end===========
total:301,succ:301,fail:0,except:0
response maxtime: 3.41151213646
response mintime 0.255661010742

===========task end===========
total:301,succ:301,fail:0,except:0
response maxtime: 3.37784004211
response mintime 0.212490081787

===========task end===========
total:301,succ:301,fail:0,except:0
response maxtime: 3.39548277855
response mintime 0.439364910126

經過這一波壓測,咱們能夠看到這樣一個奇怪現象,那就是在函數和服務器預熱完成以後,連續三次併發301個請求。函數的總體表現,反而比服務器的要好。這也說明了在Serverless架構下,彈性伸縮的一個很是重要的表現。傳統服務器,咱們若是出現了高並發現象,很容易會致使總體服務受到嚴重影響,例如響應時間變長,無響應,甚至是服務器直接掛掉,可是在Serverless架構下,這個彈性伸縮的能力是雲廠商幫助咱們作的,因此在併發量達到必定的時候,其實Serverless架構的優點變得會更加明顯。

總結:

  • Flask是能夠經過很簡單的方法上Serverless架構,用戶基本上能夠按照原生Flask開發習慣來開發Flask項目,尤爲是使用Flask開發接口服務的項目,更是能夠比較容易的遷移到Serverless架構。
  • 總體框架遷移上Serverless架構可能要要注意幾個額外的點:
  1. 若是接口比較多,可能要按照資源消耗比較大的那個接口來設置內存大小,以我例子中的狀況,非jieba接口使用的時候,可使用最小內存(64M),jieba接口使用的時候,須要256M的內存,而整個項目是一體的,只能設置一個內存,因此爲了保證項目可用性,就會總體設置爲256M的內存,這樣一來若是另外三個接口訪問比較多的前提下,可能資源消耗會相對增長比較大,因此,若是有條件的話,可考慮將資源消耗比較大的接口額外提取出來;
  2. 雲函數+API網關的組合對靜態資源以及文件上傳等的支持可能並非十分友好,尤爲是雲函數+API網關的雙重收費,因此這裏建議將Flask中的一些靜態資源統一放在對象存儲中,同時將文件上傳邏輯修改爲優先上傳到對象存儲中,能夠參考以前的文章:【實踐與踩坑】用Serverless怎麼上傳文件?
  • 框架越大,或者框架內的資源越多函數冷啓動的時間可能會越大。這一點是很是值得重視的。在剛纔測試過程當中,非框架下,最高耗時是平均耗時的3倍,而在加載Flask框架和Jieba的前提下,最高耗時是平均的10+倍!若是能夠保證函數都是熱啓動還好,一旦出現冷啓動,可能會有必定的影響。
  • 因爲用戶發起請求是客戶端到API網關再到函數,而後從函數回到API網關,再回到客戶端,這個過程相對直接訪問服務器得到結果的鏈路明顯長了一些,因此在實際測試過程當中小用戶量對的表現發而不是很好,幾回測試,基本上1核2G的服務器都是優於函數表現。可是當併發量上來的以後能夠看到函數的表現實現了大超車,一度超越這臺1核2G的服務器。那麼這裏有一個有趣的結論:對於極小規模請求,函數是按量付費,雖然性能上有必定的劣勢,可是按量付費在價格上有必定的優點;當流量逐漸變大以後,函數在性能上的優點也逐漸凸顯。

我相信,Serverless架構會隨着時間的發展,愈加的成熟,目前可能還有或多或少的問題,可是不久的未來,必定不負衆望。


相關文章
相關標籤/搜索