【Zookeeper】实现负载均衡原理

        一、思路

        • 使用Zookeeper实现负载均衡原理,服务器端将启动的服务注册到,zk注册中心上,采用临时节点。客户端从zk节点上获取最新服务节点信息,本地使用负载均衡算法,随机分配服务器。
        • 服务端启动的时候 会想注册中心Zookeeper中添加节点,(注意这个节点是临时的,目的是如果服务端关闭连接的时候,该结点会自动删除)
        • 客户端会查询注册中心里面的节点信息,拿到对应的地址和端口号,使用本地负载均衡算法随机 来进行负载均衡
            

        分享图片
        ?

          
         

        二、项目搭建

        2.1 Maven依赖

        • 需要引入zk的客户端依赖
        <dependencies>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.8</version>
            </dependency>
        </dependencies>

        2.1 创建Server服务端

        ZkServerScoekt服务

        public class ZkServerScoekt implements Runnable {
                private static int port = 18081;
        
            public static void main(String[] args) throws IOException {
                ZkServerScoekt server = new ZkServerScoekt(port);
                Thread thread = new Thread(server);
                thread.start();
            }
        
            public ZkServerScoekt(int port) {
                this.port = port;
            }
        
            public void regServer() {
                // 向ZooKeeper注册当前服务器
                ZkClient client = new ZkClient("127.0.0.1:2181", 60000, 1000);
                String path = "/test/server" + port;
                if (client.exists(path))
                    client.delete(path);
                client.createEphemeral(path, "127.0.0.1:" + port);
            }
        
            public void run() {
                ServerSocket serverSocket = null;
                try {
                    serverSocket = new ServerSocket(port);
                    regServer();
                    System.out.println("Server start port:" + port);
                    Socket socket = null;
                    while (true) {
                        socket = serverSocket.accept();
                        new Thread(new ServerHandler(socket)).start();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (serverSocket != null) {
                            serverSocket.close();
                        }
                    } catch (Exception e2) {
        
                    }
                }
            }
        
            }

        ServerHandler

        public class ServerHandler implements Runnable {
            private Socket socket;
        
        public ServerHandler(Socket socket) {
            this.socket = socket;
        }
        
        public void run() {
            BufferedReader in = null;
            PrintWriter out = null;
            try {
                in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
                out = new PrintWriter(this.socket.getOutputStream(), true);
                String body = null;
                while (true) {
                    body = in.readLine();
                    if (body == null)
                        break;
                    System.out.println("Receive : " + body);
                    out.println("Hello, " + body);
                }
        
            } catch (Exception e) {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
                if (out != null) {
                    out.close();
                }
                if (this.socket != null) {
                    try {
                        this.socket.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    this.socket = null;
                }
            }
        }
        }

        2.3 客户端ZkServerClient

        public class ZkServerClient {
            public static List<String> listServer = new ArrayList<String>();
            public static String parent = "/test";
        
            public static void main(String[] args) {
                initServer();
                ZkServerClient client = new ZkServerClient();
                BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
                while (true) {
                    String name;
                    try {
                        name = console.readLine();
                        if ("exit".equals(name)) {
                            System.exit(0);
                        }
                        client.send(name);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        
            // 注册所有server
            public static void initServer() {
                // listServer.add("127.0.0.1:18080");
        
                final ZkClient zkClient = new ZkClient("127.0.0.1:2181", 6000, 1000);
                List<String> children = zkClient.getChildren(parent);
                getChilds(zkClient, children);
                // 监听事件
                zkClient.subscribeChildChanges(parent, new IZkChildListener() {
        
                    public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                        getChilds(zkClient, currentChilds);
                    }
                });
            }
        
            private static void getChilds(ZkClient zkClient, List<String> currentChilds) {
                listServer.clear();
                for (String p : currentChilds) {
                    String pathValue = (String) zkClient.readData(parent + "/" + p);
                    listServer.add(pathValue);
                }
                serverCount = listServer.size();
                System.out.println("从zk读取到信息:" + listServer.toString());
        
            }
        
            // 请求次数
            private static int reqestCount = 1;
            // 服务数量
            private static int serverCount = 0;
        
            // 获取当前server信息
            public static String getServer() {
                // 实现负载均衡
                String serverName = listServer.get(reqestCount % serverCount);
                ++reqestCount;
                return serverName;
            }
        
            public void send(String name) {
        
                String server = ZkServerClient.getServer();
                String[] cfg = server.split(":");
        
                Socket socket = null;
                BufferedReader in = null;
                PrintWriter out = null;
                try {
                    socket = new Socket(cfg[0], Integer.parseInt(cfg[1]));
                    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    out = new PrintWriter(socket.getOutputStream(), true);
        
                    out.println(name);
                    while (true) {
                        String resp = in.readLine();
                        if (resp == null)
                            break;
                        else if (resp.length() > 0) {
                            System.out.println("Receive : " + resp);
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            }
        相关文章
        相关标签/搜索
        每日一句
          每一个你不满意的现在,都有一个你没有努力的曾经。
        公众号推荐
           一个历史类的公众号,欢迎关注
        一两拨千金
        高手论坛免费精选资料