iRpc进阶之节点扩容

iRpc选举

iRpc项目地址:

  • gitee: https://gitee.com/willbeahero/iRpc
  • github: https://github.com/BrianApple/iRpc

iRpc基于raft选举算法实现服务节点自举,由于iRpc需要集群节点扩容,因此没有直接使用dledger项目作为选举实现框架,不过iRpc在实现选举和节点扩容的过程中,复用了dledger项目相关源代码,并按照iRpc所需做出相关调整,在此再次想dledger项目及作者表示感谢,dledger项目地址为: https://github.com/openmessaging/openmessaging-storage-dledger

iRcp选举过程大致如下(如果想要了解raft算法,请自行查询):

iRpc选举
iRpc实现基本的raft选举代码如下(所有配置信息均可采用javabean或yml配置文件等形式设置):

    /**
     * ABC
     */
    @Test
    public void startCluster1_Node1(){
        IRpcServerProperty serverProperty = new IRpcServerProperty();
        serverProperty.setServerPort("10916");
        serverProperty.setHeartbeat("60");
        serverProperty.setNodeName("n0");
        serverProperty.setGroupName("iRpcGroup");
        List<NodeInfo> lits = new ArrayList<NodeInfo>();
        NodeInfo node1 = new NodeInfo();
        node1.setNode("n0");
        node1.setIp("127.0.0.1");
        node1.setPort("10916");
        lits.add(node1);
        NodeInfo node2 = new NodeInfo();
        node2.setNode("n1");
        node2.setIp("127.0.0.1");
        node2.setPort("10917");
        lits.add(node2);
        NodeInfo node3 = new NodeInfo();
        node3.setNode("n2");
        node3.setIp("127.0.0.1");
        node3.setPort("10918");
        lits.add(node3);
        serverProperty.setClusterNode(lits);;

        new ServerStarter(serverProperty);
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * ABC
     */
    @Test
    public void startCluster1_Node2(){
        IRpcServerProperty serverProperty = new IRpcServerProperty();
        serverProperty.setServerPort("10917");
        serverProperty.setHeartbeat("60");
        serverProperty.setNodeName("n1");
        serverProperty.setGroupName("iRpcGroup");
        List<NodeInfo> lits = new ArrayList<NodeInfo>();
        NodeInfo node1 = new NodeInfo();
        node1.setNode("n0");
        node1.setIp("127.0.0.1");
        node1.setPort("10916");
        lits.add(node1);
        NodeInfo node2 = new NodeInfo();
        node2.setNode("n1");
        node2.setIp("127.0.0.1");
        node2.setPort("10917");
        lits.add(node2);
        NodeInfo node3 = new NodeInfo();
        node3.setNode("n2");
        node3.setIp("127.0.0.1");
        node3.setPort("10918");
        lits.add(node3);
        serverProperty.setClusterNode(lits);;

        new ServerStarter(serverProperty);
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * ABC
     */
    @Test
    public void startCluster1_Node3(){
        IRpcServerProperty serverProperty = new IRpcServerProperty();
        serverProperty.setServerPort("10918");
        serverProperty.setHeartbeat("60");
        serverProperty.setNodeName("n2");
        serverProperty.setGroupName("iRpcGroup");
        List<NodeInfo> lits = new ArrayList<NodeInfo>();
        NodeInfo node1 = new NodeInfo();
        node1.setNode("n0");
        node1.setIp("127.0.0.1");
        node1.setPort("10916");
        lits.add(node1);
        NodeInfo node2 = new NodeInfo();
        node2.setNode("n1");
        node2.setIp("127.0.0.1");
        node2.setPort("10917");
        lits.add(node2);
        NodeInfo node3 = new NodeInfo();
        node3.setNode("n2");
        node3.setIp("127.0.0.1");
        node3.setPort("10918");
        lits.add(node3);
        serverProperty.setClusterNode(lits);

        new ServerStarter(serverProperty);
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

iRpc节点扩容

集群扩容过程中,节点的选举依然基于raft算法,扩容节点和原集群节点的groupName必须一致,且iRpc不支持两个存在leader节点的集群合并扩容——会导致出现双leader情况,导致信息不一致

AB + C(AB) -> ABC 扩容模式

AB基于raft算法自举选出leader,C节点携带原集群所有节点信息且groupName一致,参与集群扩容,选举流程如下:
选举过程
测试代码:

/**
	 * AB
	 */
	@Test
	public void startNode1(){
		IRpcServerProperty serverProperty = new IRpcServerProperty();
		serverProperty.setServerPort("10916");
		serverProperty.setHeartbeat("60");
		serverProperty.setNodeName("n0");
		serverProperty.setGroupName("iRpcGroup");
		List<NodeInfo> lits = new ArrayList<NodeInfo>();
		NodeInfo node1 = new NodeInfo();
		node1.setNode("n0");
		node1.setIp("127.0.0.1");
		node1.setPort("10916");
		lits.add(node1);
		NodeInfo node2 = new NodeInfo();
		node2.setNode("n1");
		node2.setIp("127.0.0.1");
		node2.setPort("10917");
		lits.add(node2);
		serverProperty.setClusterNode(lits);;
		
		new ServerStarter(serverProperty);
		try {
			Thread.sleep(Integer.MAX_VALUE);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * AB
	 */
	@Test
	public void startNode2(){
		IRpcServerProperty serverProperty = new IRpcServerProperty();
		serverProperty.setServerPort("10917");
		serverProperty.setHeartbeat("60");
		serverProperty.setNodeName("n1");
		serverProperty.setGroupName("iRpcGroup");
		List<NodeInfo> lits = new ArrayList<NodeInfo>();
		NodeInfo node1 = new NodeInfo();
		node1.setNode("n0");
		node1.setIp("127.0.0.1");
		node1.setPort("10916");
		lits.add(node1);
		NodeInfo node2 = new NodeInfo();
		node2.setNode("n1");
		node2.setIp("127.0.0.1");
		node2.setPort("10917");
		lits.add(node2);
		serverProperty.setClusterNode(lits);;
		
		new ServerStarter(serverProperty);
		try {
			Thread.sleep(Integer.MAX_VALUE);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * ABC
	 */
	@Test
	public void startNode3(){
		IRpcServerProperty serverProperty = new IRpcServerProperty();
		serverProperty.setServerPort("10918");
		serverProperty.setHeartbeat("60");
		serverProperty.setNodeName("n2");
		serverProperty.setGroupName("iRpcGroup");
		List<NodeInfo> lits = new ArrayList<NodeInfo>();
		NodeInfo node1 = new NodeInfo();
		node1.setNode("n0");
		node1.setIp("127.0.0.1");
		node1.setPort("10916");
		lits.add(node1);
		NodeInfo node2 = new NodeInfo();
		node2.setNode("n1");
		node2.setIp("127.0.0.1");
		node2.setPort("10917");
		lits.add(node2);
		NodeInfo node3 = new NodeInfo();
		node3.setNode("n2");
		node3.setIp("127.0.0.1");
		node3.setPort("10918");
		lits.add(node3);
		serverProperty.setClusterNode(lits);;
		
		new ServerStarter(serverProperty);
		try {
			Thread.sleep(Integer.MAX_VALUE);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
AB + C(A) 或 AB + C(B) -> ABC 扩容模式

AB基于raft算法自举选出leader,C节点只携带AB集群中的一部分节点信息参与扩容,最终达成选举一致,如下为AB + C(A)扩容的流程:
AB + C(A)
相关测试代码如下:

    /**
     * AB
     */
    @Test
    public void startCluster1_Node1(){
        IRpcServerProperty serverProperty = new IRpcServerProperty();
        serverProperty.setServerPort("10916");
        serverProperty.setHeartbeat("60");
        serverProperty.setNodeName("n0");
        serverProperty.setGroupName("iRpcGroup");
        List<NodeInfo> lits = new ArrayList<NodeInfo>();
        NodeInfo node1 = new NodeInfo();
        node1.setNode("n0");
        node1.setIp("127.0.0.1");
        node1.setPort("10916");
        lits.add(node1);
        NodeInfo node2 = new NodeInfo();
        node2.setNode("n1");
        node2.setIp("127.0.0.1");
        node2.setPort("10917");
        lits.add(node2);
        serverProperty.setClusterNode(lits);;

        new ServerStarter(serverProperty);
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * AB
     */
    @Test
    public void startCluster1_Node2(){
        IRpcServerProperty serverProperty = new IRpcServerProperty();
        serverProperty.setServerPort("10917");
        serverProperty.setHeartbeat("60");
        serverProperty.setNodeName("n1");
        serverProperty.setGroupName("iRpcGroup");
        List<NodeInfo> lits = new ArrayList<NodeInfo>();
        NodeInfo node1 = new NodeInfo();
        node1.setNode("n0");
        node1.setIp("127.0.0.1");
        node1.setPort("10916");
        lits.add(node1);
        NodeInfo node2 = new NodeInfo();
        node2.setNode("n1");
        node2.setIp("127.0.0.1");
        node2.setPort("10917");
        lits.add(node2);
        serverProperty.setClusterNode(lits);;

        new ServerStarter(serverProperty);
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * AC
     */
    @Test
    public void startCluster1_Node3(){
        IRpcServerProperty serverProperty = new IRpcServerProperty();
        serverProperty.setServerPort("10918");
        serverProperty.setHeartbeat("60");
        serverProperty.setNodeName("n2");
        serverProperty.setGroupName("iRpcGroup");
        List<NodeInfo> lits = new ArrayList<NodeInfo>();
        NodeInfo node1 = new NodeInfo();
        node1.setNode("n1");
        node1.setIp("127.0.0.1");
        node1.setPort("10917");
        lits.add(node1);
        NodeInfo node2 = new NodeInfo();
        node2.setNode("n2");
        node2.setIp("127.0.0.1");
        node2.setPort("10918");
        lits.add(node2);
        serverProperty.setClusterNode(lits);;

        new ServerStarter(serverProperty);
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

总结

综上,iRpc既可以基于raft算法实现iRpc节点的自举,又在raft选举算法框架下实现了iRpc服务节点的动态扩容模式,是的iRpc服务节点部署的灵活性大大加强,能够满足更多的业务场景需求!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

於之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值