自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python 之 WSGI、uWSGI 和 Uwsgi 介紹

開(kāi)發(fā) 前端
uwsgi 是一個(gè)與 uWSGI 服務(wù)器相關(guān)的協(xié)議。uwsgi 協(xié)議是一種二進(jìn)制協(xié)議,它定義了 uWSGI 服務(wù)器與應(yīng)用程序之間的通信協(xié)議。

一、概述

WSGI 、uWSGI 和 uwsgi 是三個(gè)相關(guān)的概念,它們是在 Web 應(yīng)用程序開(kāi)發(fā)中使用的不同的工具和協(xié)議。下面是它們的詳細(xì)介紹:

  • WSGI(Web Server Gateway Interface):WSGI 是一個(gè) Python Web 應(yīng)用程序與 Web 服務(wù)器之間的接口規(guī)范,它定義了應(yīng)用程序和服務(wù)器之間的標(biāo)準(zhǔn)接口,使得應(yīng)用程序可以在不同的 Web 服務(wù)器上運(yùn)行。WSGI 規(guī)范規(guī)定了應(yīng)用程序必須實(shí)現(xiàn)的接口方法和服務(wù)器需要支持的方法。WSGI 協(xié)議使得不同的 Python Web 框架(例如 Flask、Django 等)能夠在不同的 Web 服務(wù)器上運(yùn)行,這些服務(wù)器可以是 Apache、Nginx 等。
  • uWSGI:uWSGI 是一個(gè) Web 服務(wù)器,它是一個(gè)用 C 語(yǔ)言編寫(xiě)的 Web 應(yīng)用程序容器,支持運(yùn)行 Python、Ruby、Perl 等多種編程語(yǔ)言。uWSGI 服務(wù)器可以作為一個(gè)獨(dú)立的應(yīng)用服務(wù)器,也可以與其他 Web 服務(wù)器(如 Nginx、Apache)一起使用,通過(guò) WSGI 協(xié)議與 Python 應(yīng)用程序通信。
  • uwsgi:uwsgi 是一個(gè)與 uWSGI 服務(wù)器相關(guān)的協(xié)議。uwsgi 協(xié)議是一種二進(jìn)制協(xié)議,它定義了 uWSGI 服務(wù)器與應(yīng)用程序之間的通信協(xié)議。使用 uwsgi 協(xié)議,uWSGI 服務(wù)器可以與 Python 應(yīng)用程序通信,而不需要像 CGI 那樣啟動(dòng)一個(gè)新的進(jìn)程來(lái)處理每個(gè)請(qǐng)求。uwsgi 協(xié)議允許 uWSGI 服務(wù)器與應(yīng)用程序之間進(jìn)行雙向通信,從而提高了性能。

因此,uWSGI 是一個(gè) Web 服務(wù)器,可以通過(guò) WSGI 協(xié)議與 Python 應(yīng)用程序通信,并使用 uwsgi 協(xié)議進(jìn)行通信。WSGI 是 Python Web 應(yīng)用程序與 Web 服務(wù)器之間的接口規(guī)范,定義了應(yīng)用程序和服務(wù)器之間的標(biāo)準(zhǔn)接口。而 uwsgi 則是 uWSGI 服務(wù)器與應(yīng)用程序之間的二進(jìn)制通信協(xié)議。

圖片

二、安裝 uwsgi 模塊

uWSGI 是一種 Web 服務(wù)器網(wǎng)關(guān)接口(Web Server Gateway Interface),它可以用于將 Python Web 應(yīng)用程序與 Web 服務(wù)器(如 Nginx 或 Apache)集成在一起。

  • 在使用uWSGI模塊時(shí),需要安裝uwsgi模塊,并在Python Web應(yīng)用程序中導(dǎo)入uwsgi模塊,并使用uwsgi模塊提供的函數(shù)來(lái)配置和管理Web應(yīng)用程序的運(yùn)行。常見(jiàn)的uwsgi模塊函數(shù)包括uwsgi.optin()、uwsgi.route()、uwsgi.applications()等。
  • 另外,uWSGI模塊還提供了一些高級(jí)特性,如Master/Worker模式、進(jìn)程管理、負(fù)載均衡、自動(dòng)擴(kuò)展等,使得Web應(yīng)用程序可以更好地適應(yīng)高并發(fā)和大流量的情況。

