uWSGI學習筆記2——使用uWSGI作爲WSGI server

在上一篇認識wsgi走紅,我們瞭解了WSGI協議,知道了該協議在網絡中扮演的角色,並且使用Python自帶的WSGI模塊wsgiref編寫了一個簡單的WSGI server。wsgiref是用純Python寫的,性能不行,生產環境還是需要用uWSGI這一類高性能的WSGI server。這一篇我們使用uwsgi替代上一篇提到的自己編寫的WSGI server。

本章概覽

  1. 使用uWSGI運行簡單的WSGI application
  2. 使用processes,threads參數增強uWSGI的併發能力
  3. 使用status參數啓動uWSGI的監控
  4. 一個監視uWSGI狀態的小工具——uwsgitop

運行WSGI application

首先還是運行上一篇文章提到的hello.py

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, World!</h1>']

注:名爲application的函數是uWSGI Python加載器搜索的默認函數名(也可以自定義)。

然後使用uWSGI啓動一個HTTP 服務/路由,將請求傳遞到我們的WSGI application

 

uwsgi --http: 9090 --wsgi-file hello.py

瀏覽器進行訪問,可以看到

 

在終端可以看到log信息:

注:當前端還有一個服務器或者要做基準測試的時候,不要使用--http,而要使用--http-socket。

注:信息中有一段“!!! no internal routing support, rebuild with pcre support !!!”,可重新安裝libpcre3 libpcre3-dev,然後重新安裝uwsgi解決

 

增加併發能力

 

默認情況下,uWSGI啓動一個進程一個線程,我們可以使用--processes選項和--threads選項來增加啓動的進程和線程。

注:WSGI架構解耦了服務端與應用端,但這樣的形式也決定了其不支持異步相應。這也是爲什麼tornado這種主打異步相應的框架不能使用uwsgi的原因。

uwsgi --http :9090 --wsgi-file hello.py --master --processes 4 --threads 2

這個命令會啓動4個進程(每個進程包含兩個線程),一個主進程(它將會在其他進程死掉時將其拉起)以及一個HTTP路由。

 

啓動監控

 

默認情況下,uWSGI啓動一個進程一個線程,我們可以使用--processes選項和--threads選項來增加啓動的進程和線程。

注:WSGI架構解耦了服務端與應用端,但這樣的形式也決定了其不支持異步相應。這也是爲什麼tornado這種主打異步相應的框架不能使用uwsgi的原因。

 

啓動監控

 

在生產環境中監控uWSGI的狀態非常重要。stats子系統將uWSGI的內部統計導出爲JSON。可以通過--status啓動

 

uwsgi --http :9090 --wsgi-file hello.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

然後可以使用telent訪問9191端口獲取狀態信息如下:

 

