Scala Sqs Akka流内存不足
下面的代码在运行15分钟内(java配置xms 1024 xmx2G)在EC2实例上抛出OOO,但在intellij上运行时不会抛出任何错误Scala Sqs Akka流内存不足,scala,aws-lambda,amazon-sqs,akka-stream,alpakka,Scala,Aws Lambda,Amazon Sqs,Akka Stream,Alpakka,下面的代码在运行15分钟内(java配置xms 1024 xmx2G)在EC2实例上抛出OOO,但在intellij上运行时不会抛出任何错误 SqsSource(queueUrl, //parallelism = maxBufferSize / maxBatchSize 20 10 SqsSourceSettings().withWaitTime(10 seconds) .withMaxBatchSize(10).withMaxBufferSize(20)
SqsSource(queueUrl,
//parallelism = maxBufferSize / maxBatchSize 20 10
SqsSourceSettings().withWaitTime(10 seconds)
.withMaxBatchSize(10).withMaxBufferSize(20)
).map {
msg => {
val out = Source.single(msg)
.via(messageToLambdaRequest)
.via(lambdaRequestToLambdaResp)
.via(lambdaRespToAggregationKeySet)
.via(workFlow)
.log("error while consuming events internally.")
.withAttributes(ActorAttributes.supervisionStrategy(decider))
.runWith(Sink.seq)
val reducedResponse = out.map(response => {
response.foldLeft[Response](OK)((a, b) =>
if (a == OK && b == OK) OK else NotOK)
})
val messageAction = reducedResponse
.map(res =>
if (res == OK) {
//log.info("finally response is OK hence message action delete is prepared. {}.", msg.messageId())
delete(msg)
} else
ignore(msg)
)
messageAction
}
}
.mapAsync(1)(identity)
.withAttributes(ActorAttributes.supervisionStrategy(decider))
// For the SQS Sinks and Sources the sum of all parallelism (Source) and maxInFlight (Sink)
// must be less than or equal to the thread pool size.
.log("error log")
.runWith(SqsAckSink(queueUrl, SqsAckSettings(1)))
}
我用1.0-M3和1.0-RC1都试过了。
这有解决办法吗
使用jhat的前5个对象创建直方图-
Class Instance Count Total Size
class [C 1376284 2068640582
class software.amazon.awssdk.services.sqs.model.Message 332718 18632208
class java.lang.String 1375675 16508100
class [Lakka.dispatch.forkjoin.ForkJoinTask; 227 14880304
class scala.collection.immutable.$colon$colon 334396 5350336
我在这里也发现了类似的问题-
我想知道是否有其他方法可以解决这个问题。所以这是现有Alpakka框架中的OOM问题,并在1.0-RC2-
但是,作为charm的替代工作(尽管它不赞成使用Alpakka Sqs)您可以等待RC2/1.0.0 Alpakka发行版,也可以同时创建自己的Sqs源代码,因为代码行不多:
对象MyVeryOwnSqsSource{
def应用(
queueUrl:String,
设置:SqsSourceSettings=SqsSourceSettings.Defaults
)(隐式sqsClient:SqsAsyncClient):源[消息,未使用]=
来源
.重复{
val请求生成器=
ReceiveMessageRequest
.builder()
.queueUrl(queueUrl)
.attributeNames(settings.attributeNames.map(u.name).map(QueueAttributeName.fromValue).asJava)
.messageAttributeNames(settings.messageAttributeNames.map(\uz.name).asJava)
.maxNumberOfMessages(设置.maxBatchSize)
.waitTimeSeconds(设置.waitTimeSeconds)
settings.visibilityTimeout匹配{
case None=>requestBuilder.build()
case Some(t)=>requestBuilder.visibilityTimeout(t.toSeconds.toInt.build())
}
}
.mapAsync(settings.maxBufferSize/settings.maxBatchSize)(sqsClient.receiveMessage(U8;).toScala)
.map(u.messages().asScala.toList)
.takeWhile(messages=>!settings.closeOnEmptyReceive | | messages.nonEmpty)
.mapConcat(身份)
.buffer(设置.maxBufferSize,溢出策略.背压)
}
然后使用它:
MyVeryOwnSqsSource(queueUrl,
//并行度=maxBufferSize/maxBatchSize 20 10
SqsSourceSettings()。withWaitTime(10秒)
.withMaxBatchSize(10)。withMaxBufferSize(20)
).地图{
msg=>{
val out=源。单个(msg)
.via(messageToLambdaRequest)
.via(lambdaRequestToLambdaResp)
.via(lambdaRespToAggregationKeySet)
.via(工作流程)
.log(“内部使用事件时出错。”)
.具有属性(ActorAttributes.监督策略(decider))
.runWith(水槽序号)
val reducedResponse=out.map(响应=>{
response.foldLeft[response](确定)((a,b)=>
如果(a==正常&&b==正常)正常(否则不正常)
})
val messageAction=reducedResponse
.map(res=>
如果(res==OK){
//log.info(“最终响应正常,因此准备了消息操作delete.{}.”,msg.messageId()
删除(msg)
}否则
忽略(msg)
)
消息操作
}
}
.mapsync(1)(标识)
.具有属性(ActorAttributes.监督策略(decider))
//对于SQS接收器和源,所有并行性(源)和maxInFlight(接收器)的总和
//必须小于或等于线程池大小。
.log(“错误日志”)
能否指定删除
,忽略
&所有其他中间函数返回的确切内容?MessageAction;阿尔帕卡sqs有一个API。谢谢加布里埃尔。我现在使用akka stream sqs,但当它出现时,我将迁移到RC2。