flask+gevent+gunicorn+nginx 快速部署

一、安装依赖:

1
2
3
4
5
6
7
8
9
yum install -y gcc gcc-c++ kernel-devel
yum install -y readline-devel pcre-devel openssl-devel openssl zlib zlib-devel pcre-devel mysql-devel
yum install -y python-devel libevent MySQL-python lrzsz
yum -y install bzip2*
二、编译安装python环境到2.7.8
wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz
tar -zxvf Python-2.7.8.tgz
cd Python-2.7.8
./configure && make && make install

执行命令查看版本信息:

1
2
python -V
2.7.8

三、安装pip和库

1
2
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py

安装库:flask、gevent、gunicorn

1
2
3
pip install flask
pip install gevent
pip install gunicorn

四、安装nginx

这里我使用带lua配置的openresty,以后做一些小的东西可以用lua脚本来处理

1
2
3
4
5
6
7
8
9
10
11
wget http://openresty.org/download/ngx_openresty-1.7.2.1.tar.gz
tar -zxvf ngx_openresty-1.7.2.1.tar.gz
cd ngx_openresty-1.7.2.1
./configure --prefix=/opt/openresty \
--with-pcre-jit \
--with-ipv6 \
--without-http_redis2_module \
--with-http_iconv_module \
-j2
make && make install
ln -s /opt/openresty/nginx/sbin/nginx /usr/sbin/

执行nginx -v,查看版本信息

1
2
nginx -v
nginx version: openresty/1.7.2.1

五、配置nginx

1
vi  /opt/openresty/nginx/conf/nginx.conf

在 /opt/openresty/nginx/conf/nginx.conf 中,http节点下添加如下的server节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name www.pytest.com;

location / {
proxy_pass http://127.0.0.1:5000;
proxy_redirect default;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}

修改nginx的一些配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#user  nobody;
#服务器是2cpu的
worker_processes 2;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
use epoll;
worker_connections 4096;
}
#http配置 下略

启动nginx:

1
nginx

查看nginx启动情况

1
2
3
4
5
ps -ef|grep nginx
root 21899 1 0 10:16 ? 00:00:00 nginx: master process nginx
nobody 21900 21899 0 10:16 ? 00:00:00 nginx: worker process
nobody 21901 21899 0 10:16 ? 00:00:00 nginx: worker process
root 21903 2243 0 10:16 pts/0 00:00:00 grep nginx

如果是生产服务器,请详细配置iptables的规则,这里我是测试服务器,则关闭所有iptables规则:

1
/etc/rc.d/init.d/iptables stop

访问主机就可以看到nginx的欢迎页面了。
六、配置gunicorn启动文件
创建文件夹和日志文件夹

1
2
3
4
mkdir /var/python
mkdir /var/python/gunicorn_log
chmod 755 /var/python/
chmod 755 /var/python/gunicorn_log/

创建配置文件:

1
vi /var/python/gun.conf

内容如下:

1
2
3
4
5
6
7
8
9
bind='127.0.0.1:5000'
workers=4
backlog=2048
worker_class="gevent" #sync, gevent,meinheld
debug=False
proc_name='gunicorn.pid'
pidfile='/var/log/gunicorn/debug.log'
loglevel='error'
daemon=True

七、创建测试文件:

1
vi /var/python/flask_test.py

复制以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask  
from werkzeug.contrib.fixers import ProxyFix

app = Flask(__name__)

@app.route("/")
def index():
return "Hello World flask"

app.wsgi_app = ProxyFix(app.wsgi_app)
if __name__ == "__main__":
app.run()

八、启动flask应用:

1
2
cd /var/python/
gunicorn -c gun.conf flask_test:app

查看python进程:

1
2
3
4
5
6
7
ps -ef|grep python
root 22066 1 0 10:40 ? 00:00:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gun.conf flask_test:app
root 22071 22066 0 10:40 ? 00:00:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gun.conf flask_test:app
root 22072 22066 0 10:40 ? 00:00:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gun.conf flask_test:app
root 22075 22066 0 10:40 ? 00:00:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gun.conf flask_test:app
root 22078 22066 0 10:40 ? 00:00:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gun.conf flask_test:app
root 22084 22025 0 10:41 pts/1 00:00:00 grep python

九、测试访问:

修改本地hosts文件,如下:

1
2
#这里填入你的服务器ip
192.168.150.3 www.pytest.com

在浏览器输入www.pytest.com即可看到 flask 框架输出的 hello world

十、配置node.js对比环境

我们和Node.js的express框架对比,版本4.9.0,node.js版本0.10.28,测试代码,保存为node_test.js

1
2
3
4
5
6
7
8
var express = require('express');
var app = express();

app.get('/', function(req, res){
res.send('hello world express');
});

app.listen(6000);

利用pm2启动4个进程

1
pm2 start node_test.js -i 4 --name 'node_test'

增加nginx配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name www.nodetest.com;

location / {
proxy_pass http://127.0.0.1:6000;
proxy_redirect default;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}

重新启动nginx

1
2
pkill nginx
nginx

本地增加hosts

1
2
#这里填入你的服务器ip
192.168.150.3 www.nodetest.com

这样我们访问 www.nodetest.com 就可以看到 hello world express 字样了。

十一、压力测试对比

先压力测试python的

1
ab -c 1000 -n 10000 http://www.pytest.com/

结果如下:

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
34
35
36
Server Software:        openresty/1.7.2.1
Server Hostname: www.pytest.com
Server Port: 80

Document Path: /
Document Length: 17 bytes

Concurrency Level: 1000
Time taken for tests: 33.566 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1790000 bytes
HTML transferred: 170000 bytes
Requests per second: 297.92 [#/sec] (mean)
Time per request: 3356.600 [ms] (mean)
Time per request: 3.357 [ms] (mean, across all concurrent requests)
Transfer rate: 52.08 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 0.7 3 8
Processing: 60 3192 580.3 3352 3427
Waiting: 10 1687 962.8 1684 3408
Total: 64 3195 580.3 3354 3431

Percentage of the requests served within a certain time (ms)
50% 3354
66% 3381
75% 3391
80% 3399
90% 3408
95% 3417
98% 3422
99% 3426
100% 3431 (longest request)

然后我们压力测试node.js的:

1
ab.exe -c 1000 -n 10000 http://www.nodetest.com/

结果如下:

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
34
35
36
Server Software:        openresty/1.7.2.1
Server Hostname: www.nodetest.com
Server Port: 80

Document Path: /
Document Length: 19 bytes

Concurrency Level: 1000
Time taken for tests: 25.853 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 2270000 bytes
HTML transferred: 190000 bytes
Requests per second: 386.80 [#/sec] (mean)
Time per request: 2585.300 [ms] (mean)
Time per request: 2.585 [ms] (mean, across all concurrent requests)
Transfer rate: 85.75 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 0.8 2 32
Processing: 65 2472 587.9 2476 3775
Waiting: 9 1361 795.0 1364 3771
Total: 67 2474 587.9 2478 3777

Percentage of the requests served within a certain time (ms)
50% 2478
66% 2512
75% 2528
80% 2538
90% 2562
95% 3704
98% 3741
99% 3763
100% 3777 (longest request)

p.s.

另外记一下nginx的一个静态文件rewrite规则:

location ~ ^/download/ {
rewrite ^/download/sg(\d+).(\d+)-(.+).exe$ /download/sg$1.$2.exe break;
}