python程序的热部署实现[通俗易懂]

python程序的热部署实现[通俗易懂]pytho程序的热部署知乎上面的回答真正意义上的代码热部署应该是类似erlang那样的,将代码更新到节点后不停服务,不断连接的自动应用新代码。autoreload(代表django的autoreload)什么的还是会造成业务瞬间中断。我感觉是可以从wsgi容器级别上实现,比如更新代码后检测到文件变更,然后通知容器创建新的wsgiapplication的实例,之后所有新的请求都发送到新的wdgi…

大家好,又见面了,我是你们的朋友全栈君。

pytho程序的热部署

知乎上面的回答

真正意义上的代码热部署应该是类似erlang那样的,将代码更新到节点后不停服务,不断连接的自动应用新代码。auto reload(代表django的autoreload)什么的还是会造成业务瞬间中断。我感觉是可以从wsgi容器级别上实现,比如更新代码后检测到文件变更,然后通知容器创建新的wsgi application的实例,之后所有新的请求都发送到新的wdgi application实例上。等旧wsgi application实例的最后一个请求返回后就将其回收掉。不过貌似没有看到类似的实现

爬虫程序的热部署的原理

主要使用了:reload ,importlib 两个模块

爬虫程序,尤其是多爬虫系统,比如自动同步系统(实时爬虫),需要经常修改爬虫规则(代码),如果使用重启的方式,对于实时爬虫来说,运维工作量大,而且还会造成服务中断。所以可以使用python的reload方法来实现热部署。


但是,由于对reloa的机制不是很了解,暂时还不清楚reload对程序的负面影响,尤其对于高并发程序的影响。

实现

实现很简单,程序使用多线程,热部署线程负责监听mq消息,收到消息,reload对应的模块。

代码

新建hotupdate包 修改__init__.py文件

# coding=utf-8
"""实现热更新功能"""
import importlib
import json
import sys
import threading
import logging

from hotupdate.hot_update import HotUpdateEventDriven, HotUpdateMessage

driven = HotUpdateEventDriven()


def _callback(ch, method, properties, body):
    """收到消息执行的回调函数"""
    try:
        msg = json.loads(body.decode('utf-8'))
        message = HotUpdateMessage(model_path=msg['model_path'], is_append_path=msg['is_append_path'], physical_path=msg['physical_path'])
        # 物理路径加入pythonPath
        if message.is_append_path:
            sys.path.append(message.physical_path)

        # 动态的引入该模块
        import_module = importlib.import_module(message.model_path)
        reload(import_module)
        # 打印热更新信息
        logging.warning('%s模块已经更新' % (message.model_path))
    except Exception, e:
        logging.warning('热部署失败,收到的消息%s,异常信息%s' % (body, e.message))
    # 消息确认
    driven.input_channel.basic_ack(delivery_tag=method.delivery_tag)


def _run():
    """线程的执行方法"""
    driven.receive(_callback)


def auto_reload_module():
    """reload a module. 新开一个线程来进行reload操作 动态更新python模块代码,依赖事件驱动,就是需要有人或者程序发送消息通知程序 """
    t = threading.Thread(target=_run, name='autoReloadThread')
    t.start()


新增hot_update.py文件

# encoding=utf-8
# ---------------------------------------
# 语言:Python2.7
# 功能:事件驱动,触发热部署动作
# ---------------------------------------
import uuid

import pika

from queues import queueBase
from settings import MQ


