Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例

Zookeeper基于tomcat服务器(Valve)Master选举实例

环境准备

eclipse环境,使用tomcat8.5和tomcat9作为服务器,两个服务器中选一个作为master,zookeeper-3.4.10
在eclipse上部署两个服务器详见https://blog.csdn.net/SUNBOYmxbsH/article/details/78824963
Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第1张图片

创建maven项目,导入pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <groupId>ai.zixinggroupId>
  <artifactId>zkDemoartifactId>
  <version>0.0.1-SNAPSHOTversion>
  <name>zkDemoname>
  <description>zk-testdescription>
  
  	<properties>
		<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
		<spring.version>4.3.8.RELEASEspring.version>
	properties>
  
  <dependencies>
	<dependency>
			<groupId>junitgroupId>
			<artifactId>junitartifactId>
			<version>4.12version>
			<scope>testscope>
		dependency>

		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-coreartifactId>
			<version>${spring.version}version>
		dependency>
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-beansartifactId>
			<version>${spring.version}version>
		dependency>
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-jdbcartifactId>
			<version>${spring.version}version>
		dependency>
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-contextartifactId>
			<version>${spring.version}version>
		dependency>
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-webartifactId>
			<version>${spring.version}version>
		dependency>
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-webmvcartifactId>
			<version>${spring.version}version>
		dependency>
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-testartifactId>
			<version>${spring.version}version>
		dependency>

		<dependency>
			<groupId>org.apache.zookeepergroupId>
			<artifactId>zookeeperartifactId>
			<version>3.4.10version>
		dependency>
		<dependency>
			<groupId>com.101tecgroupId>
			<artifactId>zkclientartifactId>
			<version>0.10version>
		dependency>
		<dependency>
			<groupId>org.apache.curatorgroupId>
			<artifactId>curator-frameworkartifactId>
			<version>4.0.0version>
		dependency>
		<dependency>
			<groupId>org.apache.curatorgroupId>
			<artifactId>curator-recipesartifactId>
			<version>4.0.0version>
		dependency>


		<dependency>
			<groupId>com.zaxxergroupId>
			<artifactId>HikariCPartifactId>
			<version>2.7.1version>
		dependency>
		<dependency>
			<groupId>mysqlgroupId>
			<artifactId>mysql-connector-javaartifactId>
			<version>5.1.41version>
		dependency>


		<dependency>
			<groupId>com.fasterxml.jackson.coregroupId>
			<artifactId>jackson-coreartifactId>
			<version>2.9.1version>
		dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.coregroupId>
			<artifactId>jackson-databindartifactId>
			<version>2.9.1version>
		dependency>

		<dependency>
			<groupId>javax.servletgroupId>
			<artifactId>jstlartifactId>
			<version>1.2version>
		dependency>

		<dependency>
			<groupId>org.slf4jgroupId>
			<artifactId>slf4j-apiartifactId>
			<version>1.7.25version>
		dependency>
		<dependency>
			<groupId>org.slf4jgroupId>
			<artifactId>jcl-over-slf4jartifactId>
			<version>1.7.25version>
		dependency>
		<dependency>
			<groupId>log4jgroupId>
			<artifactId>log4jartifactId>
			<version>1.2.17version>
		dependency>
		<dependency>
		    <groupId>commons-codecgroupId>
		    <artifactId>commons-codecartifactId>
		    <version>1.11version>
		dependency>
  dependencies>
  
  <build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.pluginsgroupId>
				<artifactId>maven-compiler-pluginartifactId>
				<version>3.5.1version>
				<configuration>
					<source>1.8source>
					<target>1.8target>
					<encoding>UTF-8encoding>
				configuration>
			plugin>
			<plugin>
				<groupId>org.xolstice.maven.pluginsgroupId>
				<artifactId>protobuf-maven-pluginartifactId>
				<version>0.5.0version>
				<configuration>
					<protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}protocArtifact>
					<pluginId>grpc-javapluginId>
					<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}pluginArtifact>
				configuration>
				<executions>
					<execution>
						<goals>
							<goal>compilegoal>
							<goal>compile-customgoal>
						goals>
					execution>
				executions>
			plugin>
		plugins>
	build>
project>

编写测试类

package ai.zixing;

import java.io.IOException;

import javax.servlet.ServletException;

import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent.Type;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;

public class ZkTomcatValve extends ValveBase {

	// Curator 访问ZK的实例
	private static CuratorFramework client;

	// 实例化Curator的Watcher(小宫女:监视皇帝)
	private static TreeCache treeCache;

	// zookeeper临时节点用来进行master选举(传国玉玺,谁拿到谁就是皇帝)
	private final static String path = "/Tomcat/ActiveLock";

	// 服务器名称(两个皇子:tomcat8.5和tomcat9)
	private String serverName;

	@Override
	public void invoke(Request request, Response response) throws IOException, ServletException {

		// 初始化Curator客户端连接
		client = CuratorFrameworkFactory.builder().connectString("xx.xx.xx.xx:2181")
				.connectionTimeoutMs(3000).retryPolicy(new ExponentialBackoffRetry(1000, 3))
				.build();
		client.start();

		// 创建临时节点的过程,谁创建成功谁就是master,拿到玉玺继承皇位
		try {
			createNode(path);
		} catch (Exception e) {
			System.out.println("======== 夺位失败,对皇帝进行监控");
			try {
				// 派出小宫女去监视现在的皇帝
				addZKNodeListener(path);
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}

	}

	// 不是master就去监听master。派个小宫女去监视皇位
	private void addZKNodeListener(String path) throws Exception {
		// 实例化Curator的Watcher
		treeCache = new TreeCache(client, path);
		// 启动Watcher
		treeCache.start();

		// 添加节点监听
		treeCache.getListenable().addListener(new TreeCacheListener() {
			@Override
			public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
				if (event != null && event.getType() == Type.NODE_REMOVED) {
					System.out.println("======== 皇帝(master)挂了,起义夺权");
					createNode(path);
				}
			}
		});

		System.out.println("======== 已经派出间谍监视皇位");
	}

	private void createNode(String path) throws Exception {
		client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
		System.out.println("======== 创建节点成功" + serverName + " 成为皇帝");

	}

	public String getServerName() {
		return serverName;
	}

	public void setServerName(String serverName) {
		this.serverName = serverName;
	}
}

说明:

侵入式tomcat服务器,需要继承ValveBase类,并重写invoke(),需要导入tomcat的jar依赖
Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第2张图片

运行方式(两个tomcat都要操作)

1. 配置tomcat,在server.xml中添加如下标签


 <Valve className="ai.zixing.ZkTomcatValve" serverName="tomcat8.5"/>

Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第3张图片
将项目打成jar包放入tomcat的lib目录下

2. 将项目添加到tomcat中

Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第4张图片

3. 由于是侵入tomcat方式,所以还需要将zookeeper,Curator等jar包放入tomcat的lib目录下,不然会报错,导致tomcat启动不了。

Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第5张图片
具体估计需要这几个jar包把,可以根据报错信息找,至于jar怎么找?在你maven仓库找就可以了。
Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第6张图片Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第7张图片

进行测试

分别启动tomcat8.5和tomcat9.0
Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第8张图片
Zookeeper使用Curator基于tomcat服务器侵入式Master选举实例_第9张图片

你可能感兴趣的:(Java代码)