1)配置pip源

國(guó)內(nèi)源地址:

  • pypi 清華大學(xué)源:https://pypi.tuna.tsinghua.edu.cn/simple
  • pypi 騰訊源:http://mirrors.cloud.tencent.com/pypi/simple
  • pypi 阿里源:https://mirrors.aliyun.com/pypi/simple/
mkdir  ~/.pip/
cat >~/.pip/pip.conf<<EOF
[global]
index-url = https://repo.huaweicloud.com/repository/pypi/simple
trusted-host = repo.huaweicloud.com
timeout = 120
EOF

2)安裝 uwsgi 模塊

# 安裝python3
yum -y install python3

yum -y install gcc-c++ -y 
yum -y install python3-devel -y

# 安裝 uwsgi flask 模塊
pip3 install uwsgi flask

# 查看版本
uwsgi --version

圖片

三、示例演示(uWSGI + Nginx 配置)

圖片

1)安裝 nginx

yum update -y
yum install epel-release
yum -y install nginx

2)創(chuàng)建 app.py 文件

創(chuàng)建一個(gè)名為 app.py 的文件,添加以下代碼:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World!'

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

3)創(chuàng)建 uWSGI 配置文件

創(chuàng)建一個(gè) uWSGI 配置文件,例如 uwsgi.ini,其中包含以下信息:

[uwsgi]
module = app:app 
# 相當(dāng)于命令下面兩行
#wsgi-file = app.py # 項(xiàng)目入口文件
#callable = app #  flask應(yīng)用對(duì)象
# 支持http+socket兩種方式,這里選用socket,也可以選擇http-socket,下面會(huì)講解這三種區(qū)別
# http = 127.0.0.1:8000
socket = 0.0.0.0:8000
# 也可以使用socket文件,在nginx配置文件中配置也對(duì)應(yīng),僅限本機(jī)通信,一般也很少使用
# socket = /app/myapp.sock

# 注意記得提前創(chuàng)建目錄
chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log

uwsgi.ini常用配置參數(shù)詳解:

  • chdir=/xxx/xxx # 指定項(xiàng)目目錄, 這里寫(xiě)上程序根目錄(即app.py文件所在目錄)對(duì)應(yīng)上述目錄結(jié)構(gòu)為src
  • home=/xxx/xxx # 指定虛擬環(huán)境變量
  • wsgi-file=xxx # 指定加載WSGI文件
  • socket=xxx # 指定uwsgi的客戶端將要連接的socket的路徑(使用UNIX socket的情況)或者地址(使用網(wǎng)絡(luò)地址的情況)。#socket協(xié)議,用于和nginx通訊,端口可配置成別的端口;如果有nginx在uwsgi之前作為代理的話應(yīng)該配socket 如:socket=0.0.0.0:5000。當(dāng)然也可以使用http-socket #而如果客戶端請(qǐng)求不經(jīng)過(guò)(不搭建)Nginx代理服務(wù)器,服務(wù)請(qǐng)求直接到uwsgi服務(wù)器的話那么就配http。如:http=0.0.0.0:5000;IP和端口與項(xiàng)目啟動(dòng)文件app.py中一致; 127.0.0.1雖然是表示本地IP,但想要在網(wǎng)絡(luò)上訪問(wèn)必須設(shè)置host=0.0.0.0才不受IP限制。
  • callable=app # 這個(gè) app 指的是 flask 項(xiàng)目啟動(dòng)程序中定義的 flask name 的名字,我的啟動(dòng)程序是 app.py , 里面定義的 flask 的名字是 app 。
  • module = mysite.wsgi # 加載一個(gè)WSGI模塊,這里加載mysite/wsgi.py這個(gè)模塊
  • `master=true # 指定啟動(dòng)主進(jìn)程
  • `processes=4 # 設(shè)置工作進(jìn)程的數(shù)量
  • threads=2 # 設(shè)置每個(gè)工作進(jìn)程的線程數(shù)
  • vacuum=true # 當(dāng)服務(wù)器退出時(shí)自動(dòng)刪除unix socket文件和pid文件
  • logfile-chmod=644 # 指定日志文件的權(quán)限
  • daemonize=%(chdir)/xxx.log # 進(jìn)程在后臺(tái)運(yùn)行,并將日志打印到指定文件
  • pidfile=%(chdir)/xxx.pid # 在失去權(quán)限前,將主進(jìn)程pid寫(xiě)到指定的文件
  • uid=xxx # uWSGI服務(wù)器運(yùn)行時(shí)的用戶id
  • gid=xxx # uWSGI服務(wù)器運(yùn)行時(shí)的用戶組id
  • procname-prefix-spaced=xxx # 指定工作進(jìn)程名稱的前綴
  • chdir=/xxx/xxx # 指定項(xiàng)目目錄, 這里寫(xiě)上程序根目錄(即app.py文件所在目錄)對(duì)應(yīng)上述目錄結(jié)構(gòu)為/opt/uwsgi/
  • listen = 120 # 設(shè)置socket的監(jiān)聽(tīng)隊(duì)列大?。J(rèn):100)

