AWS Lambda执行RDS重启时出现Runtime.MarshalError错误如何解决
问题原因
- AWS Lambda运行时要求
lambda_handler的返回值必须是可直接JSON序列化的对象。你在重启RDS成功后直接返回了reboot_db_instance接口的原生响应,该响应中包含datetime类型的时间戳字段,Python标准JSON序列化工具不支持直接序列化datetime类型对象,因此触发了Runtime.MarshalError错误。 - 你的代码还存在语法逻辑错误:你定义的最终返回字典的缩进错误,位于
lambda_handler函数外部,永远不会被执行到,函数执行失败时只会返回空值。此外如果获取环境变量的逻辑报错,后续调用重启接口时会出现DBinstance未定义的错误。
修复方案
方案1(推荐):直接返回自定义可序列化响应
不需要返回RDS接口的原生响应,仅返回操作结果即可,修改后代码如下:
import sys import botocore import boto3 from botocore.exceptions import ClientError def lambda_handler(event, context): rds = boto3.client('rds') lambdaFunc = boto3.client('lambda') DBinstance = None print ('Trying to get Environment variable') try: funcResponse = lambdaFunc.get_function_configuration( FunctionName='RDSInstanceReboot' ) DBinstance = funcResponse['Environment']['Variables']['DBInstanceName'] print ('Rebooting RDS service for DBInstance : ' + DBinstance) except ClientError as e: print(e) return { 'message': "Failed to get environment variable", "error": str(e) } # 提前校验DB实例名是否正常获取,避免未定义报错 if not DBinstance: return { 'message': "DBInstanceName not found in environment variables" } try: rds.reboot_db_instance( DBInstanceIdentifier=DBinstance ) print ('Success :: ') return { 'message' : "RDS reboot triggered successfully. See Cloudwatch logs for complete output" } except ClientError as e: print(e) return { 'message': "Failed to reboot RDS instance", "error": str(e) }
方案2:需返回RDS原生响应时的处理
如果你确实需要返回RDS接口的全部响应内容,可先对响应中的datetime字段做序列化转换,示例如下:
首先引入依赖模块,自定义序列化规则:
import json import datetime def datetime_serializer(obj): if isinstance(obj, datetime.datetime): return obj.isoformat() raise TypeError ("Type %s not serializable" % type(obj))
成功调用重启接口后,对响应做转换后再返回:
response = rds.reboot_db_instance(DBInstanceIdentifier=DBinstance) serialized_response = json.loads(json.dumps(response, default=datetime_serializer)) return serialized_response
内容的提问来源于stack exchange,提问作者AWSFanatic
相关产品推荐
相关产品推荐

