Weaviate client.is_ready抛出异常而非返回布尔值问题咨询
问题分析与解决方案
核心问题拆解
Docker容器网络寻址错误
当用Docker Compose同时启动Weaviate和数据导入容器时,导入容器内的localhost指向容器自身,而非宿主机或Weaviate容器。这直接导致导入容器无法访问到Weaviate实例,无论等待多久都会失败。而本地运行代码时,localhost指向宿主机,Weaviate已在宿主机端口监听,因此能正常连接。startup_period参数未实际生效(从报错日志看)
你提供的报错日志中,Client初始化代码未传入startup_period=90(可能是容器内代码未同步更新),导致默认使用5秒超时,直接抛出启动错误,根本没走到后续的is_ready()循环逻辑。
具体解决步骤
1. 修正容器间的服务寻址方式
在Docker Compose配置中,容器可通过服务名互相访问。假设你的Weaviate服务在compose文件中命名为weaviate,修改导入代码中的Client初始化地址:
client = Client("http://weaviate:8088", startup_period=90)
这样导入容器就能通过Docker内部网络直接访问Weaviate服务,无需依赖宿主机端口映射。
2. 确保startup_period参数正确传入
检查Docker容器内的代码是否确实包含startup_period=90参数,避免因代码同步问题使用默认的5秒超时。
3. 优化启动等待逻辑(可选)
is_ready()本身会返回布尔值,但前提是Client能与Weaviate建立基础连接。若网络不通,调用该方法仍可能抛出异常,可添加异常捕获增强鲁棒性:
def main(): try: client = Client("http://weaviate:8088", startup_period=90) except WeaviateStartUpError as e: sys.stderr.write(f"初始化失败:{e}\n") sys.exit(1) wait_time_limit = 240 while True: try: if client.is_ready(): break except Exception as e: sys.stderr.write(f"连接检查失败:{e}\n") if wait_time_limit <= 0: sys.stderr.write("\rTIMEOUT: Weaviate not ready. Try again or check if weaviate is running.\n") sys.exit(1) sys.stdout.write(f"\rWait for weaviate to get ready. {wait_time_limit:02d} seconds left.") sys.stdout.flush() wait_time_limit -= 2 time.sleep(2.0)
4. 添加容器健康检查(推荐)
在Docker Compose中给Weaviate服务添加健康检查,确保导入容器仅在Weaviate完全就绪后启动:
services: weaviate: # 原有配置... healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8088/v1/.well-known/ready"] interval: 5s timeout: 5s retries: 20 import-service: # 原有配置... depends_on: weaviate: condition: service_healthy
内容的提问来源于stack exchange,提问作者slothPete
相关产品推荐
相关产品推荐

