由於項目需要,老師讓我寫一個小web系統,之前都是用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/,英文的官方文檔為http://www.tornadoweb.org/en/stable/
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開發的進程管理程序,可以將普通的命令變成后台的守護進程,並監控進程狀態。
因為只是簡單用一下,所以安裝的挺順利,如果遇到一些棘手問題,建議看看原始文檔http://supervisord.org/index.html
1) supervisor-服務啟動版
51服務器上,用apt-get install安裝后,主配置文件在/etc/supervisor/supervisord.conf下
在/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 cat /var/log/supervisor/xxx.log
2)supervisor-指令啟動版
228和105服務器上supervisor沒有配成服務,應該是用easy_install安裝的supervisor(官方推薦的安裝方式),要自己導入配置文件,通過echo_supervisord_conf >> /etc/supervisor/supervisord.conf建立一個配置文件的樣例,然后做相應修改。
無法通過服務來啟動關閉,那么需要使用如下指令來開啟和關閉,可以用supervisord -h和supervisorctl進入交互式界面后輸入help來查看對應的幫助。
supervisord和supervisorctl其實就是python文件,一般裝好后都放在python環境的bin目錄下,而python的bin一般都被設在環境變量中,所以可以直接在命令行中輸入supervisord來執行。可以通過which supervisord找到所在的目錄。
啟動和關閉supervisor supervisord supervisorctl shutdown
查看,啟動和關閉進程 supervisorctl status/start/stop/restart 設置的守護進程名
supervisorctl 進入交互模式,可以查看運行的進程狀態
3)瀏覽器控制
另外,在配置文件中添加[inet_http_server]選項組,可以在瀏覽器中控制supervisor
[inet_http_server]
port=127.0.0.1:9001
username=liaohuqiang
password=123456

4) 啟動報錯“unix:///tmp/supervisor.sock no such file”
原因:默認配置中,啟動的sock等會放到tmp目錄,而tmp目錄會自動清理導致無法使用supervisorctl命令,比如重啟機子之后。
解決方法:修改配置文件supervisord.conf,所有的/tmp改成/var/run。創建sock然后授權(touch /var/run/supervisor.sock,chmod 777)。最后重啟(supervisorctl shutdown然后supervisord)。
(5)nginx:nginx用於反向代理,可以監控80端口,把相應的請求轉發到別的主機以及別的端口上,這里我們顯示的圖片的路徑不在tornado的static中(static用來存放js和css等前端靜態資源),而是在服務器另外的位置,所以可以通過nginx的轉發來獲取圖片。另一方面,一般不會暴露其它端口(比如tornado監聽的8001端口)給用戶,所以用nginx來轉發。此外,location /static/指令告訴nginx直接提供靜態目錄文件,而不再代理請求到tornado,nginx可以比tornado更高效地提供靜態文件。
1)nginx-服務啟動版
安裝好nginx后,查看相關配置文件,51服務器放在/etc/nginx/nginx.conf中,在里面發現這一句: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。
配置完成后sudo service nginx restart重新加載配置
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/; } }
2)nginx-指令啟動版
105服務器上的nginx放在/usr/local/nginx/下
主配置文件放在/usr/local/nginx/conf/nginx.conf下,查看里面的include來確定子配置文件位置
子配置文件的配置同上,不過啟動服務的時候要cd到/usr/local/nginx/sbin下來啟動nginx
./nginx 啟動(默認以nginx目錄下conf/nginx.conf配置文件啟動)
./nginx -s reload 重載配置文件
./nginx -s stop 立刻停止
./nginx -s quit 完整有序地停止
./nginx -s reopen 重開nginx
./nginx -h 查看指令幫助
./nginx -c 配置文件位置 根據指定位置的配置文件,進行啟動
./nginx -t 檢查配置文件是否有問題
(6)日志文件
日志文件一般放在/var/log下。
1)像supervisor的主日志放在/var/log/supervisor/supervisord.log
2)配置的tornado日志放在/var/log/tornado/tornado.log
(51服務器上設在了別的位置,當時只是寫個小程序,沒考慮規范和統一,具體位置看supervisor的配置文件就知道了)
(228服務器,師兄放在了/var/log/tornado.log,因為tornado.log會在本目錄產生很多備份日志,這么放會導致/var/log下太多亂七八糟的日志,估計是當初都沒考慮太多隨意放了)
3)配置的ngnix日志放在了/var/log/nginx/access.log和/var/log/nginx/error.log
(7)opencv:一個計算機視覺庫,實現了圖像處理和計算機視覺方面的很多通用算法。由於之前采集數據的時候在處方圖片數據中混雜了人臉圖片,所以采用oepncv里的算法檢測人臉,如果是人臉則刪除該記錄。然而還是會殘留一些人臉圖片,需要人工清洗,這個數據之前有師兄清洗過,到時候拿過來重構一下數據庫。
