• 【windows&flask】flask通过service自动运行


    最近在学习在windows平台用flask框架提供Restful API服务,需要使得flask的windows应用能够开机自动运行,并且后台运行,所以通过service来实现。

    首先尝试的是在自己派生的serivice类的中直接调用  create_app(debug=True).run(host='0.0.0.0', port=5000) 的方式启动flask。

    参考代码:

    import win32serviceutil
    import win32service
    import win32event
    import win32evtlogutil
    import servicemanager
    import socket
    import time
    
    import os
    import sys
    from flask import logging, app, Flask
    from run import create_app
    
    sys.path.append(os.path.dirname(__name__))
    
    
    def main():
        # app.run(host="0.0.0.0", port=5000)  # 服务运行函数
        # launch()
        create_app(debug=True).run(host='0.0.0.0', port=5000)
    
    
    class MySvc(win32serviceutil.ServiceFramework):
        _svc_name_ = "my web service"  # 服务名
        _svc_display_name_ = "my web service"  # 描述
    
        def __init__(self, *args):
            win32serviceutil.ServiceFramework.__init__(self, *args)
            self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
            socket.setdefaulttimeout(5)
            self.stop_requested = False
    
        def SvcStop(self):
            self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
            win32event.SetEvent(self.hWaitStop)
            self.ReportServiceStatus(win32service.SERVICE_STOPPED)
            # logging.info('Stopped service ...')
            self.stop_requested = True
    
        def SvcDoRun(self):
            servicemanager.LogMsg(
                servicemanager.EVENTLOG_INFORMATION_TYPE,
                servicemanager.PYS_SERVICE_STARTED,
                (self._svc_name_, '')
            )
    
            main()
    
    
    if __name__ == '__main__':
        win32serviceutil.HandleCommandLine(MySvc)

    但是启动service的时候一直报错如下,参考了很多种方法一直解决不了

    接下来尝试用subprocess的方法拉起进程,成功!

    class MyService(PySvc):
        def start(self):
            self.child = subprocess.Popen("python run.py", cwd="C:\mytest")
            logging.warning('child pid is %s',self.child.pid)
            
        # TODO: add run service code
        def stop(self):
            self.child.kill()
         

    但是在stop的发现有一个python进程不能被kill。原因应该是flask本身会启动一个python子进程,相当于subprocess起了一个子进程执行 python run.py,在run.py启动flask的时候又启动了一个子进程,而child.kill只能杀死由subprocess启动的子进程,改成用taskkill就好了。

    class MyService(PySvc):
        def start(self):
            self.child = subprocess.Popen("python run.py", cwd="C:\mytest")
            logging.warning('child pid is %s',self.child.pid)
    
    
        # TODO: add run service code
        def stop(self):
            #self.child.kill()
            os.system("taskkill /t /f /pid %s" % self.child.pid)

    完整代码如下:

    import os
    import signal
    import subprocess
    from time import sleep
    
    import win32service
    import win32serviceutil
    import win32event
    import logging
    
    logging.basicConfig(filename='C:\app.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
    logging.warning('This will get logged to a file')
    
    
    class PySvc(win32serviceutil.ServiceFramework):
        _svc_name_ = "ServicePython"  # NET START/STOP the service by the following name
        _svc_display_name_ = "ServicePython Service"  # name in the Service  Control Manager (SCM)
        _svc_description_ = "This service writes stuff to a file"  # description in the SCM
    
        def __init__(self, args):
            win32serviceutil.ServiceFramework.__init__(self, args)
            # create an event to listen for stop requests on , 所以也是可以和client进行通信的
            self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
    
        def SvcDoRun(self):  # 启动时调用
            import servicemanager
            self.start()
            win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
    
        def SvcStop(self):  # 关闭时调用
            self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)  # tell the SCM
            win32event.SetEvent(self.hWaitStop)  # fire the stop event
            self.stop()
    
    
    
    class MyService(PySvc):
        def start(self):
            self.child = subprocess.Popen("python run.py", cwd="C:\mytest")
            logging.warning('child pid is %s',self.child.pid)
            
    
    
        # TODO: add run service code
        def stop(self):
            os.system("taskkill /t /f /pid %s" % self.child.pid)
    
    
    # TODO:shut down the running flask web service
    
    if __name__ == '__main__':
        win32serviceutil.HandleCommandLine(MyService)
  • 相关阅读:
    mobilebone.js使用笔记
    js笔记:匿名函数
    java中==和equals和hashcode的区别详解
    JVM基础学习之基本概念、可见性与同步
    面向对象-抽象类和接口解析
    maven使用deploy发布到本地仓库
    Jackson 时间格式化,时间注解 @JsonFormat 与 @DatetimeFormat 用法、时差问题说明
    cxf动态调用webservice设置超时,测试线程安全
    再谈API GateWay服务网关
    微服务实战-使用API Gateway
  • 原文地址:https://www.cnblogs.com/seyjs/p/11511630.html
Copyright © 2020-2023  润新知