All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wowtools.rmi.RmiClient Maven / Gradle / Ivy

The newest version!
package org.wowtools.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

public class RmiClient {

	public static class ZkServiceGetter {
		private static final HashMap zkuMap = new HashMap<>();
		private static final Random r = new Random();
		private final String zkPath;
		private final String name;
		private String[] serviceUrls;
		private T[] services;

		@SuppressWarnings("unchecked")
		private ZkServiceGetter(String zkUrl, String name) {
			this.name = name;
			ZookeeperUtil zku;
			synchronized (zkuMap) {
				zku = zkuMap.get(zkUrl);
				if (null == zku) {
					zku = new ZookeeperUtil(zkUrl, null);
					zkuMap.put(zkUrl, zku);
				}
			}
			final ZookeeperUtil zku1 = zku;
			Watcher watcher = new Watcher() {
				@Override
				public void process(WatchedEvent event) {
					if (event.getType() == Event.EventType.NodeChildrenChanged) {
						List nodeList = zku1.watchChildren(zkPath, this);
						serviceUrls = toServiceUrls(zku1.getZk(), nodeList);
						services = (T[]) new Object[serviceUrls.length];
					}
				}

			};
			zkPath = RmiPublisher.ZK_REGISTRY_PATH + "/" + name;
			List nodeList = zku.watchChildren(zkPath, watcher);
			serviceUrls = toServiceUrls(zku.getZk(), nodeList);
			services = (T[]) new Object[serviceUrls.length];
		}

		private String[] toServiceUrls(ZooKeeper zk, List nodeList) {
			try {
				String[] urls = new String[nodeList.size()];
				int i = 0;
				for (String node : nodeList) {
					byte[] data = zk.getData(zkPath + "/" + node, false, null);
					urls[i] = new String(data);
					i++;
				}
				return urls;
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}

		public T getService() {
			// 取缓存服务
			if (services != null && services.length > 0) {
				int i = r.nextInt(serviceUrls.length);
				T res = services[i];
				if (res != null) {
					return res;
				}
			}
			// 没取到则取远程服务
			if (serviceUrls == null || serviceUrls.length == 0) {
				throw new RuntimeException("暂无可用服务:" + zkPath);
			}
			int i = r.nextInt(serviceUrls.length);
			String url = serviceUrls[i];
			T res = RmiClient.getService(url, name);
			services[i] = res;
			return res;
		}
	}

	/**
	 * 获取一个远程service实例
	 * 
	 * @param serviceUrl
	 *            远程service ip:url
	 * @param name
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static  T getService(String serviceUrl, String name) {
		String url = "rmi://" + serviceUrl + "/" + name;
		try {
			return (T) Naming.lookup(url);
		} catch (MalformedURLException | RemoteException | NotBoundException e) {
			throw new RuntimeException(e);
		}
	}

	public static  ZkServiceGetter getServiceGetter(String zkUrl, String name) {
		ZkServiceGetter getter = new ZkServiceGetter<>(zkUrl, name);
		return getter;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy