在你发或者回消息的地方😅
egametang 这个问题的本质是
A和B2个Actor,一段逻辑A调用B,同时有另外一段逻辑发起了B调用A,就会出现A等B,B再等A,此时发生死锁。同理 [A->B->C,C->D->A] [A->B->C,B->C->A],这样的调用路径都可能会存在死锁。
感觉这类可能互相调用的业务也不少,这是也分布式必定遇到的问题,怎么才能最大程度的规避这类情况,有通用的处理方式吗?
出现了再热更新修复就行了,实际中哪有那么多,你这是不搞聊天服直接相互call才出现的,实际中有聊天服不会出现这种call
egametang 哦,因为要确定对方收到消息了,才用CallLocationActor的。
那实际聊天服要怎么实现的呢?
15951836388 为啥要确定对方收到消息呢,如果对方不在线呢,发一条message出去就不管了,就好了吧,怎么处理这条message再另外考虑呗
这说起来一下子就说不清楚了
egametang 突然想到邮件、聊天,这类功能,其实对时序没有要求,所以可以不加携程锁、
那是不是可以新加1套的不带携程锁的CallLocationActor CallActor方法,专门用于这些有可能死锁,但是没有时序要求的功能,避免死锁
ET_Newer 因为不在线要存档离线消息,和你那个“在线的帖子”有点类似,你改好了吗?
15951836388 改了一版,不确定效果如何😁,以前没做过服务器,一直做客户端,现在有ET,尝试双端一起弄,我遇到的服务器问题都很基础,因为没有任何服务器经验
其实这种死锁问题都要自己考虑的,框架不可能全部给你搞定的,要转换思路。别在一个方式上死磕,
就像while(true){1}谁都知道会卡死进程,就不会这样写,你这个写法就跟lock里面再写一次lock一样,然后还要求框架考虑这种情况,应该是你自己考虑不能写出这样的逻辑
15951836388 而且猫大不是说了答案了吗
你是因为 A call B,在b的rpcHandler里reply()前又 B call A,把B call A放到replay()之后,不就好了
ET_Newer
我就是在讨论解决方案,没说要框架解决
你说的这种是自锁,1个发起人
我这种时互相锁了,2个发起人。不一样的
一段逻辑A调用B,同时有《另外一段逻辑》发起了B调用A,就会出现A等B,B再等A,此时发生死锁。
15951836388
同时 A call B,B call A 会互相锁吗
A call B锁的是A的Sender,A收到B的消息锁的是A的mailbox
B call A锁的是B的Sender,B收到A的消息锁的是B的mailbox
4把锁都不一样,只有A call B,A的sender被锁,没解锁的情况下再调用A去call其他,后面这次调用才会一直等待吧
当然这是我的肤浅理解,可能我理解错了😁
根本就不是用Actor Location,滥用了。
Long 那用什么?
15951836388 用actor,聊天服
这样用确实会死锁 A客户端发消息给A的Unit,发一条聊天消息给B,等待B返回,注意这时候 A Unit发消息是在 A的消息队列中,它会一直等待聊天消息返回。这个时候B客户端发个消息给B unit要B unit发个聊天消息给A unit。这个时候B unit发消息是在B的消息队列中。这个时候B收到了A的聊天消息,A的聊天消息处理不了,因为要等B发给A的消息处理完成,同样A也处理不了。造成死锁。解决很简单,unit收到客户端来的聊天消息,另外起一个协程去写逻辑发给B就行了,不要在消息handler里面await sendToB,而是在新协程中SendToB
egametang 是这样吗?
是的