保存数据存储实体时发生java.util.concurrent.CancellationException [英] java.util.concurrent.CancellationException while saving Datastore Entities

查看:697
本文介绍了保存数据存储实体时发生java.util.concurrent.CancellationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图处理一个超过20K行的大型excel文件。每行应该作为实体保存在数据存储中。首先,我使用Blobstore获取servlet中的excel文件,然后使用Task Queue服务排队任务。这个任务读取excel文件,将实体中的每一行转换并存储。正如我之前所说,Excel文件可能有超过20K行。一段时间后,我得到这个异常:

  com.xxx.xxx.ProcessBlob doPost:| POST | ProcessBlob |例外:任务是取消。| Msg:任务被取消。| Stack:java.util.concurrent.CancellationException:任务被取消。 

在com.google.common.util.concurrent.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:796)
在com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture。 java:475)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:381)
at com.google.common.util.concurrent.AbstractFuture $ TrustedFuture.get( AbstractFuture.java:85)
at com.google.appengine.tools.development.TimedFuture.get(TimedFuture.java:42)
at com.google.common.util.concurrent.ForwardingFuture.get( ForwardingFuture.java:63)
在com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:88)
在com.google.appengine.api.datastore.Batcher $ ReorderingMultiFuture。通过com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:88)获取(Batcher.java:131)
(com.google.appengine.api.utils.FutureWrapper)
。通过com.google.appengine.api.utils.FutureWrap获取(FutureWrapper.java:88)
per.get(FutureWrapper.java:88)
,位于com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:75)
,位于com.google.appengine.api.datastore。 FutureHelper.quietGet(FutureHelper.java:35)
at com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:56)
at com.xxx.xxx.xxx.createEntity(
at com.xxx.xxx.ProcessBlob.doPost(ProcessBlob.java:145)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay .jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1166)
在com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
在org.mortbay .jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)
at c om.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
在org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)
。在com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
在org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)
。在org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay。 jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mort bay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
位于com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
位于org.mortbay。 jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(在org.mortbay.jetty.HttpConnection $ RequestHandler.headerComplete HttpConnection.java:542)
(HttpConnection.java:923)在com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser
。 java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
at com.google.apphosting.runtime.JavaRuntime $ RequestRunnable.run(JavaRuntime.java:527)
at com.google.tracing.TraceContext $ TraceContextRunnable.runInContext(TraceContext.java:4 37)
,位于com.google.tracing.TraceContext $ TraceContextRunnable $ 1.run(TraceContext.java:444)
,位于com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
。在在com.google.tracing.TraceContext $ AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
$ com.google.tracing.TraceContext AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
。在COM。 google.tracing.TraceContext $ TraceContextRunnable.run(TraceContext.java:441)
at com.google.apphosting.runtime.ThreadGroupPool $ PoolEntry.run(ThreadGroupPool.java:251)
at java.lang。 Thread.run(Thread.java:724)

导致:java.util.concurrent.CancellationException:Future.cancel()被调用。
,位于com.google.common.util.concurrent.AbstractFuture.cancel(AbstractFuture.java:514)
位于com.google.appengine.tools.development.TimedFuture.cancel(TimedFuture.java:85)
在com.google.common.util.concurrent.ForwardingFuture.cancel(ForwardingFuture.java:48)
在com.google.apphosting.runtime.ApiProxyImpl $ AsyncApiFuture.cancel(ApiProxyImpl.java:553)
at com.google.apphosting.runtime.RequestManager.cancelPendingAsyncFutures(RequestManager.java:626)
at com.google.apphosting.runtime.RequestManager.sendDeadline(RequestManager.java:399)
com.google.apphosting.runtime.RequestManager.sendDeadline(RequestManager.java:357)
,位于com.google.apphosting.runtime.CloneControllerImpl.sendDeadline(CloneControllerImpl.java:201)
,位于com.google .apphosting.sandbox.ModelClonePb $ CloneController $ ServiceParameters $ 3.handleRequest(ModelClonePb.java:1166)
at com.google.net.rpc3.impl.server.RpcServerInternalContext.runRpcInApplication (RpcServerInternalContext.java:558)
,位于com.google.net.rpc3.impl.server.RpcServerChannel $ 1.run(RpcServerChannel.java:871)
,位于com.google.tracing.LocalTraceSpanRunnable.run( LocalTraceSpanRunnable.java:56)
在com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:626)
在com.google.net.rpc3.impl.server.RpcServerChannel.startRpc(RpcServerChannel。 java:837)
,位于com.google.net.rpc3.impl.server.RpcServerChannel.receivedMessage(RpcServerChannel.java:594)
位于com.google.net.rpc3.impl.server.RpcServerChannel。通过com.google.net.rpc3.impl.server.RpcServerChannel访问$ 2700(RpcServerChannel.java:164)
$ TransportCallback.receivedMessage(RpcServerChannel.java:2365)
com.google.net.rpc3 .impl.wire.RpcBaseTransport.receivedMessage(RpcBaseTransport.java:457)
在com.google.apphosting.runtime.udrpc.UdrpcTransport $ ServerAdapter.receivedMessage(UdrpcTransport.java:707)
在com.google .apphost ing.runtime.udrpc.UdrpcTransport.dispatchPacket(UdrpcTransport.java:384)
at com.google.apphosting.runtime.udrpc.UdrpcTransport.readPackets(UdrpcTransport.java:283)
com.google。 apphosting.runtime.udrpc.UdrpcTransport $ 1.run(UdrpcTransport.java:100)
com.google.net.eventmanager.AbstractFutureTask $ Sync.innerRun(AbstractFutureTask.java:260)
com.google .net.eventmanager.AbstractFutureTask.run(AbstractFutureTask.java:121)
com.google.net.eventmanager.EventManagerImpl.runTask(EventManagerImpl.java:594)
com.google.net.eventmanager .EventManagerImpl.internalRunWorkerLoop(EventManagerImpl.java:1011)
位于com.google.net.eventmanager.EventManagerImpl.runWorkerLoop(EventManagerImpl.java:892)
位于com.google.net.eventmanager.WorkerThreadInfo.runWorkerLoop (WorkerThreadInfo.java:161)
at com.google.net.eventmanager.EventManagerImpl $ WorkerThread.run(EventManagerImpl.java:1879)

另一个奇怪的是,查看请求的日志时,参数ms和cpu_ms在丢弃该异常时几乎相同。也许我要超过AppEngine限制或超时限制?

  [02 / Mar / 2015:21:11:32  - 0800]POST / tasks / ProcessBlob HTTP / 1.1200 0http://xxx.appspot.com/uploadAppEngine-Google;(+ http://code.google.com/appengine)xxx。 msgstrmsgstrmsgstrmsgstrmsgstrmsgid,msgstrmsgstrmsgstrmsgid,msgstrmsgid。msgstrmsgid。msgstrmsgstr tasks / ProcessBlob HTTP / 1.1200 0http://xxx.appspot.com/uploadAppEngine-Google;(+ http://code.google.com/appengine)xxx.appspot.comms = 599420 cpu_ms = 33262 queue_name = default task_name = xxx instance = xxx app_engine_release = 1.9.18 


解决方案

看起来你面临任务队列限制,599949ms == 10分钟。根据文档:


针对自动缩放模块的任务必须在10分钟内完成执行
。如果您的任务需要更多时间或
计算资源,则可以将它们发送到手动或基本缩放
模块,在这些模块中它们可以运行长达24小时。
blockquote>

查看文档: https://cloud.google.com/appengine/docs/java/taskqueue/overview-push#task_deadlines



我建议将任务分成几部分更小的任务,比如说每1000条记录有一个任务,可能更小

I'm trying to process a big excel file with more than 20K rows. Each row should be saved as an Entity in Datastore. First, I get the excel file in my servlet using the Blobstore and then I queue a task using the Task Queue service. This task, reads the excel file, convert each line in an Entity and store it. As I said before, Excel file could have more than 20K rows. After a while I get this exception:

com.xxx.xxx.ProcessBlob doPost: |POST|ProcessBlob|Exception:Task was cancelled.|Msg:Task was cancelled.|Stack:java.util.concurrent.CancellationException: Task was cancelled.

    at com.google.common.util.concurrent.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:796)
    at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:475)
    at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:381)
    at com.google.common.util.concurrent.AbstractFuture$TrustedFuture.get(AbstractFuture.java:85)
    at com.google.appengine.tools.development.TimedFuture.get(TimedFuture.java:42)
    at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:88)
    at com.google.appengine.api.datastore.Batcher$ReorderingMultiFuture.get(Batcher.java:131)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:88)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:88)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:88)
    at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:75)
    at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:35)
    at com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:56)
    at com.xxx.xxx.xxx.createEntity(EntityService.java:87)
    at com.xxx.xxx.ProcessBlob.doPost(ProcessBlob.java:145)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:527)
    at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
    at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
    at java.lang.Thread.run(Thread.java:724)

Caused by: java.util.concurrent.CancellationException: Future.cancel() was called.
    at com.google.common.util.concurrent.AbstractFuture.cancel(AbstractFuture.java:514)
    at com.google.appengine.tools.development.TimedFuture.cancel(TimedFuture.java:85)
    at com.google.common.util.concurrent.ForwardingFuture.cancel(ForwardingFuture.java:48)
    at com.google.apphosting.runtime.ApiProxyImpl$AsyncApiFuture.cancel(ApiProxyImpl.java:553)
    at com.google.apphosting.runtime.RequestManager.cancelPendingAsyncFutures(RequestManager.java:626)
    at com.google.apphosting.runtime.RequestManager.sendDeadline(RequestManager.java:399)
    at com.google.apphosting.runtime.RequestManager.sendDeadline(RequestManager.java:357)
    at com.google.apphosting.runtime.CloneControllerImpl.sendDeadline(CloneControllerImpl.java:201)
    at com.google.apphosting.sandbox.ModelClonePb$CloneController$ServiceParameters$3.handleRequest(ModelClonePb.java:1166)
    at com.google.net.rpc3.impl.server.RpcServerInternalContext.runRpcInApplication(RpcServerInternalContext.java:558)
    at com.google.net.rpc3.impl.server.RpcServerChannel$1.run(RpcServerChannel.java:871)
    at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
    at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:626)
    at com.google.net.rpc3.impl.server.RpcServerChannel.startRpc(RpcServerChannel.java:837)
    at com.google.net.rpc3.impl.server.RpcServerChannel.receivedMessage(RpcServerChannel.java:594)
    at com.google.net.rpc3.impl.server.RpcServerChannel.access$2700(RpcServerChannel.java:164)
    at com.google.net.rpc3.impl.server.RpcServerChannel$TransportCallback.receivedMessage(RpcServerChannel.java:2365)
    at com.google.net.rpc3.impl.wire.RpcBaseTransport.receivedMessage(RpcBaseTransport.java:457)
    at com.google.apphosting.runtime.udrpc.UdrpcTransport$ServerAdapter.receivedMessage(UdrpcTransport.java:707)
    at com.google.apphosting.runtime.udrpc.UdrpcTransport.dispatchPacket(UdrpcTransport.java:384)
    at com.google.apphosting.runtime.udrpc.UdrpcTransport.readPackets(UdrpcTransport.java:283)
    at com.google.apphosting.runtime.udrpc.UdrpcTransport$1.run(UdrpcTransport.java:100)
    at com.google.net.eventmanager.AbstractFutureTask$Sync.innerRun(AbstractFutureTask.java:260)
    at com.google.net.eventmanager.AbstractFutureTask.run(AbstractFutureTask.java:121)
    at com.google.net.eventmanager.EventManagerImpl.runTask(EventManagerImpl.java:594)
    at com.google.net.eventmanager.EventManagerImpl.internalRunWorkerLoop(EventManagerImpl.java:1011)
    at com.google.net.eventmanager.EventManagerImpl.runWorkerLoop(EventManagerImpl.java:892)
    at com.google.net.eventmanager.WorkerThreadInfo.runWorkerLoop(WorkerThreadInfo.java:161)
    at com.google.net.eventmanager.EventManagerImpl$WorkerThread.run(EventManagerImpl.java:1879)

Another "weird" thing is that, seeing the logs for the requests, the parameters "ms" and "cpu_ms" are nearly the same when it drops that exception. Maybe I'm going above the AppEngine limits or timeout limits?

[02/Mar/2015:21:11:32 -0800] "POST /tasks/ProcessBlob HTTP/1.1" 200 0 "http://xxx.appspot.com/upload" "AppEngine-Google; (+http://code.google.com/appengine)" "xxx.appspot.com" ms=599492 cpu_ms=32522 queue_name=default task_name=xxx instance=xxx app_engine_release=1.9.18

[02/Mar/2015:23:21:55 -0800] "POST /tasks/ProcessBlob HTTP/1.1" 200 0 "http://xxx.appspot.com/upload" "AppEngine-Google; (+http://code.google.com/appengine)" "xxx.appspot.com" ms=599420 cpu_ms=33262 queue_name=default task_name=xxx instance=xxx app_engine_release=1.9.18

解决方案

Looks like you faced Task Queue limits, 599949ms == 10 minutes. As per doc:

Tasks targeted at an automatic scaled module must finish execution within 10 minutes. If you have tasks that require more time or computing resources, they can be sent to manual or basic scaling modules, where they can run up to 24 hours.

See docs: https://cloud.google.com/appengine/docs/java/taskqueue/overview-push#task_deadlines

I suggest to split task into few smaller tasks, say one task per 1000 records, maybe smaller

这篇关于保存数据存储实体时发生java.util.concurrent.CancellationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