江湖车侠|的自实现高可用方案,妙妙妙,PowerJob( 二 )


分组隔离其实根据前面遇到的问题 , 这一套机制的雏形也差不多出来了 。
server既然需要持有某一个分组下完整的集群信息 , 那么可以顺其自然的想到 , 能不能让某一个分组的所有worker都连接到某一台server呢?一旦某个分组下所有机器全部连接到了某一台server , 那么其实这就形成了一个小型的子系统 。 虽然整个PowerJob系统中存在着多台server和多个worker集群 , 但是对于这个分组的运行来说 , 只要有这个分组对应的worker集群以及它们连接的那一台server就够了 。 那么在这个小型“子系统”内部 , 只存在着一台server , 也就不存在重复调度问题了(server只调度连接到它的AppName下面的任务就能实现这一点) 。
所以 , 经过一层层的剥丝抽茧 , 问题已经转化为了:如何让某个分组下的所有机器都连接到同一台server上去呢?
看到这个问题的时候 , 相信很多人会有和我当时一样的想法 , 那就是:就这?
“配置一个IP怎么做高可用 , 怎么利用多台server资源?”
“好像有点道理 , 那就hash(appName)取余作为下标 , 这样就能保证同一个同一个分组下所有机器的初始IP相同 , 不同分组也能连接到不同的server”
“那 , 万一连接的server挂了怎么办?”
“这好办 , 可以采取类似于解决哈希冲突的那个什么开放定址法 , 从挂掉的server下标开始 , 依次向后重试就行了 , 同一个分组集群内所有的机器都从某个下标依次向后重试 , 还是能连接到同一台server的”
“好像很有道理 , 哼 , worker选主也就不过如此 , 方案搞定 , 英雄联盟启动!”
正当我浴血奋战直指敌将首级时 , 画面...永远定格在了见血前的那一瞬 。 “正在尝试重新连接”几个大字映入眼帘 , 也把我带入了深深的沉思 。
嗯?自己的原因?网络波动?掉线?重连?这一连串词汇 , 把我拉回了刚刚设计的方案之中 , 然后给我当头一棒 。 一旦worker因为自己的网络波动导致它以为server不可用 , 而重新连接另一台server , 就会导致所有worker都连接同一台server这个约束被破坏......因此 , 这个方案自然也就是一个充满漏洞的不可行方案 。
其实这段经历现在回过头来想特别搞笑 , 也有被自己蠢到 。 那无数个方案的失败原因其实都是同一个 , 也就是出发点错了 。 我一直在尝试让worker决定连接哪台server , 却一而再再而三忽略worker永远不可能获取server真正的存活信息(比如心跳无法传达 , 可能是worker本身的网络故障) , 因此worker不应该决定连接哪台server , 这应该由server来决定 。 worker能做的 , 只有服务发现 。 想明白了这点 , 具体的方案也就应运而生了 。
PS:这个方案的诞生 , 我大概付出了1斤脑细胞的代价(不得不说这个减肥方法还蛮好的)...脑细胞不能白死 , 尽管那些奇奇怪怪得方案没有活到正式版本 , 但没有他们就无法通往真理的大门 。 为了表达纪念和“哀悼”之情 , 我将最终的设计命名为——V4:丧钟为谁鸣 。


推荐阅读