栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python 自启动&监听进程 服务

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python 自启动&监听进程 服务

目标:
最近用python bottle写了一些api,但是阿里的服务器有时候会自动重启,导致api挂掉,所以有了写一个自启动服务的打算。

想法:
因为以前写的自启动和保护服务都是用C++写的服务,由于换了公司,电脑上也没有了vs,懒得装,查了下资料,发现python也能写成服务,就打算用python实现。

正题:

一:python实现服务
需要安装pywin32,因为我用的是python2.7,就下了pywin32-218.win-amd64-py2.7.exe,下载安装请百度。以下是服务整体的代码:

class PythonService(win32serviceutil.ServiceFramework):
    _svc_name_ = "PythonAutoRunServer"
    _svc_display_name_ = "PythonAutoRunServer"
    _svc_description_ = "用于Python服务的自启动和监测"
    _svc_description_ = _svc_description_.decode('utf8').encode('gbk')

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        self.logger = self._getLogger()
        self.run = True

    def _getLogger(self):
        logger = logging.getLogger('[PythonService]')

        this_file = inspect.getfile(inspect.currentframe())
        dirpath = os.path.abspath(os.path.dirname(this_file))
        handler = logging.FileHandler(os.path.join(dirpath, "service.log"))

        formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
        handler.setFormatter(formatter)

        logger.addHandler(handler)
        logger.setLevel(logging.INFO)

        return logger

    def SvcDoRun(self):
        import time
        # server_type: 1 后台管理系统; 2 东篱服务
        server_name = ["", "后台管理系统", "东篱"]
        server_type = 1
        self.logger.info("service is run....")
        start_server_time = 0   # 连续自启动三次时发邮件警报
        while self.run:
            try:
                if python_run_manage.start_check(server_type) == 1:
                    start_server_time += 1
                else:
                    start_server_time = 0
                if start_server_time == 3:
                    # 发送邮件警报
                    send_mail.send_auth_mail().send_mail_action("服务器警报", server_name[server_type],
                                                                "服务器服务重启次数异常")
                time.sleep(60)
            except Exception, e:
                self.logger.info(str(e))
                self.logger.info("sssss")
                time.sleep(60)
        self.logger.info("----------  svcdorun end  --------------")

    def SvcStop(self):
        self.logger.info("service is stop....")
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self.run = False


if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(PythonService)

这个服务是我百度找到的,其中send_mail是我的邮件通知模块,python_run_manage是具体监听进程是否正在运行的模块。

服务的安装等命令
1. 在环境中安装 pywin32-218.win-amd64-py2.7
2. 管理员启动的cmd中安装 python PythonAutoRunServer.py  --startup auto install 
3. 启动服务 python PythonAutoRunServer.py start

ps:
1. 关闭服务: python PythonAutoRunServer.py stop
2. 删除服务: python PythonAutoRunServer.py remove

二. 监听进程模块

先贴下完整的代码:
# 目标是 监测需要持续运行的Python程序,当没有运行时,自动启动
import httplib
import json

import subprocess
    #可用于检测程序是否正常,通过端口能否连接判断
    # def check_aliveness(ip, port, process_name):
    #     sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #     sk.settimeout(1)
    #     try:
    #         sk.connect((ip, port))
    #         print '%s %s %d service is OK!' % (process_name, ip, port)
    #         aliveness = True
    #     except Exception:
    #         print '%s %s %d service is NOT OK!' % (process_name, ip, port)
    #         # 自启动
    #         _start_py(_get_py_path(process_name))
    #         aliveness = False
    #     finally:
    #         sk.close()
    #     return aliveness

import time
import logger

def check_aliveness(ip_port, process_name):
    need_start = 0
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    conn = httplib.HTTPConnection(ip_port)
    try:
        conn.request("POST", "/test_connection", json.dumps({}), headers=headers)
        response = conn.getresponse()
        data = response.read()
    except Exception, e:
        pass
        aliveness = False
    try:
        json_data = json.loads(data)
        error_code = int(json_data["error"])
        if error_code == 200:
            aliveness = True
    except Exception, e:
        aliveness = False
        print e
    if not aliveness:
        # 自启动
        need_start = 1
        _write_log(process_name + " is not ok")
        _start_py(_get_py_path(process_name))
    else:
        _write_log(process_name + " is ok")

    return need_start


# 存储需要监控的py路径
def _get_py_path(process_name):
    if process_name == "back_manage":
        return r"D:/PythonServer/back_manager/route_for_back_manager.py"
    elif process_name == "dongli":
        return r"D:/web/python/route_dongli.py"
    elif process_name == "dongli_achievement":
        return r"D:/web/python/achievement_server.py"


# 启动py程序
def _start_py(path):
    try:
        cmd = "python %s" % path
        cwd = path[0:path.rindex("/")]
        subprocess.Popen(cmd,
                         creationflags=subprocess.CREATE_NEW_CONSOLE,
                         cwd=cwd)
    except Exception, e:
        print e


def _write_log(content):
    logger.Logger(logger="auto_server", message=content)


# 开始检测
def start_check(check_type):
    if check_type == 1:
        # 后台管理系统
        return check_aliveness('127.0.0.1:4002', "back_manage")
    elif check_type == 2:
        # 东篱
        need_start_one = check_aliveness('127.0.0.1:4000', "dongli")
        need_start_two = check_aliveness('127.0.0.1:4001', "dongli_achievement")
        if need_start_one == 0 and need_start_two == 0:
            return 0
        else:
            return 1

由服务循环调用start_check,来监测进程。本来是打算用socket来判断服务能否telnet来判断服务是否正常,后来尝试时发现,bottle写的api不能socket,一开始会显示正常,但是你不断开socket就会导致api阻塞,那个时候就会无法ping通…恩,然后就会重启n多的进程,惨惨惨,当然也是我没有把进程写成单例的原因。所以,我在进程中多加了一个test_connection 的api,用来判断进程是否正常。
在_get_py_path方法中保存了进程可执行程序的路径,恩,其实我觉得应该把这些写到cfg文件里会好些,嘛,以后再说~
_start_py方法是用cmd启动python api的方法,CREATE_NEW_CONSOLE这个属性是新开启界面,不过因为是服务启动的进程,所以不会有界面显示~

结束语:
这个服务还是非常简陋的,不过因为现在功能需求不多,还能勉强凑合,以后会加一些自己需要的功能,比如连续重启三次就发邮件给负责人等功能。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/834152.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号