部署專案Nginx+flask+Tornado+Supervisor
需要監控專案資料,但公司的系統比較大,資料比較多,平時只是需要關注部分資料即可,所以考慮自己寫個簡單的資料監控頁面,正好自己也有伺服器與域名,於是著手自己做一個簡單的資料頁面,本來想用Django來寫,後臺抽風下,又想嘗試做做不是太熟悉的flask與Tornado,於是把過程記錄一下。
過程中我選擇了一個比較繞的方式,把靜態html直接掛Nginx,用flask做介面呼叫,用Tornado做併發,再用Supervisor守護Tornado程序。
靜態結構
Nginx配置:
server { listen 80; server_name xxx.xxx.cn; # 你訪問的路徑前面的url名稱 access_log /var/log/nginx/access.log main; # Nginx日誌配置 charset utf-8; # Nginx編碼 gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream; # 支援壓縮的型別 error_page 404 /404.html; # 錯誤頁面 error_page 500 502 503 504 /50x.html; # 錯誤頁面 root /root/mdata; # 指定靜態檔案路徑 location /static { root /root/mdata; index index.html index.htm; expires 24h; access_log off; }
效果:
頁面完成後,開始做flask部分,之前Nginx又開了一個地址做介面地址
server { listen 80; server_name XXX.XXX.cn; access_log /var/log/nginx/access.log main; # Nginx日誌配置 charset utf-8; # Nginx編碼 gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream; # 支援壓縮的型別 error_page 404 /404.html; # 錯誤頁面 error_page 500 502 503 504 /50x.html; # 錯誤頁面 location /{ proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; # 把請求方向代理傳給tornado伺服器,負載均衡 proxy_pass http://127.0.0.1:8008; }
flask程式碼
# -*- coding=utf-8 -*- import flask from flask import make_response from flask_cors import * from flask import request from flask import jsonify from flask import Flask,current_app,render_template,make_response,jsonify,redirect import json import urllib import requests import psycopg2 import pymysql import datetime import requests from sshtunnel import SSHTunnelForwarder from urllib import request, parse import time,datetime import json from datetime import timedelta app = flask.Flask(__name__) CORS(app, supports_credentials=True) @app.route('/usrdata', methods=['POST']) def usrdata(): fdata = data() usrdata = fdata.getuser() return jsonify({'usrdata':usrdata}) @app.route('/usrval', methods=['POST']) def usrval(): fdata = data() td = fdata.usrval() return jsonify({'td':td})
這裡有幾個問題,因為我這邊介面用了另外一個地址,存在跨域訪問的問題,這個問題糾結了很久,最後發現flask自己就有解決方案,就是flask_cors 庫
引入後在程式碼中加入
CORS(app, supports_credentials=True)
即可解決。
另外,在程式碼中寫了業務的類訪問資料庫以及做資料處理,路由訪問的時候直接呼叫,這裡函式名比較隨意,畢竟自己用而已。在傳輸資料的時候,我用了jsonify來處理。
再來就是Tornado部分,因為業務flask都搞定了,Tornado只是分擔轉發而已,所以程式碼比較的簡單。
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from mdata_api import app
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(8008) #flask預設的埠,可任意修改
IOLoop.instance().start()
最後就是把檔案傳到伺服器啦,執行Tornado檔案即可。
當然,要讓Tornado在執行中能一直正常的運作下去,守護程序是不可缺少的。這裡就要請到Supervisor
首先配置Supervisor,我這裡做的很簡單,配置supervisord.conf放到指定位置,執行Supervisor指定配置檔案,之後執行即可。
配置如下:
# 為了方便管理,增加一個tornado組
[group:tornados]
programs=tornado-0
# 分別定義三個tornado的程序配置
[program:tornado-0]
# 程序要執行的命令
command=python3 /root/mdata_api_server.py --port=8008
directory=/root/
user=root
# 自動重啟
autorestart=true
redirect_stderr=true
# 日誌路徑
stdout_logfile=//root/tornado0.log
loglevel=info
最後在伺服器上執行sudo supervisorctl 再start all 即可 ,搞定
這一套下來都是入門級的操作,可以優化的地方太多了,做商用可不敢這樣來。
更新:
supervisord出問題,關閉重啟
$ sudo unlink /tmp/supervisor.sock
$ ps -ef | grep supervisord
$ sudo kill -9 5622
$ supervisord