Python 自启动&监听进程 服务
来源:互联网 发布:淘宝网店图标尺寸 编辑:程序博客网 时间:2024/06/01 23:29
目标:
最近用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 = Falseif __name__ == '__main__': win32serviceutil.HandleCommandLine(PythonService)
这个服务是我百度找到的,其中send_mail是我的邮件通知模块,python_run_manage是具体监听进程是否正在运行的模块。
服务的安装等命令
1. 在环境中安装 pywin32-218.win-amd64-py2.72. 管理员启动的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 alivenessimport timeimport loggerdef 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 edef _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这个属性是新开启界面,不过因为是服务启动的进程,所以不会有界面显示~
结束语:
这个服务还是非常简陋的,不过因为现在功能需求不多,还能勉强凑合,以后会加一些自己需要的功能,比如连续重启三次就发邮件给负责人等功能。
阅读全文
0 0
- Python 自启动&监听进程 服务
- 【笔记】配置Python脚本自启动服务
- 监听启动的进程
- aix系统中服务进程监控并自启动脚本
- SERVICE后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- SERVICE后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- android service后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- -------------------Android SERVICE后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- Service后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- Android SERVICE后台服务进程的自启动和保持
- 记录Android Studio提交代码忽略配置
- DNS解析过程详解
- Windows下 64 的memcached的安装
- Option
- 324. Wiggle Sort II
- Python 自启动&监听进程 服务
- PBS作业提交后,输出错误MPI_Aobrt
- java使用condition进行线程通信
- iptables
- JAVA开发之 30-java的数组的12个最佳方法
- 数据中心 FailOver 后避免数据错乱的关键做法
- 自定义 SimpleVG
- 二叉查找树
- 【JS】:关于select的multiple的JS复选使用