zookeeper(三)---使用zookeeper实现服务的主从选举和哨兵机制
代码:
maven依赖:
<groupId>com.junlaninfo</groupId> <artifactId>sentry</artifactId> <version>1.0-SNAPSHOT</version> <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.properties配置文件,后续步骤会把server.port 改为8080/8081/8082,分别启动,模拟集群的效果
server.port=8082 |
Controller
package com.junlaninfo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by 辉 on 2020/7/4. */ @RestController public class IndexController { @GetMapping("/getInfo") public String getInfo(){ return "当前是否为主节点:"+Sentry.isMaster; } } |
ZookeeperRunner
package com.junlaninfo.controller; 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; /** * Created by 辉 on 2020/7/4. */ @Component public class ZookeeperRunner implements ApplicationRunner { // 创建zk连接 ZkClient zkClient = null; private String path = "/election"; @Value("${server.port}") private String serverPort; @Override public void run(ApplicationArguments applicationArguments) throws Exception { System.out.println("项目已启动就执行这个方法"); zkClient = new ZkClient("192.168.196.175:2181"); createEphemeral(); //尝试创建节点 //创立监听watcher,看节点有无被删除和改变 zkClient.subscribeDataChanges(path, new IZkDataListener() { @Override public void handleDataChange(String s, Object o) throws Exception { } @Override public void handleDataDeleted(String s) throws Exception { // 主节点已经挂了,重新选举 System.out.println("主节点已经挂了,重新开始选举"); createEphemeral(); } }); } private void createEphemeral() { try { zkClient.createEphemeral(path); //创建临时节点 Sentry.isMaster = true; //创建节点要是成功,就把ismaster置为true,创建不成功就会出异常 } catch (Exception e) { Sentry.isMaster = false; } } } |
判断是否为主节点的标识
package com.junlaninfo.controller; import org.springframework.stereotype.Component; /** * Created by 辉 on 2020/7/4. * 这个类主要做一个标识,看它是否为主节点 */ @Component public class Sentry { public static boolean isMaster; } |
启动类
package com.junlaninfo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Created by 辉 on 2020/7/4. */ @SpringBootApplication public class sentryApplication { public static void main(String[] args) { SpringApplication.run(sentryApplication.class); } } |
效果:分别把项目启动为端口号8080 、8081、8082
代码链接:https://github.com/xuexionghui/sentry.git