Flask 效能分析 - Profiling Flask

Posted on  Jan 13, 2019  in  Flask  by  Amo Chen  ‐ 2 min read

利用 Flask 所建構的 Web 應用(Application)能夠透過 Werkzeug WSGI Application Profiler 很輕鬆地進行效能分析。

本文記錄如何結合 Werkzeug WSGI Application Profiler 對 Flask Web 應用進行效能分析。

本文環境

  • Python 3.6.5
  • Flask 1.0.2

Werkzeug WSGI Application Profiler

Werkzeug WSGI Application Profiler 是 Werkzeug 提供用來測量 WSGI Application 效能的模組,該模組中提供 1 個類別 ProfilerMiddleware ,能夠透過 Middleware 的方式將 WSGI Application 包裝起來,以從中測量效能。

首先,假設有個簡單地 Flask Application (檔名 app.py ) 如下:

# - coding: utf-8 -*-
from flask import Flask

def create_app():
    flask_app = Flask(__name__)
    return flask_app

app = create_app()

@app.route('/', methods=['GET'])
def index():
    sum = 0
    for i in range(1, 1000):
        sum += i
    return f'1 + ... + 999 = {sum}'

接著改寫 create_app 函式的部分,整合 ProfilerMiddleware

# - coding: utf-8 -*-
import os

from flask import Flask
from werkzeug.contrib.profiler import ProfilerMiddleware


def create_app():
    flask_app = Flask(__name__)
    profile_dir = os.path.join(os.getcwd(), 'pstat_files')
    try:
        os.makedirs(profile_dir)
    except FileExistsError:
        pass
    # doc: http://werkzeug.pocoo.org/docs/0.14/contrib/profiler/
    flask_app.wsgi_app = ProfilerMiddleware(flask_app.wsgi_app, profile_dir=profile_dir)
    return flask_app

app = create_app()

@app.route('/', methods=['GET'])
def index():
    sum = 0
    for i in range(1, 1000):
        sum += i
    return f'1 + ... + 999 = {sum}'

上述改寫的部分主要為了:

  1. 建立 1 個 pstat_files 資料夾存放 ProfilerMiddleware 所輸出的檔案
  2. 將原有的 flask_app.wsgi_appProfilerMiddleware 再次包裝,同時指定 profile_dir 資料夾存放測量結果的檔案,也就是上述第 1 步所建立的資料夾

如此就完成 Werkzeug WSGI Application Profiler 的整合囉。

實測 Profiler

接著使用以下指令將 Flask Web 應用啟動,並以瀏覽器打開 http://127.0.0.1:5000 以實測 Profiler 的運作:

$ env FLASK_APP=app.py flask run

執行結果:

 * Forcing debug mode off
 * Serving Flask app "app.py"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [13/Jan/2019 20:50:24] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [13/Jan/2019 20:50:24] "GET /favicon.ico HTTP/1.1" 404

再來進入 pstat_files 資料夾查看是否有測量結果的檔案:

$ cd pstat_files
$ ls
GET.favicon.ico.000000ms.1547383824.prof GET.root.000001ms.1547383824.prof

可以發現多 2 個檔案,從檔名可以看到分別對應到 "GET / HTTP/1.1""GET /favicon.ico HTTP/1.1" 這 2 個 requests 。

這些檔案是由 Python cProfile 模組所輸出的檔案,因此可以用 pstats 進行解析。

除了利用 pstats 進行解析,也可以選擇利用工具進行解讀,例如 SNAKEVIZ 利用視覺化協助我們分析。

安裝 SNAKEVIZ 的指令:

$ pip install snakeviz

安裝完成後,試著使用以下指令讀取 GET.root.000001ms.1547383824.prof

$ snakeviz GET.root.000001ms.1547383824.prof

以上就是如何 Profiling Flask Web Application 的紀錄, Happy Coding !

番外篇

除了 SNAKEVIZ 之外, qcachegrind 也是值得一試的一款工具,不過使用 qcachegrind 前,須先透過 pyprof2calltree.prof 檔轉成 qcachegrind 能夠讀取的檔案格式:

$ pip install pyprof2calltree
$ pyprof2calltree -i GET.root.000001ms.1547383824.prof -o profile.kgrind
$ qcachegrind profile.kgrind

Reference

http://werkzeug.pocoo.org/docs/0.14/contrib/profiler/

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!