我刚刚try 使用Golang从本地计算机连接到Docker Desktop上启动的3 node Scylla集群,但没有成功(在Mac M2上)

我试着遵循下面的步骤:https://university.scylladb.com/courses/using-scylla-drivers/lessons/golang-and-scylla-part-1/

例外是我没有为测试应用程序创建停靠容器,因为我不想在任何时候修改代码时重新创建容器.我现在想在本地进行测试.

Docker-组合零件

services:
  scylla-node1:
    image: scylladb/scylla:latest
    restart: always
    container_name: scylla-node1
    command: --seeds=scylla-node1,scylla-node2 --smp 1 --memory 750M --overprovisioned 1 --api-address 0.0.0.0
    volumes:
      - './scylla/scylla.yaml:/etc/scylla/scylla.yaml'
      - './scylla/cassandra-rackdc.properties.dc1:/etc/scylla/cassandra-rackdc.properties'
      - './scylla/mutant-data.txt:/mutant-data.txt'
    networks:
      - myappnetwork

  scylla-node2:
    image: scylladb/scylla:latest
    restart: always
    container_name: scylla-node2
    command: --seeds=scylla-node1,scylla-node2 --smp 1 --memory 750M --overprovisioned 1 --api-address 0.0.0.0
    volumes:
      - './scylla/scylla.yaml:/etc/scylla/scylla.yaml'
      - './scylla/cassandra-rackdc.properties.dc1:/etc/scylla/cassandra-rackdc.properties'
    networks:
      - myappnetwork

  scylla-node3:
    image: scylladb/scylla:latest
    restart: always
    container_name: scylla-node3
    command: --seeds=scylla-node1,scylla-node2 --smp 1 --memory 750M --overprovisioned 1 --api-address 0.0.0.0
    volumes:
      - './scylla/scylla.yaml:/etc/scylla/scylla.yaml'
      - './scylla/cassandra-rackdc.properties.dc1:/etc/scylla/cassandra-rackdc.properties'
    networks:
      - myappnetwork

networks:
  myappnetwork:
    driver: bridge

那么,I created the keyspace and data as explained in the tutorial

并try 连接gocql:

// go.mod

go 1.21.0

replace github.com/gocql/gocql => github.com/scylladb/gocql v1.11.1

import (
  ...
  "github.com/gocql/gocql"
)

func Start(log logger.Logger) {
    config := CreateCluster(gocql.Quorum, "catalog", "scylla-node1", "scylla-node2", "scylla-node3")
    // config := CreateCluster(gocql.Quorum, "catalog", "172.29.0.5", "172.29.0.4", "172.29.0.3")
    // >>> doesn't work either cause I can't even ping containers IPs
    session, err := gocql.NewSession(*config)
    if err != nil {
        log.Fatal(err, "db", "Start", "unable to connect to scylla")
    }
    defer session.Close()
}

func CreateCluster(consistency gocql.Consistency, keyspace string, hosts ...string) *gocql.ClusterConfig {
    retryPolicy := &gocql.ExponentialBackoffRetryPolicy{
        Min:        time.Second,
        Max:        10 * time.Second,
        NumRetries: 5,
    }
    config := gocql.NewCluster(hosts...)
    config.PoolConfig.HostSelectionPolicy = gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy())
    config.Compressor = &gocql.SnappyCompressor{}
    config.RetryPolicy = retryPolicy
    config.Timeout = 5 * time.Second

    config.Keyspace = keyspace
    config.Consistency = consistency

    return config
}

误差率 Gocql:无法创建会话:无法发现协议版本:拨号tcp:0->172.29.0.3:9042:I/O超时

推荐答案

您说得对,但这就是底层Docker实现在Mac上的工作方式.:-)

容器在VM内部运行,因此您不能默认将流量路由到容器IP地址.

但是,您可以将端口从容器绑定到主机,但这样做的问题是,考虑到CQL协议的工作方式,您的驱动程序将无法连接.

您有几个选项:

1-启动单个ScyllaDB容器,将端口9042/19042(和/或相关的TLS端口,如果适用)绑定到您的主机.告诉您的应用程序连接到本地主机并完成.此方法不适用于包含1个以上 node 的集群.

2-将您的应用程序移动到同一网络下的容器.由于容器将与底层虚拟机位于同一网络中,因此流量将是可路由的!

3-你可以阅读更多,try 一下列出的from the Docker forum个变通办法中的一些,明知在future 的某个时候它可能会崩溃.

4-改为运行Linux(或在VM中运行),它在本地将发布的容器端口路由到主机,不会有太多麻烦.

Go相关问答推荐

Go -SDP服务器读缓冲区不会更改任何内容

macOS上GoLand 2023.3.4中的代码导航

仅呈现一个模板的GIN Web应用程序

Golang XML密钥名称冲突

为什么没有正确生成这些元组?

如何在出现错误时停止从通道读取?

Golang Gorm Fiber / argon2.Config 未定义

如何使用 html/template 在 golang 中运行一个范围内的范围

对 CSV 进行单元测试失败

Golang crypto/rand 线程安全吗?

Golang Oauth2 服务帐户返回空刷新令牌字符串

如何确定作为函数参数传递的指针是否正在被修改或副本是否正在被修改?

从动态输入中提取字符串,其中部分字符串可能不存在

如何在没有内存分配的情况下压缩和发布文件

如何在 GORM 中获取字段值

vs 代码调试 go 测试不通过标志

Golang - 无法从 pipped Windows 命令中获取结果

Go Fyne 禁用 HSplit 调整大小?

如何扩充 ResponseWriter 的 Header() 返回的 map

有没有一种方法可以确保传递的值具有使用泛型的某些字段?