十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
上周的工作中遇到了一个停止运行任务时的问题,就是在一个任务运行到一半时需要停止的问题。正常的需求是一按停止按钮,就要立即停止,但现在都要等程序运行完才能停止,现在是一个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对象自己来做停止操作。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。