我正在尝试创建一个消费者应用程序,该应用程序使用Spring云流来消费Kinesis流中的事件。
我的使用者应用程序正在AWS自动缩放组中运行,我希望它可以在任何时候放大和缩小而不会影响可以处理流中给定条目的实例数。更具体地说,我希望在任何时间点最多具有一个实例来处理流中的事件。
阅读文档后,我认为可以使用使用者组来实现此功能,Kinesis绑定程序甚至在DynamoDB之上提供了自己的MetaDataStore和LockRegistry实现。
由于我不想仅出于持有锁和元数据的目的而引入DynamoDB,因此尽管我可以通过使用预定义组的Jdbc等效实现来实现相同的结果。
在我的初始测试之后,我看到按预期使用了jdbc存储,但是当我在ASG上增加实例时,我注意到消息被消耗了两次(每个实例一次),而不是阅读文档后的预期
我的属性是:
spring.cloud.stream.bindings.input.destination = stream spring.cloud.stream.bindings.input.group =组 spring.cloud.stream.bindings.input.content-type = application / json
锁定注册表领导者e.t.c.的配置:
@Bean
public DefaultLockRepository lockRepository(DataSource dataSource) {
return new DefaultLockRepository(dataSource);
}
@Bean
public LockRegistry lockRegistry(LockRepository lockRepository) {
return new JdbcLockRegistry(lockRepository);
}
@Bean
public LockRegistryLeaderInitiator leaderInitiator(LockRegistry lockRegistry) {
LockRegistryLeaderInitiator lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(lockRegistry);
lockRegistryLeaderInitiator.setPublishFailedEvents(true);
return lockRegistryLeaderInitiator;
}
@Bean
public MetadataStore metadataStore(DataSource dataSource) {
return new JdbcMetadataStore(dataSource);
}
目前,我的Kinesis上只有一条流和一条碎片。
我尝试添加更多的碎片(最多4个),并尝试通过应用程序属性配置并发性。
我可以看到在数据库中按预期填充了元数据存储,并且使用者按预期保持了状态,但是我也看到int_lock表上有多个条目,这些条目我没想到(即我希望看到只有一个客户注册,但我看到了多个)。
所以我的问题是:
我很确定我在概念上缺少一些东西,但是我没有在文档中找到任何内容,the closest to my issue was this issue reported on github 但这使我更加困惑预期的配置。 同样不清楚在ASG环境中instanceIndex和instanceCount应该如何工作
答案 0 :(得分:0)
我看不到您的配置有任何问题。 KinesisMessageChannelBinder
确实期望有ConcurrentMetadataStore
和LockRegistry
bean。使用哪种实现方式已经无关紧要。
尽管您不需要LockRegistryLeaderInitiator
。活页夹中未使用它,可能会为您做一些额外的意外工作。
不过,您需要确保DataSource
是所有实例之间的共享RDBMS。另外,您还需要确保group
选项对于所有实例而言都是相同的。
另外,锁定逻辑实际上是基于像这样的键的:
this.consumerGroup + ":" + stream + ":" + shardId
因此,尚无任何想法,可能是您的配置有问题...