Dav*_*ein 14 python websocket locust aws-lambda aws-api-gateway
我为没有身份验证的公共端点设置了AWS API网关。它连接到触发Lambda的WebSocket。
我正在通过https://pypi.org/project/websocket_client/与Python的websocket-clientlib 建立连接。
我注意到连接将在大约10%的时间内失败,并且随着负载的增加而变得更糟。正如我的常规API网关设置所说,我找不到任何让我感到烦恼的地方Your current account level throttling rate is 10000 requests per second with a burst of 5000 requests.。除此之外,每秒只有2-3个请求经常会触发问题。
同时失败响应会像 {u'message': u'Forbidden', u'connectionId': u'Z2Jp-dR5vHcCJkg=', u'requestId': u'Z2JqAEJRvHcFzvg='}
我进入了CloudWatch日志洞察,并搜索了连接ID和请求ID。API网关的日志组将找不到任何一个ID的结果。但是,在我的Lambda上进行搜索(在websocket connect上触发)时,将带有该连接ID的日志。日志显示一切正常运行。lambda只是运行一个将触发的MySQL查询。
尽管lambda可以按预期工作,但为什么我会得到禁止的响应?
获取消息时存在的问题:禁止从AWS API网关回复,似乎可以解决某些私有端点是否始终返回禁止的问题。我的用例没有任何内容。
更新
我认为这可能与locust.io或python有关,而我正在每秒使用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')
Run Code Online (Sandbox Code Playgroud)
更新2
我启用了访问日志,这是以前不存在的一种日志。现在,我可以看到我的lambda总是得到200,没有问题。403来自一些MESSAGE eventType没有达到实际水平的产品routeKey。不知道它来自哪里,但是可以肯定找到答案会解决这个问题。
我还能够确认没有ENI问题。
我的示例中的有效负载是空的。API 配置为用于$request.body.action了解 RouteKey。连接使默认$connect路由有效。
在我的身体里添加一个适当的东西action让 403 消失了。这就是解决方案。我基本上从连接和断开连接的行为中收到了 200 个响应,但每当我的消息没有负载时,就会收到 403 响应。
| 归档时间: |
|
| 查看次数: |
564 次 |
| 最近记录: |