1. 程式人生 > >ubuntu下python+tornado+supervisor+nginx部署

ubuntu下python+tornado+supervisor+nginx部署

關系型 rem 一點 意願 lib str http請求 字段 int

由於之前在醫院采集的數據都是拍照得到的處方圖片,而需要用到的是處方的文本形式。因此這兩個星期寫了個小程序把服務器的圖片顯示給用戶(到時候雇一些人),讓用戶根據圖片錄入文字信息。

之前都是用java寫web,想到自己最近學機器學習要用python,所以用python來寫一下,此外,因為想用點新東西,也介於程序比較小,所以考慮用mongodb來存儲(雖然確實沒有必要)。

基本架構是這樣:(後臺語言)python +(web框架和web服務器)tornado + (數據庫)mongodb +(進程管理)supervisor + (反向代理)nginx

(1)python:我是看廖學峰的python教程 http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

學了一些基本的語句,然後做的時候不懂再查。

(2)tornado:我是看這個教程開始學的 http://docs.pythontab.com/tornado/introduction-to-tornado/

tornado用起來特別快,它既可以像spring裏轉發器那樣直接映射請求,又可以像tomcat那樣直接監聽某個端口的http請求,這些東西tornado都幫我們做好了,我們只需要書寫get和post方法就可以了。

其它的就和java web裏面差不多了。沒有springMVC和hibernate的框架,可以自己在python包裏面分層controller, service, dao。

(3)mongodb:

非關系型數據庫,對於一張表(mongodb裏叫collection集合)的每一行數據(mongodb裏叫document文檔)沒有要求統一相同的字段名,可多可少,參差不齊。還有一點就是不支持事務,在python中執行多條讀寫語句的時候沒法回滾,所以要自己想辦法在程序中防止並發導致的問題。

比如我需要從collection中find一個status為0的document出來並update成1,代表用戶正在查看,用戶進行修改後,然後設置status為2之後再放回去,在這裏0代表未瀏覽,1代表正在瀏覽,2代表已修改。這個時候可能很多個用戶同時取到了這個status為0的數據,這就違背了我們的意願,讓很多人對同一個數據進行了修改。可以考慮直接update_one把某個document的status由0改為1,然後增多一個唯一字段來標識這個document,用這個唯一字段來find到document,這個時候別的用戶是無法取到該document的,因為update_one的時候會上鎖,別人取不到這條數據。

(4)supervisor:supervisor是用python開發的進程管理程序,可以將普通的命令變成後臺的守護進程,並監控進程狀態。

安裝好後可以在/etc/supervisor/conf.d目錄下添加配置文件printprescription.conf,配置示例如下

[program:printprescription] #設置守護進程名
command = python /home/liaohuqiang/Code/printprescription/main2.py #設置執行命令
autorstart=true #設置隨supervisor的啟動而啟動
stdout_logfile = /home/liaohuqiang/Code/printprescription/printprescription.log #設置日誌路徑

配置完成後,可以開啟,關閉和重啟supervisor服務。可以用supervisorctl status查看進程狀態,還可以在相關日誌文件查看錯誤信息

sudo /etc/init.d/supervisor start
sudo /etc/init.d/supervisor stop
sudo /etc/init.d/supervisor restart

sudo supervisorctl status printprescripton
vim cat /var/log/supervisor/xxx.log

  

(5)nginx:nginx用於反向代理,可以監控80端口,把相應的請求轉發到別的主機以及別的端口上,這裏我們顯示的圖片的路徑不在tornado的static中(static用來存放js和css等前端靜態資源),而是在服務器另外的位置,所以可以通過nginx的轉發來獲取圖片。另一方面,一般不會暴露其它端口(比如tornado監聽的8001端口)給用戶,所以用nginx來轉發。此外,location /static/指令告訴nginx直接提供靜態目錄文件,而不再代理請求到tornado,nginx可以比tornado更高效地提供靜態文件。

安裝好nginx後,查看相關配置文件,發現這一句:include /etc/nginx/sites-enabled/*。可以在這個目錄下新建配置文件進行配置

cat /etc/nginx/nginx.conf
sudo touch /etc/nginx/sites-enabled/default2

配置示例如下,需要註意的是最下面的http://127.0.0.1:8001/ 這裏最後一個斜杠如果不打,實際上會加上上面的printprescription,用戶訪問”主機/printprescription"就相當於訪問"主機:8001/printprescription“了,由於自己在tornado上映射的是主機:8001/的請求,所以這個時候會出現404。

  upstream frontends {
      server 222.222.222.222:8000;
      server 222.222.222.222:8001;
  }
  
  server {
      listen 80;
  
      location / {
         proxy_read_timeout 1800;
         proxy_pass_header Server;
         proxy_set_header Host $http_host;
         proxy_redirect off;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Scheme $scheme;
         proxy_pass http://frontends;
     }
 
    location /doctorAfter/ {  #配置圖片路徑
         root /home/wenserver;
    }
 
    location /static/ {  #配置前端靜態資源路徑
         root /home/xxx/Code/printprescription/view;
    }
 
    location /printprescription/ {
         proxy_read_timeout 1800;
         proxy_pass_header Server;
         proxy_set_header Host $http_host;
         proxy_redirect off;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Scheme $scheme;
         proxy_pass http://127.0.0.1:8001/;
     }
 
 }

(6)opencv:一個計算機視覺庫,實現了圖像處理和計算機視覺方面的很多通用算法。由於之前采集數據的時候在處方圖片數據中混雜了人臉圖片,所以采用oepncv裏的算法檢測人臉,如果是人臉則刪除該記錄。然而還是會殘留一些人臉圖片,需要人工清洗,這個數據好像之前有師兄清洗過,到時候拿過來重構一下數據庫。

ps:安裝opencv的時候imshow報錯,雖然imshow用不到,但是強迫癥使然,搞了我一天,來來回回裝了十多次,最後還是沒搞定,真是心力交瘁,特想吐嘈:垃圾opencv!毀我青春!頹我精神!耗我時間!磨我意誌!浪費人生!!!

好吧我就隨便說說,回頭還要靠它幹活。

cv2.error: /io/opencv/modules/highgui/src/window.cpp:583: error: (-2) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvShowImage

ubuntu下python+tornado+supervisor+nginx部署