{
    "version": "2.0.18",
    "listen_queue": 0,
    "listen_queue_errors": 0,
    "signal_queue": 0,
    "load": 0,
    "pid": 1494,
    "uid": 1000,
    "gid": 1000,
    "cwd": "/home/zhr/disk1/study/blog_code/uwsgi/p2_uwsgi",
    "locks": [
        {
            "user 0": 0
        },
        {
            "signal": 0
        },
        {
            "filemon": 0
        },
        {
            "timer": 0
        },
        {
            "rbtimer": 0
        },
        {
            "cron": 0
        },
        {
            "rpc": 0
        },
        {
            "snmp": 0
        }
    ],
    "sockets": [
        {
            "name": "127.0.0.1:39995",
            "proto": "uwsgi",
            "queue": 0,
            "max_queue": 100,
            "shared": 0,
            "can_offload": 0
        }
    ],
    "workers": [
        {
            "id": 1,
            "pid": 1495,
            "accepting": 1,
            "requests": 0,
            "delta_requests": 0,
            "exceptions": 0,
            "harakiri_count": 0,
            "signals": 0,
            "signal_queue": 0,
            "status": "idle",
            "rss": 0,
            "vsz": 0,
            "running_time": 0,
            "last_spawn": 1575690455,
            "respawn_count": 1,
            "tx": 0,
            "avg_rt": 0,
            "apps": [
                {
                    "id": 0,
                    "modifier1": 0,
                    "mountpoint": "",
                    "startup_time": 0,
                    "requests": 0,
                    "exceptions": 0,
                    "chdir": ""
                }
            ],
            "cores": [
                {
                    "id": 0,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                },
                {
                    "id": 1,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                }
            ]
        },
        {
            "id": 2,
            "pid": 1496,
            "accepting": 1,
            "requests": 0,
            "delta_requests": 0,
            "exceptions": 0,
            "harakiri_count": 0,
            "signals": 0,
            "signal_queue": 0,
            "status": "idle",
            "rss": 0,
            "vsz": 0,
            "running_time": 0,
            "last_spawn": 1575690455,
            "respawn_count": 1,
            "tx": 0,
            "avg_rt": 0,
            "apps": [
                {
                    "id": 0,
                    "modifier1": 0,
                    "mountpoint": "",
                    "startup_time": 0,
                    "requests": 0,
                    "exceptions": 0,
                    "chdir": ""
                }
            ],
            "cores": [
                {
                    "id": 0,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                },
                {
                    "id": 1,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                }
            ]
        },
        {
            "id": 3,
            "pid": 1497,
            "accepting": 1,
            "requests": 0,
            "delta_requests": 0,
            "exceptions": 0,
            "harakiri_count": 0,
            "signals": 0,
            "signal_queue": 0,
            "status": "idle",
            "rss": 0,
            "vsz": 0,
            "running_time": 0,
            "last_spawn": 1575690455,
            "respawn_count": 1,
            "tx": 0,
            "avg_rt": 0,
            "apps": [
                {
                    "id": 0,
                    "modifier1": 0,
                    "mountpoint": "",
                    "startup_time": 0,
                    "requests": 0,
                    "exceptions": 0,
                    "chdir": ""
                }
            ],
            "cores": [
                {
                    "id": 0,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                },
                {
                    "id": 1,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                }
            ]
        },
        {
            "id": 4,
            "pid": 1498,
            "accepting": 1,
            "requests": 0,
            "delta_requests": 0,
            "exceptions": 0,
            "harakiri_count": 0,
            "signals": 0,
            "signal_queue": 0,
            "status": "idle",
            "rss": 0,
            "vsz": 0,
            "running_time": 0,
            "last_spawn": 1575690455,
            "respawn_count": 1,
            "tx": 0,
            "avg_rt": 0,
            "apps": [
                {
                    "id": 0,
                    "modifier1": 0,
                    "mountpoint": "",
                    "startup_time": 0,
                    "requests": 0,
                    "exceptions": 0,
                    "chdir": ""
                }
            ],
            "cores": [
                {
                    "id": 0,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                },
                {
                    "id": 1,
                    "requests": 0,
                    "static_requests": 0,
                    "routed_requests": 0,
                    "offloaded_requests": 0,
                    "write_errors": 0,
                    "read_errors": 0,
                    "in_request": 0,
                    "vars": [],
                    "req_info": {}
                }
            ]
        }
    ]
}

一個監視uWSGI狀態的小工具——uwsgitop

 

有一個類似於top命令的小工具——uwsgitop,可以用來實時監視uWSGI的狀態。

通過如下命令啓動uWSGI:

 

uwsgi --http :9090 --wsgi-file hello.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 --stats-http

然後輸入:uwsgitop http://127.0.0.1:9191

或者通過如下命令啓動uWSGI:

uwsgi --http :9090 --wsgi-file hello.py --master --processes 4 --threads 2 --stats /tmp/stats.socket

然後輸入:uwsgitop /tmp/stats.socket

都可以獲得下面這樣的實時監視狀態:

其中每個字段的介紹如下:

Field

Description

WID

Worker ID

%

Worker usage

PID

Worker PID

REQ

Worker從最近一次啓動算起執行的請求次數

RPS

每秒請求次數

EXC

異常次數

SIG

被管理的uWSGI信號

STATUS

Worker是忙碌狀態還是空閒狀態

AVG

平均請求時間

RSS

Worker RSS(Resident Set Size,參閱linux內存管理)

VSZ

Worker VSZ(Virtual Memory Size,參閱linux內存管理)

TX

worker傳輸了多少數據

ReSpwn

重啓次數(Respawn count)

HC

Harakiri 次數(Harakiri是可以設置一個請求超過多少秒後會被中斷)

RunT

Worker運行了多長時間

LastSpwn

最後一次啓動時間

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章