温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

akka系统中停止运行任务的问题

发布时间:2020-07-31 22:19:23 来源:网络 阅读:2495 作者:金明略 栏目:开发技术

   上周的工作中遇到了一个停止运行任务时的问题,就是在一个任务运行到一半时需要停止的问题。正常的需求是一按停止按钮,就要立即停止,但现在都要等程序运行完才能停止,现在是一个bug。由于之前写任务运行逻辑的不是我,因此我先花一个小时苦读大神们的代码,了解了他们对于任务运行那块的逻辑,发现是首先前端发消息给一个Actor,然后这个Actor用actorOf方法创建许多子Actor,然后再对这些Actor调用ActorSelection创建运行这个任务的Actor。

   之前以为通过获取Actor的地址,终止这个Actor,然后自动终止其所有子Actor应该就能停止任务了,后来发现根本停不下来。

   第一次尝试是在状态机FSM中不仅在whenUnhandled方式下停止Actor,而且在其他每一种状态下都调用停止Actor操作,直接终止运行该线程的Actor。

   这里顺便普及一下停止Actor的时候,是给该Actor发送两种消息,Kill或者PoisonPill。使用Kill消息可以在不损失缓冲区中消息的情况下重启Actor对象,但是不会停止Actor对象,仅仅是重启,而且会抛出异常,使用PoisonPill消息可以停止Actor对象,但允许Actor对象处理完收到PoisonPill消息之前存储在缓冲区中的消息。然后我又尝试了context.stop(actorRef)去直接停止某Actor,同样无济于事,线程依旧潇洒地运行结束。

   这个时候我发现问题应该转移到线程级别,既然终止Actor是不起作用的,我就干脆把这个线程终止掉。一开始我们采用给运行线程的Actor发送消息的方式终止该线程,发现能停止,但还是在任务运行完之后停止。后来我意识到,Actor处理消息应该是按照发送顺序来的,首先发送的消息是处理这个任务,所以只有处理完任务才会处理停止线程这个消息,此时线程已经不是运行状态了。因此我干脆定义了一个线程安全的HashMap,保存了id和Process对象的映射关系,可以通过这个数据结构搜索到线程对象,当父Actor收到终止任务命令时,不再向运行该任务的子Actor发送消息,而是在父Actor中直接调用运行任务的线程的Process对象里的destroy方法,直接终止这个线程,终于成功了。

   得出结论就是,akka系统对于线程粒度的启停控制可能还是有一定缺陷,需要我们根据线程的Process对象自己来做停止操作。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI