+ Arrays.toString(args) + "]";
}
}
创建AddService
package com.chenlei.service;
public interface AddService {
public int add(Integer a, Integer b);
}
创建ProxyUtils(重点)
public class ProxyUtils {
private static Random RDM = new Random();
@SuppressWarnings("unchecked")
public static <T> T getProxy(Class<T> interfaces) {
T proxy = (T) Proxy.newProxyInstance(ProxyUtils.class.getClassLoader(), new Class<?>[] { interfaces },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if ("toString".equals(methodName)) {
return interfaces.getClass().getName() + "$Proxy";
}
if ("hashCode".equals(methodName)) {
return Object.class.hashCode();
}
if ("equals".equals(methodName)) {
return Object.class.equals(this);
}
// 消费者发送过去
Request request = new Request();
request.setInterfaceName(interfaces.getName());
request.setMethodName(methodName);
request.setArgs(args);
// 找到interfaces下的所有节点
List<String> serverList = ZkUtils.discover(interfaces.getName());
String one = randomOne(serverList);// 拿到的结果为ip:port 如127.0.0.1:8888
String[] split = one.split(":");
String address = split[0];
Integer port = Integer.valueOf(split[1]);
Socket socket = null;
// 打开书出管道,发送请求
Object result = null;
OutputStream outputStream = null;
ObjectOutputStream objectOutputStream = null;
InputStream inputStream = null;
ObjectInputStream objectInputStream = null;
try {
socket = new Socket(address, port);
outputStream = socket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(request);
inputStream = socket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
result = objectInputStream.readObject();
System.out.println("本次调用的是======" + port);
} catch (Exception e) {
e.printStackTrace();
} finally {
closeResources(objectInputStream, inputStream, objectOutputStream, outputStream, socket);
}
return result;
}
});
return proxy;
}
/**
* 从节点中随机找出一个
*
* @param serverList
* @return
*/
private static String randomOne(List<String> serverList) {
if (null == serverList || 0 == serverList.size()) {
return null;
}
int index = RDM.nextInt(serverList.size());
return serverList.get(index);
}
/**
* 关闭资源的方法
*/
public static void closeResources(Closeable... resources) {
for (Closeable resource : resources) {
if (null != resource) {
try {
resource.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
resource = null;
}
}
}
}
}
创建ZkUtils(zookeeper注册和发现,另加缓存解决脏读)在API项目中导入zkclient的依赖
public class ZkUtils {
private static final String ZK_URL = "自己的域名:2181";
private static ZkClient zkClient = null;
//创建zookeeper缓存
private static Map<String, List<String>> cache = new HashMap<String, List<String>>();
static {
zkClient = new ZkClient(ZK_URL, 10000, 10000);
}
/**
* 服务节点向zookeeper的注册
*
* @param serverName
* @param serverPort
*/
public static void register(String serverName, String serverPort) {
if (null == serverName || "".equals(serverName)) {
throw new RuntimeException("服务名不能为空");
}
if (null == serverPort || "".equals(serverPort)) {
throw new RuntimeException("服务ip和端口不能为空");
}
if (!zkClient.exists("/" + serverName)) {
zkClient.createPersistent("/" + serverName);
}
if (!zkClient.exists("/" + serverName + "/" + serverPort)) {
zkClient.createEphemeral("/" + serverName + "/" + serverPort);
}
System.out.println("注册一个服务节点为" + "/" + serverName + "/" + serverPort);
}
/**
* 向zookeeper发现服务节点
*
* @param serverName
* @return
*/
public static List<String> discover(String serverName) {
if (null == serverName || "".equals(serverName)) {
throw new RuntimeException("服务名不能为空");
推荐阅读
- 农村远程教育服务茶产业 为百万茶农致富导航
- 安溪,远程教育4+2学用模式助推茶业发展
- java多线程,静态方法加锁后,调用该方法会影响其它方法吗?
- CVE-2019-0193 Apache Solr远程代码执行漏洞 复现操作
- Windows 远程控制 Ubuntu 系统
- Linux Kernel 5.5 最终删除 SYSCTL 系统调用
- 空调清洗主要清洗哪里,空调清洗有必要吗
- 三步排查彻底解决远程桌面连接内部错误问题
- 苹果电脑MAC系统登录远程桌面 如何能够实现?
- 远程访问电脑设置教程
