python 关于热更新与热加载

聊聊热加载、热更新

知识有限,只谈谈自己对这块的了解,说的不对的地方还希望指出哈。
前段时间有个哥们说java微服务 有个配置中心spring cloud config 可以做到 配置文件热更新、热加载。基于此,提供一套Python 方案,当然对于spring来说,这个方案确实有点过于简陋(精简),尤其是如果用于微服务的时候。python 的微服务还不够完善,后续关注下nameko +py某web框架 有没有类似的方案,大家如果有时间也可以顺着spring 的方案弄一个呗,如果不觉得繁琐的话。当然如果项目不大的话,其实是可以直接重启呗,也就不到两秒钟的事情。看看各位的项目需要。

1、修改代码使用reload

其实就是在代码中import 相关模块,并用reload 方法重新加载相关参数,这种方法会实际上修改代码,在不需要重启服务的情况下,重新加载相关模块。在网上找了个简单的例子:https://blog.youkuaiyun.com/u013421629/article/details/89211695
只要提交代码到服务器上就可以了,简单粗暴,不需要重启。但是如果代码中有大量的地方需要reload。确实有点头大。

2、修改内存中的配置文件

因为项目的配置文件中的变量属于全局变量。这时候可以修改这个全局变量。这就更加简单了。提供一个接口(此处安全问题暂时忽略),传递配置文件相关参数。在接口中修改相关全局变量。

3 、autoreload

框架中的自动加载模块。试了几下,没成功,略过了,应该是可以的。

4、参照spring cloud config的方案。手动实现

原理介绍
springCloudConfig分服务端和客户端,服务端负责将本地,git或者svn中存储的配置文件发布成REST风格的接口,客户端可以从服务端REST接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置,这需要每个客户端通过POST方法触发各自的/refresh接口。而我们上面说的SpringCloudBus就发挥了其作用了

SpringCloudBus通过一个轻量级消息代理连接分布式系统的节点(有点像消息队列那种)。这可以用于广播状态更改(如配置更改)或其他管理指令。SpringCloudBus提供了通过post方法访问的endpoint/bus/refresh(spring boot 有很多监控的endpoint,比如/health),这个接口通常由git的钩子功能(监听触发)调用,用以通知各个SpringCloudConfig的客户端去服务端更新配置。
在这里插入图片描述

git服务器会从远程git拉取配置文件,并存入到本地git文件库,当远程git不可用时,会从本地git文件库拉取配置信息

下面是一张spring cloud config结合bus的一张工作流图(来自于某大神)
在这里插入图片描述

### 实现Python热加载的方式 #### 使用`importlib.reload` 对于简单的模块重载,可以利用标准库中的 `importlib` 模块所提供的 `reload()` 函数。当源代码发生改变时,可以通过重新导入该模块来达到热加载的效果[^1]。 ```python import importlib import my_module # 假设这是要被热加载的目标模块 def reload_my_module(): importlib.reload(my_module) ``` 这种方法适用于那些不涉及复杂依赖关系的小型脚本或工具类模块的即时更新场景。 #### 利用第三方库`watchdog`监控文件变化并触发重载逻辑 为了更高效地管理大型项目中的多个文件变更事件,并自动执行相应的处理操作(比如重启服务、刷新缓存等),可以选择安装额外的支持包如 watchdog 来监视特定路径下的文件变动情况,在检测到任何改动之后立即通知应用程序采取行动[^2]。 ```bash pip install watchdog ``` 下面是一个简单例子展示如何结合 `watchdog` 和 `importlib` 来构建一个基本的热加载机制: ```python from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler import os import time import importlib.util class ReloadHandler(FileSystemEventHandler): def __init__(self, module_path): self.module_name = os.path.splitext(os.path.basename(module_path))[0] spec = importlib.util.spec_from_file_location( self.module_name, module_path ) self.module = importlib.util.module_from_spec(spec) spec.loader.exec_module(self.module) def on_modified(self, event): if not event.is_directory and event.src_path.endswith('.py'): print(f"{event.src_path} has been modified.") try: importlib.reload(self.module) print(f"Successfully reloaded {self.module_name}.") except Exception as e: print(e) if __name__ == "__main__": path_to_watch = './' # 设置想要监听的目录 handler = ReloadHandler('./example.py') # 替换成实际需要热加载的模块路径 observer = Observer() observer.schedule(handler, path=path_to_watch, recursive=False) observer.start() try: while True: time.sleep(1) finally: observer.stop() observer.join() ``` 这段代码会持续观察指定位置是否有 Python 文件发生变化;一旦发现有新的更改,则尝试对该文件对应的模块进行重新加载。 #### Pytest框架内的热加载实践 在某些情况下,特别是针对测试驱动开发(TDD),像 pytest 这样的单元测试框架本身就支持一定程度上的热加载特性。例如,pytest 支持插件化扩展以及灵活配置选项,允许开发者自定义行为,包括但不限于根据环境变量调整测试集、动态注册 fixture 或者是在每次运行前清理资源等等[^4]。 此外,还有专门面向 Web 开发者的解决方案,例如 Flask 的内置服务器就提供了实时预览功能,它可以在保存 HTML/CSS/JS 文件后立刻反映最新的页面效果而不需要手动刷新浏览器窗口[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值