class HotUpdateEventDriven(object):
    """监听mq消息,收到消息,自动reload"""

    def __init__(self):
        credentials = pika.PlainCredentials(MQ['userName'], MQ['password'])
        parameters = pika.ConnectionParameters(MQ['host'], MQ['port'], '/', credentials=credentials)
        self.connection = pika.BlockingConnection(parameters)
        self.__init_input__()

    def __init_input__(self):
        ''' 初始化入口通道 '''
        self.input_channel = self.connection.channel()
        input_exchange = 'python.ppmoney.hotupdate'
        input_exchange_type = 'fanout'
        input_routing_key = '#'
        # 消息入口的队列
        self.input_queue = 'python.hotupdate.%s' % (uuid.uuid1())
        # 声明路由,如果存在就什么也不会做
        self.input_channel.exchange_declare(exchange=input_exchange, exchange_type=input_exchange_type, durable=True)
        # 声明队列
        self.input_channel.queue_declare(queue=self.input_queue, auto_delete=True)
        # 通过routing_key 将交换机与queue绑定起来
        self.input_channel.queue_bind(exchange=input_exchange, queue=self.input_queue, routing_key=input_routing_key)

    def receive(self, callback):
        ''' 入口通道:接受自动同步服务发送的任务消息 '''
        # 入口通道订阅消费者
        self.input_channel.basic_consume(consumer_callback=callback, queue=self.input_queue, consumer_tag='hotupdate_client')
        self.input_channel.start_consuming()


class HotUpdateMessage(object):
    """收到的mq消息"""

    def __init__(self, model_path, is_append_path, physical_path):
        # 模块名称
        self.model_path = model_path
        # 是否需要添加到pythonPath
        self.is_append_path = is_append_path
        # 如果需要添加到PythonPath中,需要提供模块的物理路径
        self.physical_path = physical_path

使用起来很简单,只需要增加一行代码即可

# 开启热更新
hotupdate.auto_reload_module()
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143670.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月11日 下午3:20
下一篇 2022年5月11日 下午3:40


相关推荐

  • 2026笔记本电脑详细选购指南,3月高性价比笔记本电脑推荐

    2026笔记本电脑详细选购指南,3月高性价比笔记本电脑推荐

    2026年3月12日
    2
  • 在电脑上安装部署OpenClaw详细教程指南

    在电脑上安装部署OpenClaw详细教程指南

    2026年3月13日
    3
  • c++中fstream是什么意思_汽车配置参数图文详解

    c++中fstream是什么意思_汽车配置参数图文详解在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,一,c++文件流的结构:‍1,几个文件流类名称:fstream,ifstream,ofstream,iofstream2,之间的关系:ifstream(inputfilestream)和ofstream(outpufilestream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打…

    2026年1月25日
    4
  • WPF中的布局方式

    WPF中的布局方式前言:WPF(WindowsPresentationFoundation)是微软推出的基于Windows的用户界面框架,属于.NETFramework3.0的一部分。它提供了统一的编程模型、语言和框架,真正做到了分离界面设计人员与开发人员的工作;同时它提供了全新的多媒体交互用户图形界面布局方式:1.Canvas2.Grid3.WarpPanel4.StackPanel5.ScrollViewer……

    2022年7月15日
    17
  • LM优化算法_lm算法内参计算

    LM优化算法_lm算法内参计算LM算法理论知识梯度下降高斯牛顿Levenberg–Marquardt算法框架算法的整体流程求解器update流程说明算法实现头文件cpp算法调用LM优化算法,是一种非线性优化算法,其可以看作是梯度下降和高斯牛顿法的结合。综合了梯度下降对初值不敏感和高斯牛顿在最优值附近收敛速度快的特点。本人非数学专业,且对算法理解可能不到位,详细的算法推导及各个优化算法之间的关系,非常推荐看**《METHODSFORNON-LINEARLEASTSQUARESPROBLEMS》**,其介绍更详细也更专业。

    2026年4月19日
    4
  • 机器学习:随机梯度下降法

    机器学习:随机梯度下降法1.梯度下降  1)什么是梯度下降?      因为梯度下降是一种思想,没有严格的定义,所以用一个比喻来解释什么是梯度下降。         简单来说,梯度下降就是从山顶找一条最短的路走到山脚最低的地方。但是因为选择方向的原因,我们找到的的最低点可能不是真正的最低点。如图所示,黑线标注的路线所指的方向并不是真正的地方。    既然是选择一个方向下山,那么这个方向怎么选…

    2025年10月24日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号