美文网首页Python
python flask+uwsgi 服务部署+监控机制

python flask+uwsgi 服务部署+监控机制

作者: blackmanba_084b | 来源:发表于2019-08-08 11:41 被阅读52次

    我们知道利用flask模块进行服务部署时间很简单的事情,但是flask模块本身是用于开发适用,而不是用于生产环境中。例如在下面这张图片就可以看出在启动flask会有相应警告。


    flask server.png

    因为在工作中用到了这方面内容,因此在这里做一个总结,记录一下服务简单部署的方法。在这里我们分为三个部分:

    • flask 部署
    • uwsgi部署
    • 监控部署

    通过启动uwsgi来启动flask 服务.


    文件路径

    ├── src
    │   ├── server.py
    │   ├── check_server.py                                 
    │   │  │  ├──ini
    │   │  │  │  ├── uwsgi.ini
    

    1. flask 部署

    文件1: server.py

    import flask
    
    FLASK_HOST = params_config.get('flask', 'host') 
    api_name = params_config.get('flask', 'api_name')
    FLASK_PORT = params_config.getint('flask', 'port')
    app = flask.Flask(__name__)
    
    @app.route('/quit', methods=['POST', 'GET'])
    def kill():
        # do something
        return ''
    
    @app.route('/restart', methods=['POST', 'GET'])
    def restart():
        # do something
        return ''
    
    
    
    @app.route('/{}'.format(api_name), methods=['POST', 'GET'])
    def color_cluster():
        """
        This function is a main entrance of this server
        """
        try:
            # do some thing
            return result
        except Exception as e:
            return ''
    
    if __name__ == '__main__':
        app.run(host=FLASK_HOST, port=FLASK_PORT)
    

    2. uwsgi配置

    文件2:uwsgi.ini
    这里需要说明的是这里的配置是针对flask, 有些针对django配置会有些不一样。这里给出uwsgi中文文档详细参数可以参考这里的官方文档uwsgi中文官方文档

    [uwsgi]
    daemonize = myapp_uwsgi.log
    http=:7010
    chdir=/data/project/color_extraction/code/src
    pythonpath=/data/models-master/research:/data/models-master/research/slim
    pythonpath=/data/models-master/research/object_detection/utils
    wsgi-file=/data/project/color_extraction/code/src/color_extraction_server.py
    callable = app
    processes=50
    threads=1
    master=True
    safe-pidfile=%(chdir)/ini/uwsgi.pid
    
    

    参数介绍如下:

    1. daemonize:加上这个参数就可以将uwsgi放入后台运行,并将日志打印到此日志文件中去
    2. http:这里写明端口号
    3. chdir: 这里写上程序根目录(即server.py文件所在目录)对应上述目录结构为src
    4. pythonpath:python环境变量
    5. wsgi-file: 启动服务地址,在这里是server.py
    6. callable: 对于flask一定要写上,否则会报callable not found or import error错误
    7. process: 这里写上process 进程数目
    8. thread: 这里写上thread线程数。警告:这里写上进程数目的时候,线程最好写 1 因为我在测试的时候,发现线程数目不为 1 时候,服务吞吐量会下降
    9. master: 允许主线程存在。此时的master写为True 否则会自动启动一个僵尸进程
    10. safe-pidfile : 这里会打印主线程pid到此文件中去(可以利用此pid做监控,所以建议保留此参数)

    3. 监控程序

    这里会做一个心跳监控,并实时将服务状态发送到钉钉报警群中。

    
    import os
    import socket
    import time
    import psutil
    import subprocess
    import dingtalk_chatbot
    from config_load import params_config
    
    
    web_hook = params_config.get('check_server', 'web_hook') # dingding 报警群web_hook id
    sleep_time = params_config.getint('check_server', 'sleep_time') # 每多长时间检测一次服务状态
    server_name = params_config.get("check_server", "server_name") # 服务名称
    start_uwsgi_cmd = params_config.get("check_server", "start_uwsgi_cmd") # 启动uwsgi. 这里是uwsgi uwsgi.ini
    
    
    def get_check_program_pid(process_name):
        process = subprocess.Popen(['pgrep', '-f', process_name],
                                   stdout=subprocess.PIPE, shell=False)
        pid = process.communicate()[0]
        return pid
    
    
    def get_host_ip():
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(('8.8.8.8', 80))
            ip = s.getsockname()[0]
        finally:
            s.close()
        return ip
    
    machine_ip = get_host_ip()
    
    def get_pid(pid_text_path):
        with open(pid_text_path) as pid_text:
            pid_num = int(pid_text.readlines()[-1])
        return pid_num
    
    
    def check_pid(pid_num):
        if psutil.pid_exists(pid_num):
            return True
        else:
            return False
    
    
    def restart_server():
        os.system(start_uwsgi_cmd)
        pid_text_path = params_config.get("check_server", "pid_text_path")
        time.sleep(3)
        pid_num = get_pid(pid_text_path)
        if check_pid(pid_num):
            chat_bot.send_text('{}机器 - {}服务已重新启动@所有人'.format(machine_ip, server_name))
        else:
            chat_bot.send_text('{}机器 - {}服务启动失败@所有人'.format(machine_ip, server_name))
    
    
    if __name__ == '__main__':
        chat_bot = dingtalk_chatbot.DingtalkChatbot(web_hook)
        machine_ip = get_host_ip()
        msg = "{} 机器 - {}已部署启动".format(machine_ip, server_name)
        time.sleep(3)
        chat_bot.send_text(msg)
        while True:
            pid_text_path = params_config.get("check_server", "pid_text_path")
            pid_num = get_pid(pid_text_path)
            result = check_pid(pid_num)
            if result:
                msg = '{}机器 - {}服务正常运行,请放心!'.format(machine_ip, server_name)
                chat_bot.send_text(msg)
            else:
                msg = '{}机器 - {}服务挂了! 正在重启...@所有人'.format(machine_ip, server_name)
                chat_bot.send_text(msg)
                restart_server()
            time.sleep(sleep_time)
    
    

    服务启动

    • 服务启动:
      我们只要去ini文件夹下执行uwsgi uwsgi.ini即能启动服务。

    • 监控服务启动:
      执行nohup python3 check_server.py 启动监控服务。

    参考

    1. uwsgi参数参考

    相关文章

      网友评论

        本文标题:python flask+uwsgi 服务部署+监控机制

        本文链接:https://www.haomeiwen.com/subject/rhmtjctx.html