chainlit 实际部署一些问题

chainlit内部基于了socket.io 进行消息处理,socket.io 是有一些缺陷的,但是也有相关的解决方法,同时
对于启动的入口是加载的一个python 文件,这个处理上是动态加载里边的方法到chainlit 运行环境的

内部一些处理

  • load 模块处理
def load_module(target: str, force_refresh: bool = False):
    """Load the specified module."""
 
    # Get the target's directory
    target_dir = os.path.dirname(os.path.abspath(target))
 
    # Add the target's directory to the Python path
    sys.path.insert(0, target_dir)
 
    if force_refresh:
        # Get current site packages dirs
        site_package_dirs = site.getsitepackages()
 
        # Clear the modules related to the app from sys.modules
        for module_name, module in list(sys.modules.items()):
            if (
                hasattr(module, "__file__")
                and module.__file__
                and module.__file__.startswith(target_dir)
                and not any(module.__file__.startswith(p) for p in site_package_dirs)
            ):
                sys.modules.pop(module_name, None)
 
    spec = util.spec_from_file_location(target, target)
    if not spec or not spec.loader:
        return
 
    module = util.module_from_spec(spec)
    if not module:
        return
 
    spec.loader.exec_module(module)
 
    sys.modules[target] = module
 
    # Remove the target's directory from the Python path
    sys.path.pop(0)
  • server 启动
    server的启动是基于fastapi + uvicorn 的
async def start():
    config = uvicorn.Config(
        app,
        host=host,
        port=port,
        ws=ws_protocol,
        log_level=log_level,
        ws_per_message_deflate=ws_per_message_deflate,
        ssl_keyfile=ssl_keyfile,
        ssl_certfile=ssl_certfile,
    )
    server = uvicorn.Server(config)
    await server.serve()
# Run the asyncio event loop instead of uvloop to enable re entrance
asyncio.run(start())

一些问题

目前对于uvicorn 如果需要开启多worker 需要使用 string 的模式传递应用,所以目前的模式是不能支持多worker的,可以调整,但是因为上边动态加载python 代码的问题,造成worker对于chainlit 应用加载会有问题,修改之后 ,因为多worker 运行 ,socket.io 会存在session 不一致的问题,应该基于sticky-session 解决方法,socket.io的adapter 是一种解决方法,但是是多server
消息广播的

说明

目前来说对于chainlit 实际部署最好的模式就是多实例(不是多worker),然后基于lb进行负载均衡,同时注意session共享的问题

参考资料

https://github.com/Chainlit/chainlit/issues/719
https://python-socketio.readthedocs.io/en/stable/server.html#user-sessions
https://socket.io/docs/v4/using-multiple-nodes/#why-is-sticky-session-required
https://socket.io/docs/v4/adapter/

posted on 2024-10-13 07:43  荣锋亮  阅读(49)  评论(0编辑  收藏  举报

导航