使用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);      }    }