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的选举策略了