我已经设置了一个没有认证的公共端点的AWS API网关,它连接到一个触发Lambda的websocket。
我使用Python的websocket-client库https://pypi.org/project/websocket_client/创建连接。我注意到,连接会在10%的时间内失败,并且随着负载的增加而变得更糟。我找不到任何会限制我的地方,因为我的API网关通用设置显示“您当前的帐户级别限流率为每秒10000个请求,突发请求为5000个请求。”。即使每秒只有2-3个请求,也会经常触发问题。
与此同时,故障响应将类似于“{u'message': u'Forbidden', u'connectionId': u'Z2Jp-dR5vHcCJkg=', u'requestId': u'Z2JqAEJRvHcFzvg='}”。
我进入我的CloudWatch日志洞察并搜索连接ID和请求ID。API网关的日志组找不到任何具有任一ID的结果。然而,在我的Lambda上搜索websocket连接时,会有一个具有该连接ID的日志。日志显示我们这边一切都按预期运行。Lambda仅运行触发MySQL查询的操作。
尽管Lambda按预期工作,为什么会收到被禁止的响应?
现有的问题getting message: forbidden reply from AWS API gateway似乎是在讨论私有端点是否总是返回禁止。没有任何与我的使用情况相符的内容。
更新
我认为这可能与我正在使用的
我使用Python的websocket-client库https://pypi.org/project/websocket_client/创建连接。我注意到,连接会在10%的时间内失败,并且随着负载的增加而变得更糟。我找不到任何会限制我的地方,因为我的API网关通用设置显示“您当前的帐户级别限流率为每秒10000个请求,突发请求为5000个请求。”。即使每秒只有2-3个请求,也会经常触发问题。
与此同时,故障响应将类似于“{u'message': u'Forbidden', u'connectionId': u'Z2Jp-dR5vHcCJkg=', u'requestId': u'Z2JqAEJRvHcFzvg='}”。
我进入我的CloudWatch日志洞察并搜索连接ID和请求ID。API网关的日志组找不到任何具有任一ID的结果。然而,在我的Lambda上搜索websocket连接时,会有一个具有该连接ID的日志。日志显示我们这边一切都按预期运行。Lambda仅运行触发MySQL查询的操作。
尽管Lambda按预期工作,为什么会收到被禁止的响应?
现有的问题getting message: forbidden reply from AWS API gateway似乎是在讨论私有端点是否总是返回禁止。没有任何与我的使用情况相符的内容。
更新
我认为这可能与我正在使用的
locust.io
或Python有关。我在我的计算机上安装了https://www.npmjs.com/package/wscat并重复尽可能快地连接和关闭。我没有收到Forbidden
消息。这仅令人困惑,因为我不确定我连接的方式如何会随机返回Forbidden
消息一些时间。class SocketClient(object):
def __init__(self, host):
self.host = host
self.session_id = uuid4().hex
def connect(self):
self.ws = websocket.WebSocket()
self.ws.settimeout(10)
self.ws.connect(self.host)
events.quitting += self.on_close
data = self.attach_session({})
return data
def attach_session(self, payload):
message_id = uuid4().hex
start_time = time.time()
e = None
try:
print("Sending payload {}".format(payload))
data = self.send_with_response(payload)
assert data['mykey']
except AssertionError as exp:
e = exp
except Exception as exp:
e = exp
self.ws.close()
self.connect()
elapsed = int((time.time() - start_time) * 1000)
if e:
events.request_failure.fire(request_type='sockjs', name='send',
response_time=elapsed, exception=e)
else:
events.request_success.fire(request_type='sockjs', name='send',
response_time=elapsed,
response_length=0)
return data
def send_with_response(self, payload):
json_data = json.dumps(payload)
g = gevent.spawn(self.ws.send, json_data)
g.get(block=True, timeout=2)
g = gevent.spawn(self.ws.recv)
result = g.get(block=True, timeout=10)
json_data = json.loads(result)
return json_data
def on_close(self):
self.ws.close()
class ActionsTaskSet(TaskSet):
@task
def streams(self):
response = self.client.connect()
logger.info("Connect Response: {}".format(response))
class WSUser(Locust):
task_set = ActionsTaskSet
min_wait = 1000
max_wait = 3000
def __init__(self, *args, **kwargs):
super(WSUser, self).__init__(*args, **kwargs)
self.client = SocketClient('wss://mydomain.amazonaws.com/endpoint')
更新2
我已经启用了访问日志,这是以前不存在的一种日志类型。现在我可以看到我的Lambda总是得到200,没有问题。403来自于某些未命中实际routeKey
的MESSAGE
eventType
。不确定它来自哪里,但很确定找到答案就能解决这个问题。
我还确认了没有ENI问题。
routeKey
问题,应该证实了这不是问题所在。 - Dave Stein