Ubuntu下使用Nginx+uWSGI+Flask(初體驗)

Ubuntu 18.04,Nginx 1.14.0, uWSGI 2.0.17.1,Flask,

 

前言

Windows不支持uWSGI!爲了上線自己的項目,只能選擇Linux。

自己前面開發了一個Flask應用webnews,現在,將它“移植”到Linux中。

 

注意,項目還會用到MongoDB數據庫,需要建立相應的MongoDB用戶。

 

Nginx是一個著名的反向代理服務器,在全球應用廣泛;uWSGI是一個支持uwsgi協議的Web服務器,支持部署Django、Flask等應用;Flask是Python的輕量級Web框架。

http://nginx.org/ (俄羅斯)

https://github.com/unbit/uwsgi (Rome?)

http://flask.pocoo.org/

 

注意,Nginx前天已經安裝好了,只是自己忙於將Nginx+uWSGI+Flask整合起來,所以,Nginx的配置、更厲害的使用方式暫時不清楚,同樣,還有uWSGI的,後面需要dig。

 

參考文章(大家也可以直接看這篇文章):

uWSGI+Nginx+Flask在Linux下的部署 - zhangjpn - 博客園

 

第一部:使用uWSGI部署參考文章中的Hello World應用

-安裝好用的vim編輯器

-建立Flask應用:一個簡單的文件flask0.py,輸出Hello World!

注意:if語句必須存在!後面自己移植項目到uWSGI運行時,因爲沒有這句,結果卡在了app.run()中。

-自己的第一個在Linux上運行的Flask應用運行起來啦!

 

注意,Flask本身的Web服務器僅僅用於測試、開發,不能用於正式環境——連接到Internet的環境,因此,需要uWSGI服務器。

 

-安裝uwsgi

pip3 install uwsgi

成功安裝了uwsgi-2.0.17.1!

-編寫uWSGI配置文件uwsgi0.ini

下面的配置來自前面的參考文章。不過,由於粗心,在編輯過程中把 http= 寫成了 http: ,結果浪費了不少時間。

http表示uWSGI服務器使用的協議爲http,也可以選擇http-socket、socket,後面會用到使用socket,表示支持uwsgi協議。

在和Nginx配合使用時,一般選擇使用socket。

wsgi-file很重要,表示包含Flask應用實例(app)的文件,touch-reload表示指定的目錄檢測到改變時重新加載應用——好像很重要但沒有直觀體驗&以此實現7*24小時不間斷服務嗎?

-關鍵點來啦!使用uwsgi部署Flask應用!

下面採用了配置文件的方式,也可以採用命令行的方式,不過,uwsgi的配置項很多,使用命令行?算了,統統寫到配置文件中吧!

疑問1,無法使用whereis找到uwsgi在哪裏;

疑問2,不能再uwsgi命令前面添加sudo;

疑問3,下圖紫色方框中的no internal routing support, rebuld with pcre support不知道怎麼解決——自己也重裝過pcre的,也卸載uwsgi後重裝uwsgi的,可是,這句總是存在;

服務器已啓動,注意下面的master、worker。

-訪問成功!

-訪問頁面時,輸出的日誌信息。

-退出:按Ctrl+C

下圖的第一個紫色方框中的^C就是Ctrl+C;

 

使用uWSGI同時運行多個Flask應用

-複製前面的配置文件,更改端口爲5002;

-端口5001、5002的Flask應用都啓動了;

-都可以訪問成功!

 

-使用nohup命令 將終端輸出的信息 轉存到 當前目錄的nohup.out中。

 

注意,上面的uwsgi配置文件都是使用的http協議。

 

第二部:使用Nginx反向代理到uWSGI中的Flask應用

注意,本部分的Flask應用仍然使用的是http協議。

要實現Nginx反向代理到uWSGI的應用,需要配置Nginx。

Nginx的配置文件位於/etc/nginx中,名爲nginx.conf,文中include了兩個目錄conf.d、sites-enabled

目前,目錄conf.d爲空,sites-enabled中存在一個符號鏈接default——鏈接到sites-available中的default。

注意,孤在修改配置文件時犯錯了,先是修改sites-enabled中的符號鏈接,可是,符號鏈接是不能修改的,最後跑到sites-available中才修改了Nginx的配置。

 

注意,在Nginx這邊操作過程中,請確保uWSGI已經部署了Flask應用。

 

Flask應用已經部署到uWSGI中:127.0.0.1:5001。

 

-在sites-available中配置location;

在默認的location處進行配置——默認配置爲註釋掉的try_files行;

說明,因爲uWSGI使用的是http協議運行Flask應用,因此,使用proxy_pass;

注意,下面的配置“可能”存在問題,在端口號5001後面或許要添加斜槓(/);

-代理兩個uWSGI上的Flask應用;

 

至此,實現了Nginx反向代理簡單的應用。

 

----

 

下面移植Windows上的webnews項目到Ubuntu,並在uWSGI中啓動,並通過Nginx反向代理訪問。

 

-拷貝到Windows和虛擬主機的共享目錄;

拷貝完成後,在Ubuntu中的這些文件夾和文件屬於root用戶,而當前用戶時log——管理員級別;

-拷貝webnews到當前用戶log的主目錄;

