Python基礎 - Ubuntu+Nginx+uwsgi+supervisor部署Flask應用


網上找了許多講關於Flask應用部署的文章幾乎都是一個helloworld的Demo,按照helloworld來部署都沒問題,但實際項目部署時還是遇到了不少問題。在這里簡單寫下自己成功部署的過程,防止下次部署時就忘記了,好記性不如爛筆頭這句話不是蓋的。


部署環境:

OS: Ubuntu 14.04.4 LTS
Python: 2.7.6
Nginx: nginx/1.4.6(Ubuntu)
uwsgi: 1.9.17.1-debian
supervisord: 3.0b2 

這個署架構中Nginx主要作為前置服務器,負責分發處理來自客戶端的請求,uwsgi作為后端Flask應用的容器,supervisor作為監控程序,即看門狗。
由於項目源碼是直接放在阿里雲服務器上(項目已開源http://github.com/yelongyu/chihu.git),所以這里省略了項目上傳這一步,並假設已經安裝好了Python開發環境,若未配置好Python開發環境,請先配置好,本文假設項目所在的位置為/home/chihu

環境配置:

sudo apt-get install uwsgi-plugin-python      # 這個不裝的話當發起請求時uwsgi會報錯

若是Python3的話改為:

sudo apt-get install uwsgi-plugin-python3

STEP 1: Nginx安裝配置

安裝Nginx

1. 輸入Nginx安裝命令

sudo apt-get install nginx

2. 啟動Nginx服務器:

sudo service nginx start

啟動Nginx服務器並用瀏覽器訪問測試一下Nginx是否安裝成功,若成功,進入下一步。

3. 配置Nginx
進入/etc/nginx/sites-enabled/文件夾 注意不是sites-available

直接配置/etc/nginx/nginx.conf也可以,不過要根據其語法來配置,其實最后nginx.conf還是會調用/etc/nginx/sites-enabled/default的配置。

  • 先將默認配置文件default備份(養成修改配置前先備份的習慣):
mv default default.bak
  • 編輯配置文件:
vim default
  • 寫入配置內容:
server {                                                                       
    listen 80;                   # 服務器監聽端口                                                 
    server_name 110.110.110.110; # 這里寫你的域名或者公網IP                                                    
    charset      utf-8;          # 編碼                                                  
    client_max_body_size 75M;    # 之前寫的關於GET和POST的區別,這里應該是原因之一吧                                                   
                                                                                   
    location / {                                                                   
        include uwsgi_params;         # 導入uwsgi配置                                            
        uwsgi_pass 127.0.0.1:8000;    # 轉發端口,需要和uwsgi配置當中的監聽端口一致                                             
        uwsgi_param UWSGI_PYTHON /home/chihu/venv;       # Python解釋器所在的路徑(這里為虛擬環境)      
        uwsgi_param UWSGI_CHDIR /home/chihu;             # 項目根目錄     
        uwsgi_param UWSGI_SCRIPT manage:app;             # 項目的主程序,即Flask app所在的位置                           
    }                                                                              
}

輸入:wq保存配置文件。配置好了之后別急着啟動Nginx,記得先通過nginx -t測試一下配置文件是否正確,若檢測配置文件失敗,再好好檢查下配置文件有沒有疏漏。

此時訪問Nginx服務器應該會得到502 Bad Gateway的提示,因為請求被Nginx轉發了,但是並沒有轉發服務器來處理請求(還沒有配置好uwsgi)。


STEP 2: uwsgi安裝配置

安裝uwsgi

sudo apt-get install uwsgi

編寫uwsgi配置文件
在項目文件根目錄新建配置文件uwsgi.iniuwsgi支持多種配置文件格式: xml, ini, json等)

vim uwsgi.ini

寫入配置內容如下:

[uwsgi]                                                                        
                                                                               
socket = 127.0.0.1:8000             # uwsgi的監聽端口                                              
                                                                               
plugins = python                    # 這行一定要加上,不然請求時會出現-- unavailable modifier requested: 0 --錯誤提示                                                   
                                                                               
chidir = /home/chihu                # 項目根目錄                                           
                                                                               
wsgi-file = manage.py               # flask程序的啟動文件                                           
                                                                     
callable = app                      # 程序變量名                                           

輸入:wq保存配置文件,可以通過uwsgi uwsgi.ini來啟動uwsgi。


STEP 3: 啟動及測試

Nginxuwsgi都配置好了之后下一步就是啟動Nginxuwsgi了。

  • 啟動Nginx