4)啟動(dòng) uWSGI

在命令行中啟動(dòng) uWSGI:

uwsgi --ini uwsgi.ini
###或者
uwsgi uwsgi.ini

### 重啟
uwsgi --reload /opt/myapp/myapp.pid
###關(guān)閉
uwsgi --stop /opt/myapp/myapp.pid

圖片

【溫馨提示】其實(shí)也可以通過(guò)一條命令帶上對(duì)應(yīng)的參數(shù)即可啟動(dòng),但是不推薦,測(cè)試可以。一般使用配置文件的方式啟動(dòng)服務(wù)。

使用http協(xié)議啟動(dòng)uwsgi的命令為:

uwsgi --http :8000 --ini uwsgi_conf.ini -d ./uwsgi.log --pidfile=uwsgi.pid
  • --http 指定用5800端口啟動(dòng)http協(xié)議
  • --ini 指定上述的啟動(dòng)配置文件
  • -d 指定uwsgi的log,方便我們調(diào)試
  • --pidfile 將啟動(dòng)的進(jìn)程號(hào)寫(xiě)到uwsgi.pid文件中,方便我們?cè)谛枰V狗?wù)器時(shí)kill掉。

5)配置 Web 服務(wù)器

將 Web 服務(wù)器配置為反向代理 uWSGI,例如,在 Nginx 中,可以使用以下配置文件:

# vi /etc/nginx/conf.d/myapp.conf
server {
        listen 8080;
        server_name myapp.com;
        location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:8000;
        }
}

其中,uwsgi_params 文件包含以下內(nèi)容:

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

圖片

【特別注意】uwsgi_params 在nginx conf文件夾下自帶,uwsgi_pass一定要跟uwsgi_conf.ini中寫(xiě)的地址完全一致。

6)重啟 Web 服務(wù)器

重啟 Web 服務(wù)器以使配置生效。

# 重啟
systemctl restart nginx

# 如果是之前nginx服務(wù)已經(jīng)存在,只是修改了配置,可建議使用reload加載
nginx -t && nginx -s reload
# 或者
systemctl reload nginx

訪問(wèn)(瀏覽器訪問(wèn),curl訪問(wèn)也行)

圖片

7)Nginx upstream 負(fù)載均衡

Nginx上游(upstream)是指一組后端服務(wù)器,Nginx可以與其通信并將客戶端請(qǐng)求轉(zhuǎn)發(fā)到這些服務(wù)器。換句話說(shuō),上游服務(wù)器是Nginx代理請(qǐng)求的后端服務(wù)器。

Nginx的upstream支持5種 分配方式,其中 輪詢(默認(rèn))、權(quán)重、IP散列這三種為Nginx原生支持的分配方式,fair 和 url_hash 為第三方支持的分配方式。

1、輪詢(默認(rèn))

