MongoDB -插入多个:消息头读取不完整:超过上下文截止时间

92dk7w1h  于 2022-11-22  发布在  Go
关注(0)|答案(1)|浏览(727)

我有一个服务,它从不同的远程服务器上拉取日志文件,并将它们逐行推送到MongoDB中,我使用InsertMany()来实现这一点,单个日志文件在不同的goroutine中处理,这些goroutine将mongo.client作为参数以供并发使用。
一切都运行正常,但在某个时候,我开始在错误日志中看到以下错误:{"error":"connection(127.0.0.1:27017[-11]) incomplete read of message header: context deadline exceeded"}
抛出错误的代码如下所示:

func InsertManyLines(col *mongo.Collection, slds []interface{}) {
    connectionTimeout := time.Duration(15)
    ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout*time.Second)
    defer cancel()
    opts := options.InsertMany().SetOrdered(false)
    _, err := col.InsertMany(ctx, slds, opts)
    if err != nil {
        service.LogError(err, "InsertManyLines")
    }
}

我之前在没有超时的情况下运行了该函数,并得到了以下错误:{"error":"server selection error: server selection timeout, current topology: { Type: Unknown, Servers: [{ Addr: localhost:27017, Type: Unknown, Last error: connection() error occured during connection handshake: dial tcp [::1]:27017: connect: connection refused }, ] }"}
服务每10分钟运行一次,通常在4分钟后结束。随着错误的增加,服务会变得越来越慢,最终在10分钟前无法完成。Mongo.客户端在服务启动时连接,并在其生命周期内使用。客户端在连接时从不抛出错误。
我真的不知道该从incomplete read of message header部分得到什么。我该如何防止这种情况发生?或者有人已经经历过这个错误了吗?

vyswwuz2

vyswwuz21#

在我的案例中,这个问题是由于没有启用TLS而引起的
例如mongodb://localhost:27017/?ssl=true&ssl_ca_certs=my-rds-cert.pem&retryWrites=false并提供正确的证书

func connect() (*mongo.Database, error) {
    caFile := "my-rds-cert.pem"
    uri := "mongodb://localhost:27017/?ssl=true&ssl_ca_certs=my-rds-cert.pem&retryWrites=false"
    var clientOptions *options.ClientOptions = options.Client().ApplyURI(uri)
    tlsConfig := new(tls.Config)
    certs, err := ioutil.ReadFile(caFile)
    tlsConfig.RootCAs = x509.NewCertPool()
    ok := tlsConfig.RootCAs.AppendCertsFromPEM(certs)
    if !ok {
        return nil, fmt.Errorf("failed parsing pem file: %w", err)
    }
    if err != nil {
        return nil, fmt.Errorf("failed getting tls configuration: %v", err)
    }

    clientOptions.SetTLSConfig(tlsConfig)

    client, err := mongo.NewClient(clientOptions)
    if err != nil {
        return nil, fmt.Errorf("failed to create client: %v", err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    err = client.Connect(ctx)
    if err != nil {
        log.Fatalf("Failed to connect to cluster: %v", err)
    }

    db := client.Database("yourdbname")
    return db, nil
}

相关问题