在AWS Greengrass运行Lambda无法向S3上传对象问题求助
解决AWS Greengrass Lambda写入S3时的'module' object has no attribute 'wait_for_read'异常
这问题我之前帮朋友排查过类似的,核心原因是Greengrass运行环境里的依赖库版本和Lambda控制台环境不兼容,尤其是树莓派这类ARM架构的设备,依赖库的适配很容易出问题。你遇到的'module' object has no attribute 'wait_for_read'错误,本质是urllib3库的版本不匹配——Greengrass自带的旧版urllib3没有这个方法,而你的代码依赖的boto3版本又需要这个方法,导致调用时出错。
下面是一步步的解决方案:
1. 锁定兼容的依赖版本
Greengrass Core(尤其是2019年的旧版本)对boto3和urllib3的版本有严格要求,建议直接指定经过验证的兼容版本:
- boto3 == 1.9.201
- urllib3 == 1.24.3
不要依赖Greengrass自带的库,把这些依赖打包到你的Lambda部署包中,确保运行环境使用的是你指定的版本。
2. 正确构建ARM架构的部署包
因为树莓派是ARM架构,不能在x86电脑上直接安装依赖(否则会出现架构不兼容的问题),推荐两种方式构建:
方式一:树莓派本地构建
在树莓派上执行以下命令:
# 创建临时目录 mkdir lambda-package && cd lambda-package # 安装依赖到当前目录 pip install boto3==1.9.201 urllib3==1.24.3 -t . # 把你的Lambda代码文件(比如lambda_function.py)复制到这个目录 cp /path/to/your/lambda_function.py . # 打包成zip包 zip -r lambda-deploy.zip .
方式二:Docker模拟ARM环境构建
如果没有树莓派在手,可以用Docker模拟ARM架构:
# 启动ARM架构的Python容器 docker run --rm -v "$PWD":/app -w /app arm32v7/python:3.7-slim pip install boto3==1.9.201 urllib3==1.24.3 -t . # 复制代码文件并打包 cp /path/to/your/lambda_function.py . zip -r lambda-deploy.zip .
打包完成后,把这个zip包上传到Lambda控制台,再重新部署到Greengrass。
3. 调整代码中的boto3初始化逻辑
不要直接使用默认的boto3.resource('s3'),而是指定Greengrass兼容的配置,确保凭证和端点正确:
import greengrasssdk import boto3 import logging from botocore.config import Config from botocore.exceptions import ClientError # 配置日志 logging.basicConfig(level=logging.INFO) # 指定Greengrass兼容的配置 s3_config = Config( signature_version='s3v4', region_name='你的AWS区域(比如eu-west-1)' ) # 初始化S3资源 s3 = boto3.resource('s3', config=s3_config) def handler(event, context): try: some_binary_data = b'Here we have some more data from BB' s3_object = s3.Object('你的S3桶名','Testing') s3_object.put(Body=some_binary_data) logging.info("数据成功写入S3") except ClientError as e: logging.error(f"写入S3失败: {e}") raise e
4. 验证Greengrass配置和权限
虽然你说已经确认权限,但还是再检查两点:
- 确保Greengrass服务角色(Greengrass Service Role)拥有
s3:PutObject权限,并且已经关联到你的Greengrass组。 - 检查Greengrass Core的网络连接,确保它能正常访问S3端点(可以在树莓派上执行
curl https://你的桶名.s3.你的区域.amazonaws.com测试连通性)。
额外排查技巧
可以在代码中加入日志,打印依赖库版本,对比控制台和Greengrass环境的差异:
import boto3 import urllib3 logging.info(f"当前boto3版本: {boto3.__version__}") logging.info(f"当前urllib3版本: {urllib3.__version__}")
通过日志可以明确看到两个环境的版本是否一致,帮助定位问题。
内容的提问来源于stack exchange,提问作者Bipradip
相关产品推荐
相关产品推荐

