使用zookeeper实现集群和负载均衡

来源:互联网 发布:如何开好淘宝直通车 编辑:程序博客网 时间:2024/05/22 17:45
[html] view plaincopy
  1. package com.bubble.cluster;  
  2.   
  3. import java.net.InetSocketAddress;  
  4. import java.util.List;  
  5. import java.util.Random;  
  6. import java.util.concurrent.Executors;  
  7.   
  8. import org.I0Itec.zkclient.IZkChildListener;  
  9. import org.I0Itec.zkclient.ZkClient;  
  10. import org.jboss.netty.bootstrap.ClientBootstrap;  
  11. import org.jboss.netty.channel.ChannelFactory;  
  12. import org.jboss.netty.channel.ChannelPipeline;  
  13. import org.jboss.netty.channel.ChannelPipelineFactory;  
  14. import org.jboss.netty.channel.Channels;  
  15. import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;  
  16. import org.jboss.netty.handler.codec.string.StringDecoder;  
  17. import org.jboss.netty.handler.codec.string.StringEncoder;  
  18.   
  19. /**  
  20.  * @author hxpwangyi@163.com  
  21.  * @date 2013-2-10  
  22.  */  
  23. public class Client extends ClusterClient {  
  24.     private static String appServer;  
  25.     private static String zkServer = "127.0.0.1:2181";  
  26.     private static ClientBootstrap bootstrap;  
  27.     private static Client client;  
  28.   
  29.     public static void main(String[] args) throws Exception {  
  30.   
  31.         ChannelFactory factory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());  
  32.         bootstrap = new ClientBootstrap(factory);  
  33.         bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  34.             public ChannelPipeline getPipeline() {  
  35.                 ChannelPipeline pipeline = Channels.pipeline();  
  36.                 pipeline.addLast("encode", new StringEncoder());  
  37.                 pipeline.addLast("decode", new StringDecoder());  
  38.                 pipeline.addLast("handler", new DemoHandler());  
  39.                 return pipeline;  
  40.             }  
  41.         });  
  42.         bootstrap.setOption("tcpNoDelay", true);  
  43.         bootstrap.setOption("keepAlive", true);  
  44.         client=new Client();  
  45.         ZkClient zkClient = new ZkClient(zkServer);  
  46.         client.connect(zkClient);  
  47.           
  48.         client.failOver();  
  49.     }  
  50.   
  51.     @Override  
  52.     public void connect(ZkClient zkClient) {  
  53.         while (true) {  
  54.             try {  
  55.                 RoundRobinLoadBalance loadBlance = new RoundRobinLoadBalance();  
  56.                 //loadBlance.SetClient("127.0.0.1:"+new Random().nextInt(1000));  
  57.                 String server = loadBlance.select(zkServer);  
  58.                 if (server != null) {  
  59.                     String ip = server.split(":")[0];  
  60.                     int port = Integer.parseInt(server.split(":")[1]);  
  61.                     appServer = server;  
  62.                     System.out.println(server);  
  63.                     bootstrap.connect(new InetSocketAddress(ip, port));  
  64.                       
  65.                     client.setZkClient(zkClient);  
  66.                     client.join( "127.0.0.1:"+new Random().nextInt(5000));  
  67.                     ZookeeperConnStatistic.incrementConn(zkServer, appServer);  
  68.                     break;  
  69.                 }  
  70.                 Thread.sleep(1000);  
  71.   
  72.             } catch (Exception e) {  
  73.                 e.printStackTrace();  
  74.                 try {  
  75.                     Thread.sleep(1000);  
  76.                 } catch (InterruptedException e1) {  
  77.   
  78.                 }  
  79.                 connect(zkClient);  
  80.             }  
  81.         }  
  82.   
  83.     }<pre name="code" class="html">package com.bubble.cluster;  
  84.   
  85. import java.util.List;  
  86.   
  87. import org.I0Itec.zkclient.IZkChildListener;  
  88. import org.I0Itec.zkclient.ZkClient;  
  89.   
  90. /**  
  91.  * @author hxpwangyi@163.com  
  92.  * @date 2013-2-11  
  93.  */  
  94. public abstract class ClusterClient {  
  95.     public abstract void connect(ZkClient zkClient);  
  96.     public abstract String getAPPServer();  
  97.     public void setZkClient(ZkClient zkClient){  
  98.         this.zkClient=zkClient;  
  99.     }  
  100.     private ZkClient zkClient;  
  101.   
  102.     public void failOver() {  
  103.         zkClient.subscribeChildChanges(Constant.root, new IZkChildListener() {  
  104.             @Override  
  105.             public void handleChildChange(String parentPath, List currentChilds) throws Exception {  
  106.                 boolean has = false;  
  107.                 for (int i = 0; i < currentChilds.size(); i++) {  
  108.                     if (getAPPServer().equals(currentChilds.get(i))) {  
  109.                         has = true;  
  110.                         break;  
  111.                     }  
  112.                 }  
  113.                 if (!has) {  
  114.                     connect(zkClient);  
  115.                 }  
  116.             }  
  117.         });  
  118.     }  
  119.       
  120.     public void join(String client){  
  121.         if(!zkClient.exists(Constant.client)){  
  122.             zkClient.createPersistent(Constant.client);  
  123.         }  
  124.         if(!zkClient.exists(Constant.client+"/"+client)){  
  125.             zkClient.createEphemeral(Constant.client+"/"+client);  
  126.         }  
  127.     }  
  128.       
  129.     public void leave(String client){         
  130.         if(zkClient.exists(Constant.client+"/"+client)){  
  131.             zkClient.delete(Constant.client+"/"+client);  
  132.         }  
  133.         zkClient.close();  
  134.     }  
  135. }</pre><br>  
  136. <pre name="code" class="html">package com.bubble.cluster;  
  137.   
  138. import java.io.UnsupportedEncodingException;  
  139. import java.security.MessageDigest;  
  140. import java.security.NoSuchAlgorithmException;  
  141. import java.util.List;  
  142.   
  143. import org.I0Itec.zkclient.ZkClient;  
  144.   
  145. /**  
  146.  * @author hxpwangyi@163.com  
  147.  * @date 2013-2-11  
  148.  */  
  149. public class ConsistentHashLoadBalance implements LoadBlance {  
  150.     private String client;  
  151.       
  152.     public void SetClient(String client){  
  153.         this.client=client;  
  154.     }  
  155.       
  156.     @Override  
  157.     public String select(String zkServer) {  
  158.         ZkClient zkClient = new ZkClient(zkServer);  
  159.         List<String> serverList = zkClient.getChildren(Constant.root);  
  160.         ConsistentHashSelector selector=new ConsistentHashSelector(client,serverList);  
  161.         return selector.select();  
  162.           
  163.     }  
  164.       
  165.      private static final class ConsistentHashSelector {  
  166.             public ConsistentHashSelector(String client,List<String> appServer){  
  167.                 this.client=client;  
  168.                 this.appServer=appServer;  
  169.             }  
  170.            
  171.             private String client;  
  172.             private List<String> appServer;  
  173.               
  174.             public String select() {  
  175.                 String key =client ;  
  176.                 byte[] digest = md5(key);  
  177.                 String server =appServer.get((int) hash(digest, 0));  
  178.                 return server;  
  179.             }  
  180.   
  181.             private long hash(byte[] digest, int number) {  
  182.                 return (((long) (digest[3 + number * 4] & 0xFF) << 24)  
  183.                         | ((long) (digest[2 + number * 4] & 0xFF) << 16)  
  184.                         | ((long) (digest[1 + number * 4] & 0xFF) << 8)   
  185.                         | (digest[0 + number * 4] & 0xFF))   
  186.                         & 0xFFFFFFFFL;  
  187.             }  
  188.   
  189.             private byte[] md5(String value) {  
  190.                 MessageDigest md5;  
  191.                 try {  
  192.                     md5 = MessageDigest.getInstance("MD5");  
  193.                 } catch (NoSuchAlgorithmException e) {  
  194.                     throw new IllegalStateException(e.getMessage(), e);  
  195.                 }  
  196.                 md5.reset();  
  197.                 byte[] bytes = null;  
  198.                 try {  
  199.                     bytes = value.getBytes("UTF-8");  
  200.                 } catch (UnsupportedEncodingException e) {  
  201.                     throw new IllegalStateException(e.getMessage(), e);  
  202.                 }  
  203.                 md5.update(bytes);  
  204.                 return md5.digest();  
  205.             }  
  206.   
  207.         }  
  208.   
  209. }  
  210. </pre><br>  
  211. <pre name="code" class="html">package com.bubble.cluster;  
  212. /**  
  213.  * @author hxpwangyi@163.com  
  214.  * @date 2013-2-11  
  215.  */  
  216. public class Constant {  
  217.     public static final String root="/cluster";  
  218.     public static final String round="/round";  
  219.     public static final String client="/client";  
  220.     public static final String route="/route";  
  221. }  
  222. </pre><br>  
  223. <pre name="code" class="html">package com.bubble.cluster;  
  224.   
  225. import java.util.Date;  
  226.   
  227. import org.jboss.netty.channel.ChannelHandlerContext;  
  228. import org.jboss.netty.channel.ChannelStateEvent;  
  229. import org.jboss.netty.channel.MessageEvent;  
  230. import org.jboss.netty.channel.SimpleChannelUpstreamHandler;  
  231.   
  232. /**  
  233.  * @author hxpwangyi@163.com  
  234.  * @date 2013-2-10  
  235.  */  
  236. public class DemoHandler extends SimpleChannelUpstreamHandler {  
  237.   
  238.     @Override  
  239.     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {  
  240.         Thread.sleep(5000);  
  241.         System.out.println(e.getMessage());  
  242.         ctx.getChannel().write("bbb");  
  243.     }  
  244.     @Override  
  245.     public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {  
  246.         e.getChannel().write("abcd");  
  247.     }  
  248.   
  249.   
  250. }  
  251. </pre><br>  
  252. <pre name="code" class="html">package com.bubble.cluster;  
  253.   
  254. import java.util.List;  
  255.   
  256. import org.I0Itec.zkclient.ZkClient;  
  257.   
  258. /**  
  259.  * @author hxpwangyi@163.com  
  260.  * @date 2013-2-11  
  261.  */  
  262. public class LeastActiveLoadBalance implements LoadBlance {  
  263.   
  264.     @Override  
  265.     public String select(String zkServer) {  
  266.         ZkClient zkClient = new ZkClient(zkServer);  
  267.         List<String> serverList = zkClient.getChildren(Constant.root);  
  268.   
  269.         String tempServer = null;  
  270.         int tempConn = -1;  
  271.         for (int i = 0; i < serverList.size(); i++) {  
  272.             String server = serverList.get(i);  
  273.             if (zkClient.readData(Constant.root + "/" + server) != null) {  
  274.                 int connNum = zkClient.readData(Constant.root + "/" + server);  
  275.                 if (tempConn == -1) {  
  276.                     tempServer = server;  
  277.                     tempConn = connNum;  
  278.                 }  
  279.                 if (connNum < tempConn) {  
  280.                     tempServer = server;  
  281.                     tempConn = connNum;  
  282.                 }  
  283.             }else{  
  284.                 zkClient.close();  
  285.                 return server;  
  286.             }  
  287.         }  
  288.         zkClient.close();  
  289.         if (tempServer != null && !tempServer.equals("")) {  
  290.             return tempServer;  
  291.         }  
  292.   
  293.         return null;  
  294.     }  
  295.   
  296. }  
  297. </pre><br>  
  298. <pre name="code" class="html">package com.bubble.cluster;  
  299.   
  300. import java.util.List;  
  301.   
  302. /**  
  303.  * @author hxpwangyi@163.com  
  304.  * @date 2013-2-11  
  305.  */  
  306. public interface LoadBlance {  
  307.     String select(String zkServer);  
  308. }  
  309. </pre><br>  
  310. <pre name="code" class="html">package com.bubble.cluster;  
  311.   
  312. import java.util.List;  
  313. import java.util.Random;  
  314.   
  315. import org.I0Itec.zkclient.ZkClient;  
  316.   
  317. /**  
  318.  * @author hxpwangyi@163.com  
  319.  * @date 2013-2-11  
  320.  */  
  321. public class RandomLoadBalance implements LoadBlance {  
  322.   
  323.     @Override  
  324.     public String select(String zkServer) {  
  325.         ZkClient zkClient = new ZkClient(zkServer);  
  326.         List<String> serverList = zkClient.getChildren(Constant.root);  
  327.         zkClient.close();  
  328.         Random r=new Random();  
  329.         if(serverList.size()>=1){  
  330.             String server=serverList.get(r.nextInt(serverList.size()));  
  331.             return server;  
  332.         }else{  
  333.             return null;  
  334.         }  
  335.           
  336.     }  
  337.   
  338. }  
  339. </pre><br>  
  340. <pre name="code" class="html">package com.bubble.cluster;  
  341.   
  342. import java.util.List;  
  343. import java.util.concurrent.atomic.AtomicInteger;  
  344.   
  345. import org.I0Itec.zkclient.ZkClient;  
  346.   
  347. /**  
  348.  * @author hxpwangyi@163.com  
  349.  * @date 2013-2-11  
  350.  */  
  351. public class RoundRobinLoadBalance implements LoadBlance {  
  352.       
  353.     @Override  
  354.     public String select(String zkServer) {  
  355.         ZkClient zkClient = new ZkClient(zkServer);  
  356.         List<String> serverList = zkClient.getChildren(Constant.root);  
  357.         int round=0;  
  358.         if(!zkClient.exists(Constant.round)){  
  359.             zkClient.createPersistent(Constant.round);  
  360.             zkClient.writeData(Constant.round, 0);  
  361.         }else{  
  362.             round=(Integer)zkClient.readData(Constant.round);  
  363.             zkClient.writeData(Constant.round, ++round);  
  364.         }  
  365.         zkClient.close();  
  366.         if (serverList != null && serverList.size() > 0) {  
  367.             return serverList.get(round % serverList.size());  
  368.         } else {  
  369.             return null;  
  370.         }  
  371.   
  372.     }  
  373.   
  374. }  
  375. </pre><br>  
  376. <pre name="code" class="html">package com.bubble.cluster;  
  377.   
  378. import java.net.InetSocketAddress;  
  379. import java.util.concurrent.Executors;  
  380.   
  381. import org.I0Itec.zkclient.ZkClient;  
  382. import org.apache.zookeeper.Watcher.Event.KeeperState;  
  383. import org.jboss.netty.bootstrap.ServerBootstrap;  
  384. import org.jboss.netty.channel.ChannelFactory;  
  385. import org.jboss.netty.channel.ChannelPipeline;  
  386. import org.jboss.netty.channel.ChannelPipelineFactory;  
  387. import org.jboss.netty.channel.Channels;  
  388. import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;  
  389. import org.jboss.netty.handler.codec.string.StringDecoder;  
  390. import org.jboss.netty.handler.codec.string.StringEncoder;  
  391.   
  392. /**  
  393.  * @author hxpwangyi@163.com  
  394.  * @date 2013-2-10  
  395.  */  
  396. public class Server {  
  397.   
  398.     /**  
  399.      * @param args  
  400.      */  
  401.     public static void main(String[] args) {  
  402.         ChannelFactory factory = new NioServerSocketChannelFactory(  
  403.                 Executors.newCachedThreadPool(),  
  404.                 Executors.newCachedThreadPool());  
  405.             ServerBootstrap bootstrap = new ServerBootstrap (factory);  
  406.             bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  407.                 public ChannelPipeline getPipeline() {  
  408.                      ChannelPipeline pipeline = Channels.pipeline();  
  409.                     pipeline.addLast("encode",new StringEncoder());  
  410.                     pipeline.addLast("decode",new StringDecoder());  
  411.                     pipeline.addLast("handler",new DemoHandler());  
  412.                     return pipeline;  
  413.                 }  
  414.             });  
  415.             bootstrap.setOption("child.tcpNoDelay", true);  
  416.             bootstrap.setOption("child.keepAlive", true);  
  417.             bootstrap.bind(new InetSocketAddress(8081));  
  418.               
  419.             ClusterServer.join("127.0.0.1:8081", "127.0.0.1:2181");  
  420.     }  
  421.   
  422. }  
  423. </pre><br>  
  424. <pre name="code" class="html">package com.bubble.cluster;  
  425.   
  426. import java.util.List;  
  427.   
  428. import org.I0Itec.zkclient.ZkClient;  
  429.   
  430. /**  
  431.  * @author hxpwangyi@163.com  
  432.  * @date 2013-2-11  
  433.  */  
  434. public class ZookeeperConnStatistic {  
  435.     public static void incrementConn(String zkServer,String appServer){  
  436.         ZkClient zkClient = new ZkClient(zkServer);  
  437.         List<String> serverList = zkClient.getChildren(Constant.root);  
  438.         for(int i=0;i<serverList.size();i++){  
  439.             String server=serverList.get(i);  
  440.             if(server.equals(appServer)){  
  441.                 if(zkClient.readData(Constant.root+"/"+appServer)==null){  
  442.                     zkClient.writeData(Constant.root+"/"+appServer, 1);   
  443.                 }else{  
  444.                     int conn=zkClient.readData(Constant.root+"/"+appServer);  
  445.                     zkClient.writeData(Constant.root+"/"+appServer, ++conn);  
  446.                 }  
  447.                 break;  
  448.             }  
  449.         }  
  450.         zkClient.close();  
  451.     }  
  452.       
  453.     public static int getNodeConn(String zkServer,String appServer){  
  454.         ZkClient zkClient = new ZkClient(zkServer);  
  455.         List<String> serverList = zkClient.getChildren(Constant.root);  
  456.         for(int i=0;i<serverList.size();i++){  
  457.             String server=serverList.get(i);  
  458.             if(server.equals(appServer)){  
  459.                 int conn=zkClient.readData(Constant.root+"/"+appServer);  
  460.                 zkClient.close();  
  461.                 return conn;  
  462.             }  
  463.         }  
  464.         zkClient.close();  
  465.         return 0;  
  466.     }  
  467. }  
  468. </pre><br>  
  469. @Overridepublic String getAPPServer() {return appServer;}}  
  470. <pre></pre>  
  471. <br>  
0 0
原创粉丝点击