Flash+gunicorn+nginx+gevent
其实比如Flask,webpy,Django、CherryPy 都带着WSGI server 。当然性能都不好,自带的web server 更多的是测试用途, 线上发布时,则使用高性能的wsgi server或者是联合nginx做uwsgi
神器Gunicorn是一个Python WSGI UNIX的HTTP服务器。这是一个预先叉工人模式,从Ruby 的独角兽(Unicorn)项目移植。该Gunicorn服务器与各种Web框架兼容,我们只要简单配置执行,轻量级的资源消耗,以及相当迅速。它的特点是与各个web结合紧密,部署特别方便
一,安装nginx
1.1,先安装相应的编译工具
yum -y install epel-release
yum -y install yum-axelget wget
yum install lrzsz
yum -y install gcc gcc-c++ autoconf automake
yum -y install zlib zlib-devel openssl openssl-devel pcre-devel
1.2,下载163网易的yum源:
wget -O /etc/yum.repos.d/CentOS-Base.repo https://www.doczj.com/doc/6210350293.html,/repo/Centos-7.repo wget https://www.doczj.com/doc/6210350293.html,/epel/6/i386/epel-release-6-8.noarch.rpm
1.3,建立nginx 用户和用户组
# groupadd -r nginx
# useradd -s /sbin/nologin -g nginx -r nginx
查看用户及用户组信息
# id nginx
注:
zlib:nginx提供gzip模块,需要zlib库支持
openssl:nginx提供ssl功能
pcre:支持地址重写rewrite功能
1.4,编译安装nginx
wget ftp://https://www.doczj.com/doc/6210350293.html,/pub/software/programming/pcre/pcre2-10.23.tar.bz2 # wget https://www.doczj.com/doc/6210350293.html,/download/nginx-1.12.1.tar.gz
# tar zxvf nginx-1.12.1.tar.gz
# cd nginx-1.12.1
# ./configure --prefix=/usr/local/nginx
# make -j4 && make install
1.5,启动nginx
/usr/local/nginx/sbin/nginx
关闭nginx
/usr/local/nginx/sbin/nginx -s stop
重启nginx
sudo /usr/local/nginx/sbin/nginx -s reload
或者kill -HUP `cat /usr/local/nginx/logs/nginx.pid
( kill -HUP 杀掉某进程并重新读取配置文档启动该进程)
接下来访问localhost证明nginx安装成功
1.6,Nginx启动centos6脚本:
# cat /etc/init.d/nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /usr/local/nginx/nginx.conf
# config: /usr/local/nginx/html
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING"= "no"] && exit0
nginx="/usr/loca/nginx/sbin/nginx"
prog=$(basename$nginx)
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
[ -f /usr/local/nginx/sbin/nginx] && . /usr/local/nginx/sbin/nginx lockfile=/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`nginx -V 2>&1 | grep"configure
arguments:"| sed's/[^*]*--user=\([^ ]*\).*/\1/g'-` options=`$nginx -V 2>&1 | grep'configure arguments:'`
for opt in$options; do
if[ `echo$opt | grep'.*-temp-path'` ]; then
value=`echo$opt | cut-d "="-f 2`
if[ ! -d "$value"]; then
# echo "creating" $value
mkdir-p $value && chown-R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] || exit5
[ -f $NGINX_CONF_FILE ] || exit6
make_dirs
echo-n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq0 ] && touch$lockfile
return$retval
}
stop() {
echo-n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq0 ] && rm-f $lockfile
return$retval
}
restart() {
configtest || return$?
stop
sleep1
start
}
reload() {
configtest || return$?
echo-n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE }
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null2>&1 }
case"$1"in
start)
rh_status_q && exit0
$1
;;
stop)
rh_status_q || exit0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit0
;;
*)
echo$"Usage: $0
{start|stop|status|restart|condrestart|try-restart|reload|force-reload| configtest}"
exit2
esac
为此脚本赋予权限:
# chmod +x /etc/init.d/nginx
[root@nginx ~]# chkconfig --add nginx
[root@nginx ~]# chkconfig nginx on
[root@nginx ~]# chkconfig nginx --list
1.7,nginx启动centos7脚本
vim /usr/lib/systemd/system/nginx.service
#输入下面内容,并保存
[Unit]
Description=nginx - high performance web server
Documentation=https://www.doczj.com/doc/6210350293.html,/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAIN
PID PrivateTmp=true
[Install]
WantedBy=multi-user.target
二,安装python3
2.1,下载python3源码安装包
# wget --no-ckeck-certificate
https://https://www.doczj.com/doc/6210350293.html,/ftp/python/3.6.2/Python-3.6.2.tgz
或者访问https://https://www.doczj.com/doc/6210350293.html,/downloads/release/python-362/
2.2,解压安装python3
# tar xvf Python-3.6.2.tgz
# cd Python-3.6.2
# mkdir /usr/local/python3
# ./configure --prefix=/usr/local/python3 --enable-shared
# make -j4&& make install
2.3,让系统默认使用Python
3.6.2
注意:在/usr/bin中有python、python2、python2.7三个文件依次指向后者,我们将python 备份
# cd /usr/bin
# mv python python.bak
# ln -s /usr/local/python3/bin/python3 /usr/bin/python
# ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
# python -V 测试python3版本,如果出现以下错误:
python: error while loading shared libraries: libpython3.6m.so.1.0
# cd /etc/ld.so.conf.d/
# vim python3.conf
添加路径/usr/local/python3/lib
保存退出之后,运行ldconfig
2.4,修改系统的yum源调用
注意:编译安装之后在/usr/local/python3/bin下会自动生成一个python3的连接,他指向bin 目录中的python3.6
因为yum使用python2,因此替换为python3后可能无法正常工作,继续使用这个python2.7.5 # vim /usr/bin/yum
把文件头部的#!/usr/bin/python改成#!/usr/bin/python2.7保存退出即可.
2.5,测试yum是否调用python3
# yum install htop -y
File "/usr/libexec/urlgrabber-ext-down", line 28
开了/usr/libexec/urlgrabber-ext-down看了下,也使用了/usr/bin/python,于是跟前面一样,改为2.7,完成.
2.6,pip3安装uwsgi
# pip3 install uwsgi
# ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi
# uwsgi --version
2.7,pip3安装virtualenv
# pip3 install virtualenv
# pip3 install flask
# ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv
# ln -s /usr/local/python3/bin/flask /usr/bin/flask
2.8,安装Gunicorn
Gunicorn 绿色独角兽是一个Python WSGI UNIX的HTTP服务器。这是一个pre-fork worker 的模型,从Ruby的独角兽(Unicorn )项目移植。该Gunicorn服务器大致与各种Web框架兼容,只需非常简单的执行,轻量级的资源消耗,以及相当迅速。
# pip3 install gevent
# pip3 install gunicorn
# ln -s /usr/local/python3/bin/gunicorn /usr/bin/gunicorn
2.9,配合gevent
gunicorn 默认使用同步阻塞的网络模型(-k sync),对于大并发的访问可能表现不够好,它还支持其它更好的模式,比如:gevent或meinheld。gevent是一个基于libev的并发库。它为各种并发和网络相关的任务提供了整洁的API。gunicorn对于“协程”也就是Gevent的支持非常好。
# mkdir -p /opt/yundao/
# mkdir /var/log/gunicorn
##### virtualenv /opt/venv
# source /opt//venv/bin/activate
# pip3 install gunicorn
# pip3 install gevent
# vim /opt/yundao/app/gun.py
[root@centos7 python]# cat gun.py
# import os
bind='127.0.0.1:5000'
backlog=2048
worker_class="gevent" #sync, gevent,meinheld
debug=True
proc_name='gunicorn.pid'
pidfile='/var/log/gunicorn/debug.log'
loglevel='debug'
#daemon=True
###### gunicorn -k gevent code:application
# meinheld
[root@centos7 python]# cat run_test.py
from flask import Flask
from flask import render_template_string
import os
from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World"
app.wsgi_app = ProxyFix(app.wsgi_app)
if __name__ == "__main__":
app.run()
[root@centos7 python]# gunicorn -c gun.conf run_test:app &
[root@centos7 python]# gunicorn -w4 -b0.0.0.0:5000 run_test:app &
监听本机的5000端口,工作模式为gevent,开启4个进程
2.10,安装supervisor
想要结束gunicorn 只需执行pkill gunicorn,有时候还的ps 找到pid 进程号才能kill。可是这对于一个开发来说,太过于繁琐,因此出现了另外一个神器—supervisor,一个专门用来管理进程的工具,还可以管理系统的工具进程。
wget https://https://www.doczj.com/doc/6210350293.html,/Supervisor/supervisor/zip/master
# or pip3 install supervisor
# unzip supervisor.zip
# cd supervisor && python setup.py install
# vim supervisor.conf
[program:myapp]
command=/usr/bin/gunicorn -w4 -b0.0.0.0:8000 myapp:app
directory=/opt/yundao/myproject
stopwaitsecs=0
autostart=false
autorestart=false
stdout_logfile=/var/log/gunicorn.log
stderr_logfile=/var/log/gunicorn.err
supervisord -c supervisor.conf
supervisorctl -c supervisor.conf status / stop / start / reload / [all] / [appname]
supervisor 还有一个web的管理界面,可以激活。更改下配置
[inet_http_server] ; inet (TCP) server disabled by default
port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for all iface)
username=user ; (default is no username (open server))
password=123 ; (default is no password (open server))
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
username=user ; should be same as http_username if set
password=123 ; should be same as http_password if set
;prompt=mysupervisor ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history ; use readline history if available
现在可以使用supervsior 启动gunicorn啦。运行命令 supervisord -c supervisor.conf
访问 http://127.0.0.1:9001 可以得到supervisor的web管理界面,访问 http://127.0.0.1:2170可以看见gunciron 启动的返回的hello world
2.11,项目目录结构
flashproject
app/
|----app.py
|----manage.py
|----requirements.txt
|----data.sqlite
|----gun.conf
|----static
|----templates
|----venv
三,配置nginx反向解析gunicorn
3.1,配置代理服务器nginx.conf
/usr/local/nginx/conf/目录下
# vim /usr/local/nginx/conf
server {
listen 80;
server_name 公网IP或者你已经解析的域名;
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 Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection $http_connection;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
检查配置文件/usr/local/nginx/sbin/nginx -t
3.2,压力测试对比
先压力测试python的
ab -c 1000 -n 10000 http://localhost/
3.3,压力测试后端
在另一台虚拟上进行用ab模拟并发请求
[root@rs-1 ~]# time ab -n 200 -c 200 http://192.168.1.252/
[root@centos7]# yum -y install p7zip
四,nginx反向代理
4.1反向代理:
客户端的请求过来之后交给反向代理服务器,然后反向代理服务器再交给后台真实的服务器。
http-server1:192.168.1.252(nginx服务)
http-server2:192.168.1.253(nginx服务)
nginx-proxy:192.168.1.254
[root@manager conf]# cat nginx.conf
#user nobody;
worker_processes 4;
events {
worker_connections 1024;
}
http {
upstream loadbance {
#upstream:反向代理的关键字loadbance:你可以理解为后台一组服务器的名称
#server:后台真实的服务器地址,可以是IP或者FQDN(如果是FQDN,别忘记解析
#listen:监听的端口,如果没有把原来nginx做web服务器的配置内容注销掉,建议改为其他端口
server 192.168.1.252;
# server 192.168.10.156 weight=3; //可以设置权值的哦
server 192.168.1.253;
# server 192.168.1.254 backup;
#如果其其他端口,后面请加端口号:X.X.X.X:8888
#proxy_pass:后面跟http://loadbance 此一定要和upstream后面(服务器组名称)的名称保持一致
}
server {
listen 80;
location / {
proxy_pass http://loadbance;
}
}
}
[root@manager conf]#