使用zookeeper实现服务路由和负载均衡
CheWardill
9年前
来自: http://www.it165.net/admin/html/201501/4737.html
三个类:
ServiceAProvider
ServiceBProvider
ServiceConsumer
其中
ServiceAProvider提供的服务名service-A,指向IP为192.168.58.130
ServiceBProvider提供的服务名service-A,指向IP为192.168.58.131
当有消费者请求时,随机地选取service-A列表的服务器提供服务
ServiceConsumer 为消费者类
依赖:
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.5-cdh5.1.0</version> </dependency> <dependency> <groupId>org.apache.helix</groupId> <artifactId>helix-core</artifactId> <version>0.6.4</version> </dependency>
服务提供者ServiceAProvider类的源码为:
package com.jamesfen.zookeeper; import java.net.InetAddress; import org.I0Itec.zkclient.ZkClient; public class ServiceAProvider { private String serviceName = "service-A"; //向zookeeper注册服务 public void init() throws Exception{ String serverList = "192.168.58.11:2181"; String PATH ="/configcenter";//根节点路径 ZkClient zkClient = new ZkClient(serverList); boolean rootExists = zkClient.exists(PATH); if(!rootExists){ zkClient.createPersistent(PATH); } //判断是否存在,不存在则创建服务节点 boolean serviceExists = zkClient.exists(PATH + "/" + serviceName); if(!serviceExists){ zkClient.createPersistent(PATH + "/" + serviceName); } //註冊當前服務 InetAddress addr =InetAddress.getLocalHost(); //String ip= addr.getHostAddress().toString(); String ip = "192.168.58.130"; //創建當前服務器節點 zkClient.createEphemeral(PATH + "/" + serviceName + "/" + ip); System.out.println("提供的服务节点名称为:"+PATH + "/" + serviceName + "/" + ip); } //提供服务 public void provide(){ } public static void main(String[]args) throws Exception { ServiceAProvider service = new ServiceAProvider(); service.init(); Thread.sleep(1000*60*60*24); } }
服务提供者ServiceBProvider类源码为
package com.jamesfen.zookeeper; import java.net.InetAddress; import org.I0Itec.zkclient.ZkClient; public class ServiceBProvider { //服务名仍然为 A,这样是为了,一个服务名有两个台机器在服务,才能做负载均衡. private String serviceName = "service-A"; //向zookeeper注册服务 public void init() throws Exception{ String serverList = "192.168.58.11:2181"; String PATH ="/configcenter";//根节点路径 ZkClient zkClient = new ZkClient(serverList); boolean rootExists = zkClient.exists(PATH); if(!rootExists){ zkClient.createPersistent(PATH); } boolean serviceExists = zkClient.exists(PATH + "/" + serviceName); if(!serviceExists){ zkClient.createPersistent(PATH + "/" + serviceName);//創建服務節點 } //註冊當前服務 InetAddress addr =InetAddress.getLocalHost(); //String ip= addr.getHostAddress().toString(); String ip = "192.168.58.131"; //創建當前服務器節點 zkClient.createEphemeral(PATH + "/" + serviceName + "/" + ip); System.out.println("提供的服务节点名称为:"+PATH + "/" + serviceName + "/" + ip); } //提供服务 public void provide(){ } public static void main(String[]args) throws Exception { ServiceBProvider service = new ServiceBProvider(); service.init(); Thread.sleep(1000*60*60*24); } }
消费者类源码为:
package com.jamesfen.zookeeper; import java.util.ArrayList; import java.util.List; import java.util.Random; import org.I0Itec.zkclient.IZkChildListener; import org.I0Itec.zkclient.ZkClient; public class ServiceConsumer { private List<String> serverList = new ArrayList<String>(); private String serviceName ="service-A"; //初始化服务地址信息 public void init(){ String zkServerList ="192.168.58.11:2181"; String SERVICE_PATH="/configcenter/"+serviceName;//服务节点路径 ZkClient zkClient = new ZkClient(zkServerList); boolean serviceExists =zkClient.exists(SERVICE_PATH); if(serviceExists){ serverList =zkClient.getChildren(SERVICE_PATH); }else{ throw new RuntimeException("service not exist!"); } //注册事件监听 zkClient.subscribeChildChanges(SERVICE_PATH,new IZkChildListener(){ //@Override public void handleChildChange(String parentPath, List<String> currentChilds)throws Exception{ serverList = currentChilds; } }); } //消费服务 public void consume(){ //通过负责均衡算法,得到一台服务器进行调用 int index = getRandomNum(0,1); System.out.println("调用" + serverList.get(index)+"提供的服务:" + serviceName); } public int getRandomNum(int min,int max){ Random rdm = new Random(); return rdm.nextInt(max-min+1)+min; } public static void main(String[] args)throws Exception { ServiceConsumer consumer = new ServiceConsumer(); consumer.init(); consumer.consume(); Thread.sleep(1000*60*60*24); } }