使用NGINX + NGINX Unit + Flask组合在Python的Web应用上运行
使用NGINX + NGINX Unit + Flask进行Python Web应用开发。
我打算用Python进行Web开发,所以我进行了Python Web应用的环境搭建。
以前,NGINX <-> uwsgi <-> Flask的设置是主流的,但是在2018年4月,NGINX公司发布了轻量级的AP服务器NGINX Unit。
这次我将使用NGINX Unit,将环境搭建成NGINX <-> NGINX Unit <-> Flask的设置来进行Web应用的开发。
环境
作为 Web 服务器,使用 NGINX,作为 AP 服务器,使用 NGINX Unit,使用 Python 的 Web 框架 Flask。
-
- OS : CentOS7
-
- Python : 3.7.4
-
- NGINX : 1.16.1
-
- NGINX Unit : 1.10.0
- Flask : 1.1.1
备考
服务器使用Vagrant和VirtualBox虚拟环境。
请启用私有网络。
$ vagrant init centos/7
$ vi Vagrantfile
- # config.vm.network "private_network", ip: "192.168.33.10"
+ config.vm.network "private_network", ip: "192.168.33.10"
$ vagrant up
$ vagrant ssh
请使用 vagrant ssh 连接到虚拟环境,并将 selinux 禁用。
$ sudo vi /etc/selinux/config
- SELINUX=enforcing
+ SELINUX=disabled
$ sudo reboot
搭建Python开发环境
在虚拟环境中搭建Python开发环境。
CentOS默认安装了Python 2.7.5。
$ python --version
Python 2.7.5
本次将使用 Python 3.7.4。
在 CentOS 上安装 Python3
参考Python官方网站的步骤,在CentOS上安装Python。
首先,安装所需工具。
$ sudo yum -y groupinstall "development tools"
$ sudo yum install -y bzip2-devel gdbm-devel libffi-devel libuuid-devel ncurses-devel openssl-devel readline-devel sqlite-devel tk-devel wget xz-devel zlib-devel
请使用wget命令从Python官方网站下载安装程序。下载完成后,请解压缩。
$ wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz
$ tar xzf Python-3.7.4.tgz
解压源代码后进行构建。
$ cd Python-3.7.4
$ ./configure --enable-shared
$ make
$ sudo make install
$ sudo sh -c "echo '/usr/local/lib' > /etc/ld.so.conf.d/custom_python3.conf"
$ sudo ldconfig
构建命令将安装到/usr/local/bin目录下。
$ which python
/usr/bin/python
$ which python3
/usr/local/bin/python3
$ python3 --version
Python 3.7.4
$ which pip3
/usr/local/bin/pip3
最后,将pip升级。
$ pip3 install --upgrade pip --user
最新版本的pip命令将安装在本地的bin目录中。
$ which pip
~/.local/bin/pip
$ pip --version
pip 19.2.3 from /home/vagrant/.local/lib/python3.7/site-packages/pip (python 3.7)
Python的环境已经设置完毕。
创建Python虚拟环境
为了根据每个项目来切换和管理包,我们将建立Python虚拟环境。
Python提供了一个名为venv的标准模块来支持创建虚拟环境。
我们将使用venv来创建虚拟环境。
# flask_sampleという仮想環境を作成
$ python3 -m venv flask_sample
$ ls
venv
激活由 venv 创建的虚拟环境。
$ source flask_sample/bin/activate
(flask_sample)$
通过执行venv模块创建的目录内的activate脚本,可以激活虚拟环境。
激活虚拟环境后,提示符的开头将显示虚拟环境的名称。
移动到创建的虚拟环境目录并确认其配置。
(flask_sample)$ cd flask_sample
(flask_sample)$ ls
bin include lib lib64 pyvenv.cfg
在bin目录中,有激活虚拟环境的activate脚本和Python的包管理工具pip命令。当在虚拟环境中执行pip命令时,将运行此目录中的命令。安装的包将被安装在lib/python3.7/site-packages和lib64/python3.7/site-packages目录中。在虚拟环境中,将忽略Python本身的site-packages目录,而使用此目录中的包。这样可以进行应用程序开发,而不会影响Python本身的包。
使用Flask创建样本项目。
Flask是Python的一个轻量级微框架。它只包含最基本的功能,适用于开发小型应用程序。由于有提供插件的功能,可以进行功能扩展。如果要从一开始开发大型应用程序,则需要使用Django。
安装Flask
在venv虚拟环境中,安装Flask。
(flask_sample)$ pip install Flask
创建应用程序
样本项目的组成如下所示。
/sample
|- app.py
|- templates
|- index.html
|- post.html
每个代码的实现如下所示。
from flask import Flask ,render_template,request
application = Flask(__name__)
@application.route('/')
def index():
return render_template('index.html')
@application.route('/sample',methods=['POST'])
def sample():
message = request.form['message']
return render_template('post.html',message=message)
if __name__=="__main__":
application.run(host='0.0.0.0')
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
<form action="sample" method="post">
<input type="text" name="message" />
<input type="submit" value="送信" />
</form>
</body>
</html>
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
メッセージ:{{message}}
</body>
</html>
在实施后执行app.py,启动Flask应用程序。
(flask_sample)$ python /sample/app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
当您启动后,在浏览器中访问http://虚拟环境的私有IP:5000/,将显示index.html页面。如果能确认这一点,那么Flask的操作已完成。下一步,将使用NGINX Unit构建AP服务器。
NGINX Unit = NGINX 单元
NGINX Unit 是由 NGINX 公司开发的轻量级应用服务器。
由于可以运行多种语言的应用程序,因此可以在同一台服务器上运行不同语言的应用程序。
支持的语言包括Python、PHP、Go、Perl、Ruby、Node.js和Java。
此外,还可以共存并运行不同版本的同一种语言(如Python2.7和Python3)。
通过API或JSON,可以实时更改配置而无需停止服务器,从而可以无缝地在不停止服务的情况下进行配置更改。
安装
在公式文档中,每个操作系统的安装方法都已经公开。
退出虚拟环境,然后添加yum仓库。
(flask_sample)$ deactivate
$ sudo vi /etc/yum.repos.d/unit.repo
[unit]
name=unit repo
baseurl=https://packages.nginx.org/unit/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
我将安装。
$ sudo yum install -y unit
$ sudo yum install -y unit-devel unit-go unit-jsc8 unit-perl unit-php unit-python
我們將設置NGINX Unit的自動啟動。
$ sudo systemctl enable unit
Created symlink from /etc/systemd/system/multi-user.target.wants/unit.service to /usr/lib/systemd/system/unit.service.
$ sudo service unit start
Redirecting to /bin/systemctl start unit.service
$ sudo service unit status
Redirecting to /bin/systemctl status unit.service
● unit.service - NGINX Unit
Loaded: loaded (/usr/lib/systemd/system/unit.service; enabled; vendor preset: disabled)
Active: active (running) since 火 2019-11-05 15:42:47 UTC; 7h ago
Main PID: 5714 (unitd)
CGroup: /system.slice/unit.service
├─5714 unit: main v1.12.0 [/usr/sbin/unitd --log /var/log/unit/unit.log --pid /var/run/unit/unit.pid --no-daemon]
├─5716 unit: controller
└─5717 unit: router
可以确认通过service unit status命令,NGINX Unit已成功启动。
设置Flask的配置
进行设置,将Flask的应用程序配置在NGINX Unit上运行。
通过从NGINX Unit的套接字获取配置文件,将Flask的应用程序加载到NGINX Unit中进行配置。
NGINX Unit用于控制的Unix套接字位于/var/run/unit/control.sock中(位置因操作系统而异)。
$ cd /sample
$ sudo curl --unix-socket /var/run/unit/control.sock http://localhost/config/ > config.json
$ vi config.json
{
"listeners": {
"*:8080": {
"pass": "applications/flask_app"
}
},
"applications": {
"flask_app": {
"type": "python",
"processes": 2,
"path": "/sample/",
"module": "app"
}
}
}
-
- listeners : ポートの設定を行います。*:8080のpassの値が、applicationsの階層と紐ずいています。
-
- applications :
type : モジュール名(言語)を指定
processes : worker 数
path : Python プログラムを配置しているパス
module : 起動するファイル。ファイル名から拡張子を除いた形で指定
将创建的配置文件PUT到NGINX Unit的套接字,以便应用配置的更改。
$ sudo curl -X PUT --data-binary @config.json --unix-socket /var/run/unit/control.sock http://localhost/config
{
"success": "Reconfiguration done."
}
当成功返回时,设置已经完成。您还可以确认设置的内容。
$ sudo curl --unix-socket /var/run/unit/control.sock http://localhost/
{
"certificates": {},
"config": {
"listeners": {
"*:8080": {
"pass": "applications/flask_app"
}
},
"applications": {
"flask_app": {
"type": "python",
"processes": 2,
"path": "/sample/",
"module": "app"
}
}
}
}
启动虚拟环境,访问http://localhost:8080/。
$ source venv/bin/activate
(flask_sample)$ curl http://localhost:8080/
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
<form action="sample" method="post">
<input type="text" name="message" />
<input type="submit" value="送信" />
</form>
</body>
</html>
如果index.html文件被显示出来,那么就表示已经完成了构建。即使在浏览器中访问,也会显示index.html文件。
以上是关于NGINX Unit的构建。接下来我们将构建NGINX Web服务器。
NGINX 是一个开源的高性能的Web服务器和反向代理服务器。
輕量高速是這款開源網頁伺服器的特點,被關注作為對Apache的替代伺服器。
相較於Apache,它在可伸縮性方面更為優越,其處理性能、並行處理和記憶體使用量等特點更加突出。我們這次將使用它作為代理伺服器。
在CentOS上安装NGINX
由于NGINX官方正式发布了yum仓库,所以我们会从该仓库中进行安装。
我们将根据官方网页的描述来添加仓库并进行安装。
添加仓库
我将从Python虚拟环境中退出。
我将添加yum仓库。我将添加/etc/yum.repos.d/NGINX.repo。
$ sudo vi /etc/yum.repos.d/NGINX.repo
[NGINX]
name=NGINX repo
baseurl=http://NGINX.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
安装
我会检查存储库。
$ sudo yum info nginx
Available Packages
Name : NGINX
Arch : x86_64
Epoch : 1
Version : 1.16.1
Release : 1.el7_4.ngx
Size : 754 k
Repo : NGINX/x86_64
Summary : High performance web server
URL : http://NGINX.org/
License : 2-clause BSD-like license
Description : NGINX [engine x] is an HTTP and reverse proxy server, as well as
: a mail proxy server.
一旦使用yum info命令确认存储库中是否存在NGINX,然后进行安装。
$ sudo yum install nginx
设置自动启动,并启动NGINX。
$ sudo systemctl enable nginx
$ sudo service start nginx
$ ![nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239179/0d818e0a-7aee-8a07-af95-72d34dfaa824.png)
service status nginx
● NGINX.service - NGINX - high performance web server
Loaded: loaded (/usr/lib/systemd/system/NGINX.service; enabled; vendor preset: disabled)
Active: active (running)
在启动 NGINX 后,使用浏览器访问虚拟环境的私有 IP,如果显示以下类似界面,则表示启动成功。
![nginx.png](https://cdn.silicloud.com/blog-img/blog/img/657d13b537434c4406bf94fe/89-0.png)
NGINX 和 NGINX Unit 的协作
Nginx 的配置文件
NGINX作为NGINX Unit之前的Web服务器和代理服务器运行。
将应用程序的请求代理给Nginx Unit。
NGINX的配置文件位于/etc/nginx/conf.d目录中。
$ sudo vi /etc/nginx/conf.d/app.conf
upstream unit-python {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name localhost;
location ~ / {
proxy_pass http://unit-python;
proxy_set_header Host $host;
}
}
重启NGINX并访问 http://localhost/ 。
$ sudo service restart nginx
$ curl http://localhost/
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
<form action="sample" method="post">
<input type="text" name="message" />
<input type="submit" value="送信" />
</form>
</body>
</html>
如果显示 ‘index.html’,则代理设置已完成。您可以在浏览器中访问虚拟环境的私有IP并确认 index.html。至此,Python Web应用程序的环境配置已完成。
总结一下
我使用NGINX、NGINX Unit和Flask搭建了一个WEB应用环境。由于NGINX Unit专注于微服务的运营,我认为它将在未来继续受到关注。我希望能够持续地进行学习和实践。