AWS Lambda跨调用模块持久化:单元测试结果异常排查
问题原因解析
这是AWS Lambda的**执行环境复用(Warm Start)**机制导致的Python模块缓存问题,具体拆解如下:
1. Lambda执行环境的复用特性
AWS Lambda为了提升性能,会在函数调用结束后保留执行环境一段时间。后续的函数调用会直接复用这个已初始化的环境——包括已经加载到sys.modules中的Python模块、内存中的变量对象等。
2. 模块加载的缓存逻辑
当你执行from util import foo时:
- Python首先会检查
sys.modules字典中是否存在util模块。如果存在,直接复用内存中已加载的旧模块对象,不会重新读取/tmp下的新文件。 - 即使你后续把新的
util.py写入/tmp,只要sys.modules['util']还存在,导入操作就不会触发模块的重新加载。
3. inspect.getsource的特殊行为
你看到inspect.getsource(foo)能打印最新源码,是因为这个函数是直接从文件系统读取对应模块的源码文件,而不是从内存中的函数对象获取。所以它会读取/tmp/util.py的最新内容,但内存中执行的还是第一次加载的旧foo函数对象。
4. 本地测试无问题的原因
本地测试时,每次运行Lambda处理器都是启动全新的Python进程,sys.modules字典每次都是空的。因此每次都会重新从文件加载模块,自然不会出现缓存旧代码的情况。
为什么删除sys.modules['util']能解决问题
删除sys.modules['util']后,Python会认为该模块从未被加载过,再次执行from util import foo时,会重新读取/tmp下的最新文件,生成新的模块和函数对象,单元测试也就会执行新代码了。
内容的提问来源于stack exchange,提问作者AlwaysLearning
相关产品推荐
相关产品推荐

