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/719https://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/