sudo service nginx restart
  • 啟動uwsgi
    進入項目根目錄,即uwsgi.ini所在的目錄,執行以下命令。
uwsgi wsgi.ini

若一切正常的話就可以在終端上看到uwsgi的啟動信息了。

測試:
打開瀏覽器訪問服務器,若可以正常訪問,說明Nginxuwsgi配置成功了,但離真正項目上線還差一段,因為uwsgi是直接在前台啟動的,當我們的連接終端跟服務器斷開的時候uwsgi進程也被關閉了,所以我們需要讓uwsgi在后台運行。

STEP 4: 進程監控

原本打算用uwsgi emperor的方式運行uwsgi即讓uwsgi成為守護進程(daemon),但是折騰了一天還是沒解決問題,遂換supervisor。(折騰uwsgi emperor到后面發現問題是,當單獨使用uwsgi的時候一切正常,但一使用uwsgi emperor就會出現os.environ.get()獲取不到環境變量的問題,但環境變量明明可以通過env看到,直接在Python終端上執行os.environ.get()也可以獲取到.....等有時間再回過頭了折騰。)

單獨一個uwsgi程序運行短時間可能沒問題,但是網絡狀況瞬息萬變,萬一uwsgi進程掛了網站也就訪問不了了.....為了防止出現意外情況,還需要一個監控程序來監控uwsgi的狀況,這里該supervisor出場了。具體什么是supervisor可以Google之。

1. 首先安裝supervisor

sudo apt-get install supervisor

2. 生成默認配置文件

echo_supervisord_config > supervisord.conf

3. 加入監控程序的配置

[program:project_name]          # project_name這里寫上你的項目名稱,如我的為[project:chihu]
command = uwsgi --ini /home/chihu/uwsgi.ini  # 跟手動啟動的命令一樣
stopsignal=QUIT
autostart=true
autorestart=true
stdout_logfile=/var/log/uwsgi/supervisor_chihu.log      # 運行日志
stderr_logfile=/var/log/uwsgi/supervisor_chihu_err.log  # 錯誤日志

4. 啟動supervisord

supervisorctl reload

5. 檢查uwsgi進程是否正常運行

ps aux|grep uwsgi

如果一切正常,此時應該可以看到uwsgi進程
嘗試kill掉uwsgi進程看supervisor會不會重新啟動一個新的uwsgi進程

sudo killall uwsgi

若再次通過ps aux|grep uwsgi查看發現有新的uwsgi進程在運行,那差不多可以祝你成功了, God bless you。

ERROR

supervisorctl reload   

提示錯誤

error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.py line: 224

issue
只需手動啟動supervisord即可:

sudo supervisord -c configfile.conf

這里涉及到一個啟動程序的用戶的問題,好幾次莫名不能通過os.environ.get()到系統中的環境變量,導致程序出錯。一步一步排查猜測是因為啟動程序的用戶不匹配的問題,遂將啟動程序的用戶從root改為普通的登陸用戶,問題解決,但這里還有疑問,因為環境變量是設置在/et/environment當中的,按理這里設置的應該是全局都可以訪問的環境變量,但是當用root用戶啟動程序時就不能訪問到環境變量,為了這個問題折騰了好幾天,總算解決了,但是當中的疑惑還是需要好好思考探索。


后記:
折騰了兩天終於搞定,有時候教程看着簡單,你的配置也和教程一樣,但就是由於各種錯誤無法運行,雖然說計算機非0即1,是我們人類最忠實可靠的伙伴,但是有時候就差那么一點點,有可能是軟件環境不對亦或是我們電腦的打開方式不對...總之,就是要有那么個折騰的過程,所謂吃一塹長一智,不折騰折騰估計過后就忘了怎么回事了,還是要勤動手不放棄,雖然被一個uwsgi emperor折騰得快要懷疑人生了,但我還是堅定不移地...改道supervisor了 :)

初次寫教程,文中可能有疏漏或寫得不夠恰當的地方,還請各位看官多多包涵,歡迎指正和交流。如果部署的過程中有問題也歡迎留言,雖然不能保證可以解決。

-EOF-

參考:

https://segmentfault.com/a/1190000004294634 # uwsgi及Nginx配置
http://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/#comment-2401229330 # uwsgi emperor
http://letgoof.me/2013/deploy-django-project-with-uwsgi-nginx-and-supervisor/ # supervisor配置
http://liyangliang.me/posts/2015/06/using-supervisor/ # supervisor & supervisord


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM