由於supervisor不支持windows,但要防止程序異常中斷,所以需要采取措施
通過pywin32,使得flask以服務的方式運行
創建pythonservice.py
import win32serviceutil
import win32service
import win32eventfrom flask import Flask
class win32test(win32serviceutil.ServiceFramework):
_svc_name_ = "Flask Service"
_svc_display_name_ = "Flask Service"
_svc_description_ = "Flask App Service"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
self.main()
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def main(self):app = Flask(__name__)
app.run(host="0.0.0.0",port=5000)
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(win32test)
安裝服務:python flaskservice.py install
啟動服務:python flaskservice.py start
停止服務:python flaskservice.py stop
刪除服務:python flaskservice.py remove
出現的問題即解決過程:
flask不能以debug模式啟動,必須關掉debug
問題:服務沒有及時響應啟動或控制請求
查了下,通過python flaskservice debug的方式,但錯誤信息是注冊表問題,操作了半天的注冊表,問題依然存在
之后查到NSSM也可以通過服務的方式運行,但報錯信息還是一致,所以原因應該是一樣的
通過查看windows日志解決問題:
(參考:https://blog.csdn.net/ywg_1994/article/details/82430943)
之后看了下報錯信息,提示可以查看windows日志,這下打開了新世界的大門
控制面板-系統和安全-管理工具-查看事件日志,等加載完畢,左側選擇windows日志-應用程序,這時觀察右邊,里面果然有Flask Service,點擊查看錯誤信息
from jinja2 import escape 未找到模塊jinja2
但明明是安裝了的
pip show jinja2
顯示位置為 c:\users\username\appdata\roaming\python\python36\site-packages
但python解釋器明明是在c:\program files\python\python36\lib\site-packages
卸載重裝模塊,結果還是在用戶目錄下
有了日志就不怕了,出了問題都可以知道原因,解決即可
通過whl手動指定安裝位置:
(但pip install --target=c:\program files\python\….. jinja2,顯示files\…目錄未找到,wtf)
最后通過下載whl文件,將文件放到目標目錄,pip install xx.whl完成指定目錄的模塊安裝
之后啟動服務提示未找到markupsafe,同樣下載whl進行安裝
問題:提示服務開啟后又被關閉
日志中:The instance's SvcRun() method failed <Error getting traceback - traceback.print_exception() failed %2: %3
在pythonservice.py的最前面添加下面語句:
sys.stdout = sys.stderr = open(os.devnull, 'w')
然后重啟服務,果然可以了;(原因不是很清楚,問題應該是無法輸出錯誤信息,解決方案思路應該是給標准輸出指定一個設備空文件)
之后在flask服務中設置:程序異常后-重新啟動即可
也可以配合pyinstaller使用,更方便
在虛擬環境中也是可以的,操作與之前一樣
python的服務主要是依賴於PythonService.exe和所寫的服務文件(pythonservice.py)
保證這兩個路徑即可:
PythonService.exe的路徑在服務中就可以查看
服務運行文件可以在服務的注冊表中查看:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
如果安裝上面直接不可以啟動的話,參考:https://stackoverflow.com/questions/34696815/using-pythonservice-exe-to-host-python-service-while-using-virtualenv
其他:
python xxservice.py debug就是坑,最后已經可以啟動服務了,執行還是報注冊表未找到錯誤,wtf
中間還嘗試了windows-supervisor,結果根本就不行
stackflow很完善,對於這些‘小眾’的bug,都有相應的討論及解決方案,很nice
流程:
python(環境變量配置,安裝virtualenvwrapper,workon環境變量配置)
虛擬環境(安裝模塊的離線包)
安裝服務,啟動