分布式day10_04-代码实现Master选举策略

本文详细介绍了如何在Spring Boot应用中实现ZooKeeper的选举策略,通过在不同端口启动多个服务器实例,并利用ZooKeeper的临时节点特性进行主从服务器选举。当主服务器意外关闭时,ZooKeeper能自动触发重新选举,确保集群中始终有一个主服务器运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

pom文件

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.10</version>
			<exclusions>
				<exclusion>
					<artifactId>slf4j-api</artifactId>
					<groupId>org.slf4j</groupId>
				</exclusion>
				<exclusion>
					<artifactId>log4j</artifactId>
					<groupId>log4j</groupId>
				</exclusion>
				<exclusion>
					<artifactId>slf4j-log4j12</artifactId>
					<groupId>org.slf4j</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

application.yml文件

IndexController文件

package zk_day_64;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
	
	@Value("${server.port}")
	private String serverPort;
	@RequestMapping("/getServerInfo")
	public String getServerInfo() {
		return "serverPort:" + serverPort + (ElectionMaster.isSurvival ? "选举为主服务器!" : "该服务器为从服务器");
	}
	
	
	public static void main(String[] args) {
		// 1. 项目启动的时候会在zk上创建一个相同的临时节点
		// 2. 谁能够创建成功谁就是为主服务器
		// 3. 使用服务监听节点是否被删除,如果接受到节点被删除的话,重新开始选举(重新开始创建节点)
		
		
	}

}

 ElectionMaster文件

package zk_day_64;

import org.springframework.stereotype.Component;

@Component
public class ElectionMaster {

	// 服务器info信息 是否存活
	public static boolean isSurvival;

}

MyApplicationRunner文件

package zk_day_64;

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationRunner implements ApplicationRunner{

	private ZkClient zkClient = new ZkClient("127.0.0.1:2181");
	private String path = "/election";
	
	@Value("${server.port}")
	private String serverPort;
	
	public void run(ApplicationArguments args) throws Exception {
		System.out.println("项目启动成功");
		// 1.项目启动的时候会在zk上创建一个相同的临时节点
		// 2. 谁能够创建成功谁就是为主服务器
		createEphemeral();
		// 3. 使用服务监听节点是否被删除,如果接受到节点被删除的话,重新开始选举(重新开始创建节点)
		zkClient.subscribeDataChanges(path, new IZkDataListener() {
			
			//节点如果被删除后,返回通知
			public void handleDataDeleted(String dataPath) throws Exception {
				System.out.println("开始重新选举策略");
				createEphemeral();
			}
			
			public void handleDataChange(String dataPath, Object data) throws Exception {
				// TODO Auto-generated method stub
				
			}
		});
		
	}

	private void createEphemeral() {
		try {
			zkClient.createEphemeral(path);
			System.out.println("serverPort:" + serverPort + ",选举成功!!!");
			ElectionMaster.isSurvival = true;
		} catch (Exception e) {
			System.out.println("该节点已经存在");
			ElectionMaster.isSurvival = false;
		}
	}
	
	

}

App文件

package zk_day_64;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
	
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

 分别启动  8080、 8081、 8082 端口的3个服务器

 

现在将8080关闭 (就是将8080端口的红色小正方形点了,强制关闭8080端口)

由于是强制关闭8080,zookeeper节点不会立马消失,会产生延迟,这个时候等待个几十秒就好

几十秒过后,代码上的debug会自动弹出,这个时候就是zookeeper重新选举了

这样就选举成功了

我们现在再重新开启8080端口

8080端口就成为从服务器了

这样就完成了zookeeper的选举策略了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值