輪詢是upstream的默認(rèn)分配方式,即每個(gè)請(qǐng)求按照時(shí)間順序輪流分配到不同的后端服務(wù)器,如果某個(gè)后端服務(wù)器 down 掉后,能自動(dòng)剔除。

upstream backend {
    server 192.168.182.110:8000;
    server 192.168.182.111:8000;
}

2、權(quán)重(weight)

輪詢的加強(qiáng)版,既可以指定輪詢比率,weight 和訪問(wèn)幾率成正比,主要應(yīng)用于后端服務(wù)器異質(zhì)的場(chǎng)景下。

upstream backend {
    server 192.168.182.110:8000 weight=1;
    server 192.168.182.111:8000 weight=2;
}

3、IP散列(ip_hash)

每個(gè)請(qǐng)求按照訪問(wèn) Ip(即Nginx的前置服務(wù)器或客戶端IP)的 hash結(jié)果分配,這樣每個(gè)訪客會(huì)固定訪問(wèn)一個(gè)后端服務(wù)器,可以解決 session 一致問(wèn)題。

upstream backend {
    ip_hash;
    server 192.168.182.110:8000 weight=1;
    server 192.168.182.111:8000 weight=2;
}

先在另外一個(gè)節(jié)點(diǎn)上再起一個(gè)uWSGI服務(wù),將上面示例配置修改:

# vi /etc/nginx/conf.d/myapp.conf
upstream backend {
    server 192.168.182.110:8000;
    server 192.168.182.111:8000;
}

server {
        listen 8080;
        server_name myapp.com;
        location / {
           include uwsgi_params;
           uwsgi_pass backend;
        }
}

192.168.182.110 節(jié)點(diǎn) app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World 192.168.182.110!\n'

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

192.168.182.111 節(jié)點(diǎn) app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World 192.168.182.111!\n'

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

驗(yàn)證

curl  127.0.0.1:8080

圖片

從上圖可知,請(qǐng)求輪詢調(diào)度,這才是企業(yè)一般想要的效果,負(fù)載均衡。

8)http、http-socket 和 socket 區(qū)別

  • http和http-socket的區(qū)別在于,如果我們想直接將uwsgi用作服務(wù)器(例如Apache和nginx那樣)直接暴露在公網(wǎng)那么就使用http;
  • 如果有單獨(dú)的服務(wù)器(例如Apache或者nginx),由服務(wù)器將請(qǐng)求轉(zhuǎn)發(fā)給uwsgi處理,并且使用http協(xié)議,那么此時(shí)使用http-socket。
  • http: 自己會(huì)產(chǎn)生一個(gè)http進(jìn)程(可以認(rèn)為與nginx同一層)負(fù)責(zé)路由http請(qǐng)求給worker, http進(jìn)程和worker之間使用的是uwsgi協(xié)議。
  • http-socket: 不會(huì)產(chǎn)生http進(jìn)程, 一般用于在前端webserver不支持uwsgi而僅支持http時(shí)使用, 他產(chǎn)生的worker使用的是http協(xié)議。
  • 因此, http 一般是作為獨(dú)立部署的選項(xiàng); http-socket 在前端webserver不支持uwsgi時(shí)使用, 如果前端webserver支持uwsgi, 則直接使用socket即可(tcp or unix)。

【1】socket 示例(uwsgi.ini):

[uwsgi]
module = app:app
#socket = 127.0.0.1:8000
socket = 0.0.0.0:8000

chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log

nginx配置

upstream backend {
    server 192.168.182.110:8000;
    server 192.168.182.111:8000;
}

server {
        listen 8080;
        server_name myapp.com;
        location / {
           include uwsgi_params;
           uwsgi_pass backend;
        }
}

【2】http 示例(uwsgi.ini):

[uwsgi]
module = app:app
socket = 0.0.0.0:8000

chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log

nginx配置

upstream backend {
    server 192.168.182.110:8000;
    server 192.168.182.111:8000;
}

server {
        listen 8080;
        server_name myapp.com;
        location / {
           include uwsgi_params;
           proxy_pass http://backend;
        }
}

【3】http-socket 示例(uwsgi.ini):

[uwsgi]
module = app:app
http = 0.0.0.0:8000

chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log

nginx配置

upstream backend {
    server 192.168.182.110:8000;
    server 192.168.182.111:8000;
}

server {
        listen 8080;
        server_name myapp.com;
        location / {
           include uwsgi_params;
           proxy_pass http://backend;
        }
}

9)TCP 與 uinx 區(qū)別

TCP和Unix套接字(Unix domain socket)是兩種不同類型的套接字。

  • TCP套接字是基于TCP/IP協(xié)議的網(wǎng)絡(luò)套接字,用于在網(wǎng)絡(luò)上進(jìn)行進(jìn)程間通信。TCP套接字需要指定IP地址和端口號(hào),以便其他進(jìn)程可以連接到該套接字進(jìn)行通信。TCP套接字是一種跨網(wǎng)絡(luò)邊界的套接字,可以在不同的計(jì)算機(jī)之間進(jìn)行通信。TCP套接字常用于客戶端/服務(wù)器架構(gòu)中,如Web服務(wù)器、數(shù)據(jù)庫(kù)服務(wù)器等。
  • Unix套接字是基于Unix域套接字(Unix domain socket)的本地套接字,用于在同一臺(tái)計(jì)算機(jī)上進(jìn)行進(jìn)程間通信。Unix套接字只需要指定一個(gè)文件路徑,而不需要使用IP地址和端口號(hào)。Unix套接字是一種進(jìn)程間通信(IPC)機(jī)制,它提供了高效、可靠和安全的進(jìn)程間通信方式。Unix套接字通常用于本地服務(wù)器和本地客戶端之間的通信,例如X Window系統(tǒng)中的客戶端和服務(wù)器。

因此,TCP套接字用于在網(wǎng)絡(luò)上進(jìn)行通信,而Unix套接字用于在同一臺(tái)計(jì)算機(jī)上進(jìn)行通信。雖然TCP套接字可以通過(guò)網(wǎng)絡(luò)連接到不同的計(jì)算機(jī),但是Unix套接字提供了更高效的進(jìn)程間通信機(jī)制,并且更適合于需要在同一臺(tái)計(jì)算機(jī)上運(yùn)行的進(jìn)程間通信。

【TCP 示例】常用uwsgi.ini:

[uwsgi]
module = app:app
socket = 127.0.0.1:8000

chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log

【unix 示例】?jī)H限于本機(jī)通信,很少使用。uwsgi.ini:

[uwsgi]
module = app:app
socket = /opt/myapp/myapp.socket

chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log

nginx配置

server {
        listen 8080;
        server_name myapp.com;
        location / {
           include uwsgi_params;
           proxy_pass unix:///opt/myapp/myapp.sock;
        }
}

責(zé)任編輯:武曉燕 來(lái)源: 大數(shù)據(jù)與云原生技術(shù)分享
相關(guān)推薦

2023-03-28 14:58:22

Web工具開(kāi)發(fā)

2024-05-13 09:38:14

PythonWeb開(kāi)發(fā)WSGI

2010-10-13 09:21:39

2019-02-18 11:01:31

緩存Nginxuwsgi

2021-08-10 07:00:01

Redis單線程并發(fā)

2014-11-24 09:35:06

CGIFastCGIWSGI

2022-02-22 15:27:46

數(shù)據(jù)結(jié)構(gòu)容器算法

2023-05-23 07:06:05

PythonPowerShell

2010-06-01 18:03:05

Rsync 使用

2021-09-16 10:05:09

鴻蒙HarmonyOS應(yīng)用

2010-04-26 14:44:36

負(fù)載均衡設(shè)備

2023-06-20 15:45:15

服務(wù)卡片鴻蒙

2015-07-22 16:16:47

PythonScikit-Lear機(jī)器學(xué)習(xí)

2010-06-01 17:44:14

Rsync 使用

2017-01-09 16:25:55

Android Shortcuts系統(tǒng)

2011-07-13 11:12:43

C++MFC

2023-02-03 17:28:44

HIDLAndroid硬件

2011-04-02 10:57:41

2011-06-30 15:45:55

SEO

2009-07-06 18:43:13

VB指針
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)