【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();
}
}
}
}
}
【Zookeeper】实现负载均衡原理的更多相关文章
- Zookeeper实现负载均衡原理
先玩个正常的,好玩的socket编程: 服务端: 首先公共的这个Handler: package com.toov5.zkDubbo; import java.io.BufferedReader; i ...
- 使用Zookeeper实现负载均衡原理
思路 使用Zookeeper实现负载均衡原理,服务器端将启动的服务注册到,zk注册中心上,采用临时节点.客户端从zk节点上获取最新服务节点信息,本地使用负载均衡算法,随机分配服务器. 创建项目工程 M ...
- 六大Web负载均衡原理与实现
还有个姊妹篇也可以参考这个文章:LVS(Linus Virtual Server):三种负载均衡方式比较+另三种负载均衡方式, LVS 实现了负载均衡,NAT,DR,TUN zookeeper使用ZA ...
- Nginx 负载均衡原理简介与负载均衡配置详解
Nginx负载均衡原理简介与负载均衡配置详解 by:授客 QQ:1033553122 测试环境 nginx-1.10.0 负载均衡原理 客户端向反向代理发送请求,接着反向代理根据某种负载机制 ...
- 搞懂分布式技术9:Nginx负载均衡原理与实践
搞懂分布式技术9:Nginx负载均衡原理与实践 本篇摘自<亿级流量网站架构核心技术>第二章 Nginx负载均衡与反向代理 部分内容. 当我们的应用单实例不能支撑用户请求时,此时就需要扩容, ...
- (转)使用LVS实现负载均衡原理及安装配置详解
使用LVS实现负载均衡原理及安装配置详解 原文:https://www.cnblogs.com/liwei0526vip/p/6370103.html
- LVS实现负载均衡原理及安装配置
LVS实现负载均衡原理及安装配置 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F ...
- LVS实现负载均衡原理及安装配置 负载均衡
LVS实现负载均衡原理及安装配置 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F ...
- 使用ZooKeeper实现软负载均衡(原理)
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,提供的功能包括配置维护.名字服务.分布式同步.组服务等. ZooKeeper会维护一个树形的数据结构,类似于Windows资源管理器 ...
随机推荐
- 使用 Sublime + PlantUML 高效地画图
转自 http://www.jianshu.com/p/e92a52770832
- node.js写巨大的xlsx
一般用node-xlsx写xlsx文件的话局要把数据全部放在内存里面再写到文件里,如果文件很大的话就会导致内存吃不消. 可以使用PySpreadsheet这个npm库,他支持写很大的文件. PySpr ...
- Python3之高阶函数sorted
排序算法 Python内置的sorted()函数可以对list进行排序 >>> sorted([36,5,-12,9,-21]) [-21, -12, 5, 9, 36] 此外,so ...
- iOS-UITextField的使用
UITextField UITextField * accountField = [[UITextField alloc] initWithFrame:CGRectMake(85.0f, 60.0f ...
- iOS-MJRefresh框架
1.用MJRefresh框架实现上下拉刷新 1.1 如何使用这个框架,只需要告诉控件的scrollView是谁,就能将框架添加到我们的滚动视图中了 // 下拉刷新 MJRefreshHeaderVie ...
- MySQL“Another MySQL daemon already running with the same unix socket”的处理
方法一: rm var/lib/mysql/mysql.sock service mysqld start 方法二: mv /var/lib/mysql/mysql.sock /var/lib/mys ...
- 关于opencv的几个小总结
关于opencv的几个小总结 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:opencv是一个非常好用的开源图像处理与计算机视觉支持库,但是在实际使用 ...
- IBM.WMQ订阅主题,连续获取消息解决办法
去队列里面一直获取消息,一开始想到了两种解决方案: 第一:订阅一次获取一次消息,正常的话每次都能获取到,但是要及时去清理订阅并且时间粒度不好控制 第二:订阅一次,再获取消息这里加死循环,超时MQ已经做 ...
- 最新 字节跳动java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.字节跳动等10家互联网公司的校招Offer,因为某些自身原因最终选择了字节跳动.6.7月主要是做系统复习.项目复盘.Leet ...
- 【链接】js监听input输入框内容变化
https://blog.csdn.net/idomyway/article/details/79078625 $("#input1").bind("input prop ...