2017-04-20 178 views
6

我们正在创建一个使用Akka.NET的新系统,并具有分片和持久性的基本集群设置。Akka .NET连接池超时问题

我们已经使用官方文档以及一些Petabridge博客帖子来使分片正常工作。但是,我们遇到了分片超过SQL Server连接池允许的最大连接数的问题。因此,我们得到以下信息...

2017年4月20日14:04:31.433 +01:00【警告】“超时过期的 超时时间已过获取连接之前, 发生这种情况的原因可能是因为所有连接的池都在使用中,并且最大池大小已达到 。“

我们认为当分片更新分片日志时会发生这种情况。

分区模块如何正确管理其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

这可能是因为SQL杂志上充斥着传入的事件如此严重,是连接超时触发一个标志,而事件正等待从池中的下一个连接是释放。

从你的配置我怀疑,这可能发生,如果你已经开始持续事件和创建高比率的碎片/实体。现有的SQL日志将在不久的将来大幅提升速度(请参阅batching journals)。希望这可以帮助解决你的问题。

+0

我们目前关注的主要问题是,我们实际上最多只能传递一次这些消息。无论何时发生SQL超时,应该执行的操作都会丢失。 我们希望通过使用Akka.Persistence,我们能够实现至少一次交付。到目前为止,这似乎不是这种情况。您能否告知我们如何实现这一目标,以便重试操作/发生超时时不会丢失消息? – Aaron

+0

[此片段](https://gist.github.com/Horusiath/64d829720b66df16bc59dbf106a8008e)或多或少是如何构建代理角色的示例,这些代理角色至少是一次传递网关。但请记住它会限制你的演员以幂等的方式处理传入的消息。同样,如果你真的想获得至少一次交付语义,通常最好在通信链前放置一个队列(即RabbitMQ甚至Kafka),如果失败,只需重新启动未处理消息的过程。 – Horusiath