首页 > 解决方案 > 如何检查 python 项目中的 websocket 瓶颈

问题描述

我目前有一个脚本可以连接到服务器、建立 websocket 连接并接收高频消息。

我很确定我的客户端的处理跟不上消息的速度,因此我在一小段时间后就落后了。

我的理解是消息在服务器发送缓冲区和我的客户端接收缓冲区中都排队,如果我处理它们的速度不够快,最终缓冲区将填满,我将丢失消息,这将导致乱序问题,我的假设正确吗?

我的问题是,追踪可能的瓶颈并追踪问题是服务器还是客户端的最佳方法(工具)是什么?我正在 Visual Studio 中使用 python,并且现在使用 PM2 运行单个进程。

我正在寻找有关跟踪低级别瓶颈的方法的建议,即使这意味着使用wireshark等工具。

谢谢。

标签: websocketnetwork-programming

解决方案


我的建议是使用geventgevent-websocket以便所有连接都是异步的。然后您可以异步进行多个连接。

  • 使用 GIPC,您可以为每个 cpu 内核启动一个实例并在端口之间进行负载平衡。

例子:

from gevent import monkey, socket, Timeout, sleep
monkey.patch_all()
import sys
pyver = sys.version_info[0]
if pyver == 3:
    import signal
    from gevent import signal_handler as sig
else:
    from gevent import signal
import bottle
from bottle import route, request, response, abort
import ujson as json
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket import WebSocketError
import traceback

@route('/ws/app')
def handle_websocket():
    global ws_users
    ws = request.environ.get('wsgi.websocket')
    if not ws:
        abort(400, 'Expected WebSocket request.')
    while 1:
        message = None
        try:
            with Timeout(2, False) as timeout:
                message = ws.receive()
            if message:
                message = json.loads(message)
                # process message, report back with ws.send()
                
        except WebSocketError:
            break
        except Exception as exc:
            traceback.print_exc()
            sleep(1)


if __name__ == '__main__':
    print(socket.gethostname())
    print('Started...')
    botapp = bottle.app()
    server = WSGIServer(("0.0.0.0", int(80)), botapp , handler_class=WebSocketHandler)

    def shutdown():
        print('Shutting down ...')
        server.stop(timeout=60)
        exit(signal.SIGTERM)
    if pyver == 3:
        sig(signal.SIGTERM, shutdown)
        sig(signal.SIGINT, shutdown)
    else:
        signal(signal.SIGTERM, shutdown)
        signal(signal.SIGINT, shutdown) #CTRL C
    server.serve_forever()

推荐阅读