利用ZooKeeper开发分布式应用系统案例--服务端与客户端实现

利用ZooKeeper开发分布式应用系统案例--服务端与客户端实现

服务端代码:

package cn.edu360.zk.distributesystem;

import java.io.IOException;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class TimeQueryServer {
	 
	ZooKeeper zk = null;
	
	//启动zk客户端连接
    public void connectZK() throws Exception {
    	
    	zk = new ZooKeeper("hadoop1:2181,hadoop2:2181,hadoop3:2181", 2000, null);
    }
	
    //注册服务器信息
    public void registerServerInfo(String hostname,String port) throws Exception, InterruptedException {
    	
    	/*
    	 * 先判断注册节点是否存在,如果不存在,则创建
    	 */
    	
    	Stat stat = zk.exists("/servers", false);
    	if(stat == null) {
    		zk.create("/servers", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    		
    	}
    	
    	//注册服务器数据到zk的约定注册节点下
    	String create = zk.create("/servers/server", (hostname + ":" + port).getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    	
    	System.out.println(hostname + "服务器向zk注册信息成功,注册的节点为:" + create);
    }
    
    
    //启动业务线程开始处理业务
    
    
    
    
	
	public static void main(String[] args) throws Exception, Exception {
		
		TimeQueryServer timeQueryServer = new TimeQueryServer();
		
		//启动zk客户端连接
		timeQueryServer.connectZK();
		//注册服务器信息
		timeQueryServer.registerServerInfo(args[0], args[1]);
		//启动业务线程开始处理业务
		new TimeQueryService(Integer.parseInt(args[1])).start();
		
	}

}

服务端线程代码:

package cn.edu360.zk.distributesystem;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class TimeQueryService extends Thread{
	
	int port = 0;
	
	public TimeQueryService(int port) {
		this.port = port;
	}
	
	
	@Override
	public void run() {
		
		try {
			ServerSocket ss = new ServerSocket(port);
			System.out.println("业务线程已绑定端口"+ port + "准备接受消费端请求了...");
			while(true) {
				Socket sc = ss.accept();
				InputStream inputStream = sc.getInputStream();
				OutputStream outputStream = sc.getOutputStream();
				outputStream.write(new Date().toString().getBytes());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

}

客户端代码:

package cn.edu360.zk.distributesystem;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;

public class Consumer {
	
	//定义一个list用于存放最新的在线服务器列表
	private volatile ArrayList<String> onlineServers = new ArrayList<String>();
	
	
	//构造zk连接对象
    ZooKeeper zk = null;
	
    public void connectZK() throws Exception {
    	
    	zk = new ZooKeeper("hadoop1:2181,hadoop2:2181,hadoop3:2181", 2000, new Watcher() {

			@Override
			public void process(WatchedEvent event) {
				if(event.getState() == KeeperState.SyncConnected && event.getType() == EventType.NodeChildrenChanged) {
					try {
						//事件回调逻辑中,再次查询zk上的在线服务器节点即可,查询逻辑中又再次注册子节点事件监听。
						getOnlineServers();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
				
			}
    		
    	});
    }
	
   //查询在线服务器列表
    
    public void getOnlineServers() throws Exception, InterruptedException {
    	List<String> children = zk.getChildren("/servers", true);
    	ArrayList<String> list = new ArrayList<String>();
    	for (String child : children) {
    		byte[] data = zk.getData("/servers/"+child, false, null);
    		String serverInfo = new String(data);
    		list.add(serverInfo);
			
		}
    	onlineServers = list;
    	System.out.println("查询了一次zk,当前在线的服务器有:"+list);
    }
    
    
    public void sendRequest() throws Exception {
    	
    	Random random = new Random();
    	
    	while(true) {
    		try {
         //挑选一台当前在线的服务器	
    		int nextInt = random.nextInt(onlineServers.size());
    		String server = onlineServers.get(nextInt);
    		String hostname = server.split(":")[0];
    		int port = Integer.parseInt(server.split(":")[1]);
    		
    		
    		System.out.println("本次请求挑选的服务器为:" + server);
    		
    		Socket socket = new Socket(hostname, port);
    		OutputStream outputStream = socket.getOutputStream();
    		outputStream.write("haha".getBytes());
    		outputStream.flush();
    		
    		InputStream inputStream = socket.getInputStream();
    		byte[] buf = new byte[256];
    		int read = inputStream.read(buf);
    		System.out.println("服务器相应的时间为" + new String(buf,0,read));
    		
    		outputStream.close();
    		inputStream.close();
    		
    		socket.close();
    		
    		Thread.sleep(2000);
    		}catch(Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    }
	
	
	public static void main(String[] args) throws Exception {
		Consumer consumer = new Consumer();
		//构造zk连接对象
		consumer.connectZK();
		
		
		//查询在线服务器列表
		consumer.getOnlineServers();
		
		//处理业务(向一台服务器发送时间查询请求)
		
		consumer.sendRequest();
		
	}
	

}

猜你喜欢

转载自blog.csdn.net/RobertDowneyLm/article/details/80345030