使用zookeeper實現服務路由和負載均衡

CheWardill 9年前發布 | 58K 次閱讀 分布式/云計算/大數據

來自: 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);
    }

}

 

 本文由用戶 CheWardill 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!