Python3+, Flask, Nginx, uWSGI,MySQL 搭建的 Web 应用遇到的问题

本文记录基于 Python3+, Flask, Nginx, uWSGI,MySQL 搭建的 Web 应用遇到的问题。

软件依赖

  • Python :: >=3.4
  • pip :: >=7.1.2
  • Flask :: = 0.11.1
  • Flask-Script :: =2.0.5
  • Nginx :: >=1.0.15
  • uWSGI :: = 2.0.12-2.el6
  • MySQL :: >=5.5.37

    Python

pyenv

使用 pyenv 来选择 Python 及 pip 的版本。 pyenv 为 github 项目,参照步骤安装。

1
2
3
4
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
$ echo 'eval "$(pyenv init -)"' >> ~/.zshrc
$ exec $SHELL

安装需要的Python版本

1
2
3
$ pyenv install 3.5.2
$ pyenv versions
$ pyenv local 3.5.2

Python Package

项目涉及的 package, 建议使用 pip install packagename 安装。

Flask

安装

1
$ pip install Flask

详细文档见官网,或pdf版本

启动

1
2
3
4
5
6
7
8
9
10
$ vim myapp.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()

启动 Web:

1
2
$ python myapp.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

curl http://127.0.0.1:5000/ 查看启动。

使用 MySQL

可以使用 SQLAlchemy 来操作数据库,安装

1
pip install flask-sqlalchemy

安装 flask-mysql,但报错

1
2
pip install flask-mysql
ImportError: No module named 'ConfigParser'

原因,Flask-MySQL 使用 MySQL-Python , 而后者不支持 Python3,替代方案有

  1. pip install flask-sqlalchemy mysqlclient
  2. pip install PyMySQL

uWSGI

安装

1
$ pip install uwsgi

测试 uwsgi --http :8002 --wsgi-file test.py 启动, test.py

1
2
3
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return "Hello World"

curl localhost:8002 查看启动。

uWSGI 启动 Flask Web 应用

uwsgi --http 127.0.0.1:8002 --processes 2 --enable-threads --wsgi-file myapp.py --callable=app

问题

    1. uwsgi --http 127.0.0.1:8002 --processes 2 --chdir /my/to/path/ --master --enable-threads --wsgi-file myapp.py --callable=app 报错,
      invalid request block size: 21573 (max 4096)...skip

原因: uwsgi 参数 -s 表示以 socket 方式提供通信端口,默认的协议是 tcp,
而通过浏览器访问使用的协议是http。

正确方式: 直接提供 http 服务。

如果使用第三方路由,如 Nginx, 则可以使用 -s 参数。

方便起见,将参数写入配置文件,如 xml, ini 类型。例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ vim uwsgiconfig.ini
[uwsgi]
#启动程序时所使用的地址和端口,通常在本地运行flask项目,
#地址和端口是127.0.0.1:5000,
#不过在服务器上是通过uwsgi设置端口,通过uwsgi来启动项目,
#也就是说启动了uwsgi,也就启动了项目。
socket = 127.0.0.1:8002
#项目目录
chdir = /home/supertool/ma/test/
#flask程序的启动文件,通常在本地是通过运行
# python manage.py runserver 来启动项目的
wsgi-file = myapp.py
#程序内启用的application变量名
callable = app
#处理器个数
processes = 4
#线程个数
threads = 2
#获取uwsgi统计信息的服务地址
stats = 127.0.0.1:9191

查看更多说明,执行 uwsgi -h

Nginx

使用 Nginx 进行反向代理配置,路由端口映射。

安装

以 root 权限安装:

1
$ yum install nginx

安装后,配置位置在 /etc/nginx 目录下,nginx.conf 为默认配置, 启动服务则在 sites 下增加配置, 在 nginx.conf 增加一行: include sites/*.conf。Ubuntu 下目录名有所不同,但作用是一样的。

配置

基本项目配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ vim basic-project.conf
server {
listen 80;
#listen 443;
large_client_header_buffers 4 512k;
server_name domain;
charset utf-8;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Is-EDU 0;
proxy_set_header Via "nginx";
auth_basic "nginx basic http for doc";
auth_basic_user_file /etc/nginx/conf/localhost_htpasswd;
more_set_headers "Access-Control-Allow-Origin *";
more_set_headers "Access-Control-Allow-Headers X-Requested-With";
more_set_headers "Access-Control-Allow-Methods GET,POST,OPTIONS";
index index.html;
root /path/to/projectname;
proxy_connect_timeout 600; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_read_timeout 600; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_send_timeout 600; #后端服务器数据回传时间(代理发送超时)
proxy_buffer_size 32k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k;
}
}

Nginx 可以编译添加第三方模块 more_set_headers 来自定义或清除相关head信息。

uWSGI 启动项目配置

在上述基础上增加两行,如下

1
2
3
4
5
6
7
8
9
10
11
12
$vim uwsgi-project.conf
server {
...
location / {
...
include uwsgi_params
uwsgi_pass 127.0.0.1:8002
...
}
...
}

启动

1
/usr/sbin/nginx -c /etc/nginx/conf/nginx.conf

-c 制定配置文件的路径,不加 -c 会自动加载默认路径下的配置文件。

查看更多说明,执行 nginx -h

1
2
3
4
5
6
7
8
9
10
11
12
13
nginx version: nginx/1.8.1
Usage: nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /usr//)
-c filename : set configuration file (default: /etc/nginx/nginx.conf)
-g directives : set global directives out of configuration file

注意 -s signal 控制主进程。

重启 Nginx, nginx -s reload

总结

每个模块都可能会遇到些问题,多看官方文档,多使用 Google,Bing 和 stackoverflow.com。