Moj*_*imi 5 amazon-web-services aws-lambda python-3.7
我知道以前有人对此提出过质疑,但没有提出真正的解决方案,我想知道现在是否有任何新方法。
无论如何,是否可以使用任何 AWS 服务挂钩事件来检查 lambda 是否已超时?我的意思是它登录到它超时的 CloudWatch 日志中,所以必须有办法。
特别是在 Python 中,因为它并不像使用 Javascript 和其他自然并发语言那样持续检查它是否达到 20 分钟标记那么简单。
理想情况下,如果 python lambda 超时,我想执行一个 lambda,并使用与原始接收相同的负载。
小智 15
我想更新 @John Rotenstein 的答案,该答案对我有用,但导致填充 cloudwatch 日志时出现以下错误:
START RequestId: ********* Version: $LATEST
Traceback (most recent call last):
File "/var/runtime/bootstrap", line 9, in <module>
main()
File "/var/runtime/bootstrap.py", line 350, in main
event_request = lambda_runtime_client.wait_next_invocation()
File "/var/runtime/lambda_runtime_client.py", line 57, in wait_next_invocation
response = self.runtime_connection.getresponse()
File "/var/lang/lib/python3.7/http/client.py", line 1369, in getresponse
response.begin()
File "/var/lang/lib/python3.7/http/client.py", line 310, in begin
version, status, reason = self._read_status()
File "/var/lang/lib/python3.7/http/client.py", line 271, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "/var/lang/lib/python3.7/socket.py", line 589, in readinto
return self._sock.recv_into(b)
File "/var/task/lambda_function.py", line 6, in timeout_handler
raise Exception('Time limit exceeded')
Exception: Time limit exceeded
END RequestId
Run Code Online (Sandbox Code Playgroud)
所以我只需要在返回每个响应之前重置信号警报:
import logging
import signal
def timeout_handler(_signal, _frame):
raise Exception('Time limit exceeded')
signal.signal(signal.SIGALRM, timeout_handler)
def lambda_handler(event, context):
try:
signal.alarm(int(context.get_remaining_time_in_millis() / 1000) - 1)
logging.info('Testing stuff')
# Do work
except Exception as e:
logging.error(f'Exception:\n{e}')
signal.alarm(0)# This line fixed the issue above!
return {'statusCode': 200, 'body': 'Complete'}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ein 10
这是来自cloudformation-custom-resources/lambda/python · GitHub的示例展示了用 Python 编写的 AWS Lambda 函数如何意识到它即将超时。
(我已经编辑了其他内容,这是相关的部分):
import signal
def handler(event, context):
# Setup alarm for remaining runtime minus a second
signal.alarm((context.get_remaining_time_in_millis() / 1000) - 1)
# Do other stuff
...
def timeout_handler(_signal, _frame):
'''Handle SIGALRM'''
raise Exception('Time exceeded')
signal.signal(signal.SIGALRM, timeout_handler)
Run Code Online (Sandbox Code Playgroud)
我能想到的两个选择,第一个是快速和肮脏的,但也不太理想:
在步骤函数中运行它(查看AWS中的步骤函数),该函数能够在超时/错误时重试
更好的方法是将代码重新架构为幂等。在此示例中,触发 lambda 的流程会检查一个条件,只要该条件为真,就会触发 lambda。除非 lambda 成功执行完逻辑,否则该条件需要保持为 true。例如,这可以通过将发送到 lambda 的参数保存在数据库的表中来获得,并且有一个名为“processed”的额外字段,仅当 lambda 成功完成该事件的运行后,该字段才会被修改为“true”。
使用方法 #2 将使您的代码更具弹性,易于在出现错误时重新运行,并且也易于监控:基本上您所要做的就是检查有多少此类未处理的记录,以及它们的创建/内容是什么更新数据库上的时间戳。
| 归档时间: |
|
| 查看次数: |
4132 次 |
| 最近记录: |