-將webnews項目部署到uWSGI服務器上——出現錯誤,模塊導入失敗;

使用webnews項目平級的runApp.py文件來運行,在之前使用flask run時可以找到webnews模塊,但現在不可以了。

什麼原因呢?webnews模塊搜索不到,而這個webnews模塊正是項目主目錄,但在uWSGI服務器中,它不“認”這個目錄了。

可能的解決方法:

0.將webnews模塊所在目錄添加到PYTHONPATH環境變量中;

第一時間使用了這個方法,奇怪的是,Ubuntu中的PYTHONPATH默認爲空。

1.安裝應用;

2.修改uWSGI配置文件

2.1.使用chdir配置項切換到webnews模塊所在目錄;

今天使用了這個辦法;

2.2.使用pythonpath配置項;

-通過方法1解決問題後啓動,成功——今天才發現,到了這裏其實並不算成功的!

 -訪問服務器上的網頁失敗——一直在轉動,但就是出不來頁面;

-按下Ctrl+C,頁面顯示成功;

爲何如此?因爲自己寫的runApp.py中運行了app.run(),程序在這裏掛起了

按下Ctrl+C退出了app.run(),然後進入了uWSGI服務器運行app的進程(叫進程合適嗎?)

刪除這句,或者,使用if __name__...包含它即可消除問題。

 

注意,本部分的uWSGI仍然使用http協議部署Flask應用。 

 

第三部:使用uwsgi協議進行通信

使用uwsgi協議進行通信的涵義是,uWSGI服務器部署Flask應用時使用uwsgi協議(socket),Nginx和uWSGI通信使用uwsgi協議。

 

有文章介紹說,uWSGI可以支持3個協議配置方式:http、http-socket、socket,本部分均採用socket方式,這個方式的配置會導致無法通過瀏覽器訪問Flask應用,但卻是作爲後端服務器(前端服務器就是Nginx了)的必須配置。

 

本部分解決了兩個問題,然後去的了最終的勝利:

1.socket文件的權限

使用uWSGI加載webnews應用後,socket文件的權限變爲755,懷疑是因爲這個原因才導致後續工作失敗,無法訪問頁面的;

看了一篇博文後找到了解決方法:在配置文件中添加chmod-socket配置項;不過博文本身不是爲了解決這個問題的;

示例:

 

手動改爲777的權限也是可以訪問的,但是,下次uWSGI加載應用時,socket文件的權限又變回去了:

 

這個問題消耗了自己大量精時,參考文件裏面說的配置很簡單啊!可是,真正動手纔會知道有什麼坑,不過,本文提供了填坑的方法!

 

2.uWSGI加載runApp.py後卡在了腳本中的語句app.run()中,需要按一次Ctrl+C纔可以正常運行

兩者都浪費了不少時間,但解決方法都挺簡單。

在解決權限問題的過程中,發現權限問題解決後,頁面仍然不能訪問,直到在uWSGI的終端按下Ctrl+C,頁面纔會顯現出來。

注意Debug mode: off下的方框中開頭的^C。

感覺程序卡在什麼地方了!

和前面簡單的Hello World應用對比後發現,自己的webnews項目在uWSGI中啓動真的存在問題:

準備去百度找答案,但否決了。在程序裏面寫調試語句吧,runApp.py中寫一些打印語句。結果uWSGI運行後,app.run()前面的調試語句輸出了,而其後的卻沒有:

哇哦,還好沒有去百度找,否則,不知道多少精時要被耗掉呢!

 

參考簡單的Hello World應用,將app.run()包裹在if __name__ == '__main__'中,問題得到解決。

啓動就正常了,訪問也正常了:

 

補充說一下socket參數的配置,可以是IP+端口,也可以是socket文件(最開始自己還不曉得*.sock是個文件,還想怎麼得到它,原來,一個touch指令就可以新建了,不用往裏面輸入任何內容)。

在所有問題解決後,本部分的示例都採用的是socket文件形式,但是,IP+端口的方式在之前也嘗試過,HelloWorld應用是可以的,webnews項目自己沒有再測試過。

兩者的區別,孤還需要繼續dig。

 

參考資料:

將uwsgi配置參數從端口號改爲socket文件,需要給uwsgi哪些權限?

【Flask】 利用uWSGI和Nginx發佈Flask應用 (自己尚未讀完,忙着解決問題了,)

 

後記

在不瞭解、熟悉uWSGI、Nginx的情況下開始了自己的實踐,結果,遇到問題後,爲了解決花了好多時間。

要是自己一開始就熟悉,那麼,分分鐘可以搞定吧!

只是,孤以爲【帶着問題去學習】是一種好的方式,所以,邊動手邊學習,的確學到了不少,也的確取得了一些成功。

但是,不懂得還是不懂啊,還挺多的。

所以,後面會好好看看uWSGI、Nginx的官文和其它資料。

必須要感謝各位先行者網友的博文,的確大大加快了自己的進度,要知道,時間就是金錢啊,更是自己的生命!

也因此,孤的博文會寫的較爲詳細,或許存在一些問題,但,知道的都說清楚了,不知道的也告知不知道了。

今天,就這麼過去了吧!

需要明確每日目標,減少浪費,加快進度,提高效率!

需要瘋狂一點!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章