You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Cassandra时容器启动早于数据库就绪的问题求助

解决Cassandra容器健康检查失败导致的Docker Compose启动问题

你的核心问题在于Cassandra容器的健康检查配置有误,同时代码中存在几处小错误,以下是具体修复方案:

1. 修复Docker Compose的健康检查配置

原健康检查命令存在拼写错误,且检测逻辑不合理(Cassandra刚启动时没有自定义keyspace,describe keyspace会直接报错)。修改后的配置如下:

services:
  app:
    build: 
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - .:/app
    container_name: app-container
    depends_on:
      database:
        condition: service_healthy

  database:
    image: cassandra:latest
    ports:
      - 9042:9042
    container_name: cassandra-study-container
    healthcheck:
      test: ["CMD", "cqlsh", "-e", "SELECT now() FROM system.local"]
      interval: 10s
      timeout: 5s
      retries: 10

关键修改点:

  • 将拼写错误的descripe改为describe,同时改用SELECT now() FROM system.local作为检测命令,该查询无需提前创建keyspace,能直接验证Cassandra服务是否正常响应CQL请求
  • 调整健康检查参数:缩短检测间隔、增加重试次数,给Cassandra足够的启动初始化时间(首次启动通常需要30-60秒)

2. 修复App.py中的代码错误

原代码存在两处会导致运行失败的问题,修改后的完整代码如下:

from cassandra.cluster import Cluster
import time

def create_keyspace_and_table(session):
    keyspace_query = """
    CREATE KEYSPACE IF NOT EXISTS store WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}
    """
    session.execute(keyspace_query)

    session.set_keyspace('store')

    create_table = """
    CREATE TABLE IF NOT EXISTS store.mytable (
        id UUID PRIMARY KEY,
        message TEXT
    )
    """
    session.execute(create_table)

def insert_data(session, message):
    insert_query = """
    INSERT INTO store.mytable (id, message) VALUES (uuid(), %s)
    """
    # 单个元素的元组必须加逗号,否则会被解析为单个字符串
    session.execute(insert_query, (message,))

def print_data(session):
    select_query = "SELECT * FROM store.mytable"
    rows = session.execute(select_query)

    for row in rows:
        # 修正拼写错误:mesage → message
        print(f"ID: {row.id}, Message: {row.message}")


if __name__ == "__main__":
    # 添加连接重试逻辑,避免健康检查刚通过但Cassandra未完全就绪的情况
    cluster = None
    session = None
    max_retries = 5
    retry_delay = 3

    for attempt in range(max_retries):
        try:
            cluster = Cluster(['database'], connect_timeout=10)
            session = cluster.connect()
            print("成功连接到Cassandra")
            break
        except Exception as e:
            print(f"连接失败,重试 {attempt+1}/{max_retries}: {e}")
            time.sleep(retry_delay)
    else:
        print("多次重试后仍无法连接到Cassandra,退出")
        exit(1)

    try:
        create_keyspace_and_table(session)

        data = [
            "Ciao sono il primo",
            "Ciao sono il secondo",
            "Ciao sono il terzo"
        ]

        for message in data:
            insert_data(session, message)

        print("\n查询到的数据:")
        print_data(session)
    finally:
        if cluster:
            cluster.shutdown()

关键修改点:

  • 修复print_data函数中row.mesage的拼写错误,改为row.message
  • 修复insert_data函数的参数传递问题:将(message)改为(message,),确保传递的是元组类型,否则Cassandra驱动会将单个字符串解析为字符数组,导致参数不匹配错误
  • 添加连接重试逻辑:即使健康检查标记容器为健康,Cassandra可能仍未完全就绪,通过重试机制避免启动时连接失败

3. 运行验证

执行以下命令重新启动服务:

docker-compose down
docker-compose up --build

此时Cassandra容器会完成健康检查后再启动应用容器,应用也能正常创建keyspace、插入数据并查询输出。

内容的提问来源于stack exchange,提问作者user23733163

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:47:04