Flask+Nginx+Gunicorn+Redis+Mysql搭建一個小站

首先簡單介紹一下這幾個東東。
Flask是一個輕量級的Web應用框架, 基於Werkzeug和 Jinja2 模板引擎,使用 Python編寫,可擴展強。
Nginx是一個高性能的 HTTP 和 反向代理服務器,在高併發方面表現很是不錯。
Gunicorn 是一個Python WSGI UNIX的HTTP服務器,從Ruby的獨角獸(Unicorn )項目移植,能與不少Web框架兼容,只需很是簡單的執行,輕量級的資源消耗,以及至關迅速。
Redis是一個高性能的key-value存儲系統,支持集合、列表、字典等複雜的數據結構,數據既能夠保存在內存中也能夠持久化到硬盤,對關係數據庫起到很好的補充。

前段時間作了個小站,目前已上線,使用到了這幾個東東。算起來學習python後臺開發有4個月了,可是水平仍是菜鳥級別,因此本文也就簡單講講配置問題以及該項目的架構,若有錯誤,請各位看官指正。因爲是小站,目前訪問人數也不是特別多,天天幾十萬IP,因此如今就一臺服務器。前端使用nginx作反向代理和動靜分離(把css、js、image、html等靜態文件直接經過nginx轉發,不經過後端處理),後端使用gunicorn+flask的方式,剛開始就直接使用flask跑,可是有一次就出現502了,發現因爲flask是單進程處理請求的,不像Tornado的異步,同時訪問的人數稍微過多,就會出現阻塞的狀況,致使nginx出現502的問題。gunicorn能夠指定多個工做進程,底層實現應該是經過調用fork函數建立子進程,這樣就能夠很好的利用服務器多核的特性了,實現併發功能。進程數應該指定多少呢,能夠參考gunicorn官網上的一個例子:workers = multiprocessing.cpu_count() * 2 + 1。爲了減小服務端的壓力,對訪問比較多的頁面作了靜態化處理,而後把訪問和變化都比較頻繁的數據使用redis作緩存處理,關係數據庫使用的是mysql,網站的圖片使用CDN的。javascript

flask和redis的安裝就不講述了,也十分簡單,下面主要講nginx和gunicorn的配置。
1.安裝和配置nginx
首先安裝pcre,讓安裝Nginx支持rewrite,這個功能仍是挺重要的css

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.20.tar.bz2
bzip2 -d pcre-8.20.tar.bz2
tar xvf pcre-8.20.tar
cd pcre-8.20.tar/
./configure
sudo make && sudo make install

安裝nginxhtml

wget http://sysoev.ru/nginx/nginx-1.0.0.tar.gz
tar zxvf nginx-1.0.0.tar.gz
cd nginx-1.0.0
./configure
sudo make && sudo make install
啓動nginx
sudo /usr/local/nginx/sbin/nginx
關閉nginx
sudo /usr/local/nginx/sbin/nginx -s stop
重啓nginx
sudo /usr/local/nginx/sbin/nginx -s reload
或者
sudo kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
( kill -HUP 殺掉某進程 並從新讀取配置文檔 啓動該進程)

測試:打開瀏覽器,輸入ip,若是一切正常將會看到:Welcome to nginx!
可能會出現的問題:
啓動nginx時出現
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
解決辦法:
ps -ef | grep nginx查看nginx是否已啓動
若是已經啓動:sudo kill -9 ‘nginx pid’
不然 sudo netstat -nltp查看80端口被哪一個應用給佔了
而後sudo kill -9 pid前端

配置nginx
假設個人應用監聽的端口是8888,本機ip是192.168.60.146,修改hosts文件,添加:
192.168.60.146 www.app.com
這樣你在本機訪問www.app.com這個域名的時候,系統就不會提交到DNS域名解析服務器,而是直接訪問配置的IP地址192.168.60.146,十分方便,可是hosts是不支持通配符的,像*.app.com,這樣就沒法設置二級域名了,解決方案能夠參考個人這篇文章http://codingnow.cn/unix/431.html
接下來就要配置當用戶訪問www.app.com這個域名時,如何能訪問到咱們的應用呢,此時就須要配置nginx了。java

創建用戶及用戶組node

sudo /usr/sbin/groupadd zjh 
sudo /usr/sbin/useradd -g zjh zjh

配置nginx.conf,通常位於/usr/local/nginx/conf/目錄下python

#運行用戶組和用戶
user zjh zjh;
#啓動進程,一般設置成和cpu的數量相等
worker_processes 1;
#全局錯誤日誌及PID文件
error_log logs/error.log;
pid logs/nginx.pid;
 
#工做模式及鏈接數上限
events {
#單個後臺worker process進程的最大併發連接數
worker_connections 1024;
#epoll是多路複用IO(I/O Multiplexing)中的一種方式,可是僅用於linux2.6以上內核,能夠大大提升nginx的性能
use epoll;
}
 
#設定http服務器,利用它的反向代理功能提供負載均衡支持
http {
#設定mime類型,類型由mime.types文件定義
include mime.types;
default_type application/octet-stream;
#設定日誌格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
 
access_log off;
 
#sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,
#必須設爲 on,若是用來進行下載等應用磁盤IO重負載應用,可設置爲 off,以平衡磁盤與網絡I/O處理速度,下降系統的uptime.
sendfile on;
tcp_nopush on;
tcp_nodelay on;
 
#開啓gzip壓縮
gzip on;
gzip_min_length 1000;
gzip_proxied any;
gzip_types text/plain text/css text/xml
application/x-javascript application/xml
application/atom+xml text/javascript
#鏈接超時時間
keepalive_timeout 65;
proxy_read_timeout 200;
proxy_next_upstream error;
 
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
 
include sites/*.conf;
}

在/usr/local/nginx/conf/目錄下建立一個sites目錄,裏面存放具體應用的配置文件,便於管理。這裏建立app.conf,內容以下mysql

server {
  #偵聽80端口
    listen 80;
#定義使用www.xx.com訪問
    server_name www.app.com;
    client_max_body_size 10M;
 
   #設定本虛擬主機的訪問日誌
    access_log logs/app.log main;
 
  #默認請求
    location / {
        #請求轉向本機ip:8888
        proxy_pass http://192.168.60.146:8888;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    #配置靜態文件轉發
    location ~.*(js|css|png|gif|jpg|mp3|ogg)$ {
        root /home/zhoujianghai/temp/data/app/medias/;
    }
    #配置靜態頁面轉發
    location ~.*(html)$ {
        root /home/zhoujianghai/temp/data/app/app_static_pages/;
    }
}

重啓nginx,在瀏覽器訪問:www.app.com 就會訪問到你的應用程序了linux

2. 安裝和配置Gunicornnginx

sudo easy_install gunicorn

編寫配置文件gunicorn.conf

workers = 4
bind = ‘192.168.60.146:8888′
proc_name = ‘app’
pidfile = ‘/tmp/app.pid’

執行:

gunicorn --config gunicorn.conf app:app

解釋一下app:app,前面的app表明當前運行的module名,也就是文件名,後面的app是建立的Flask對象。固然我實際的項目中module名不是app,這裏只是做爲demo。如今你能夠經過

ps -ef | grep app

來查看有多少app進程。
下面是一個最簡單的flask應用demo:app.py,由於使用gunicorn來運行,因此就沒有調用run方法。關於Flask的快速入門能夠參考這一篇:http://codingnow.cn/python/409.html

相關文章
相關標籤/搜索