Akka .NET 连接池超时问题

7
我们正在使用Akka.NET创建一个新系统,并已经设置了基本的群集,包括分片和持久性。我们参考了官方文档和Petabridge博客文章使分片正常工作。但是,我们遇到了一个问题,即分片数超过了SQL Server连接池允许的最大连接数,导致出现以下消息:“Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached。” 我们认为这是在分片更新分片日志时发生的。为什么分片模块没有正确管理其SQL连接?这里是否存在配置问题?当此类错误发生时,是否可能重试以避免消息丢失?以下是相关的HOCON:
cluster.sharding {
    journal-plugin-id = "akka.persistence.journal.sharding"
    snapshot-plugin-id = "akka.persistence.snapshot-store.sharding"
}
persistence {
    journal {
        plugin = "akka.persistence.journal.sql-server"
        sql-server {
            class = "Akka.Persistence.SqlServer.Journal.SqlServerJournal, Akka.Persistence.SqlServer"
            connection-string = "Server=.;Database=akkasystem;Integrated Security=true"
            schema-name = dbo
            auto-initialize = on
        }
        # a separate config used by cluster sharding only 
        sharding {
            connection-string = "Server=.;Database=akkasystem;Integrated Security=true"
            auto-initialize = on
            plugin-dispatcher = "akka.actor.default-dispatcher"
            class = "Akka.Persistence.SqlServer.Journal.SqlServerJournal, Akka.Persistence.SqlServer"
            connection-timeout = 30s
            schema-name = dbo
            table-name = ShardingJournal
            timestamp-provider = "Akka.Persistence.Sql.Common.Journal.DefaultTimestampProvider, Akka.Persistence.Sql.Common"
            metadata-table-name = ShardingMetadata
        }
    }
    snapshot-store {
        sharding {
            class = "Akka.Persistence.SqlServer.Snapshot.SqlServerSnapshotStore, Akka.Persistence.SqlServer"
            plugin-dispatcher = "akka.actor.default-dispatcher"
            connection-string = "Server=.;Database=akkasystem;Integrated Security=true"
            connection-timeout = 30s
            schema-name = dbo
            table-name = ShardingSnapshotStore
            auto-initialize = on
        }
    }
}
1个回答

1
这可能是SQL日志记录了大量事件,以至于连接超时触发,而事件正在等待池中的下一个连接被释放。从您的配置中可以看出,如果您开始持久化事件并创建高比率的分片/实体,则可能会发生这种情况。现有的SQL日志记录将在不久的将来获得显着的速度提升(请参见批处理日志记录)。希望这能帮助解决您的问题。

我们目前最关注的问题是,这些消息实际上只能以最多一次的方式传递。每当发生 SQL 超时时,应该执行的操作就会丢失。我们希望通过使用 Akka.Persistence 来实现至少一次的消息传递。到目前为止,这似乎不是这种情况。您能否提供建议,以便在超时发生时重新尝试操作/消息不丢失? - Aaron
这段代码片段是构建作为至少传递一次的网关代理工作的示例。但请记住,它将约束您的演员以幂等的方式处理传入消息。如果您真的想获得至少传递一次的传送语义,通常最好的方法是在通信链前面放置一个队列(例如RabbitMQ或甚至Kafka),并在发生故障时仅重新启动未处理的消息进程。 - Bartosz Sypytkowski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接