【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资源管理器 ...
随机推荐
- Node.js使用ftp连接远程ftp服务器枚举和下载文件示例
示例代码: var Ftp = require('ftp'); var fs = require('fs'); var path = require('path'); // 首先判断参数中是否包含{d ...
- LODOP中纸张高度不定超文本和纯文本对比
关于纸张高度不定的小票打印,建议使用纯文本进行设计,避免纸张高度引起变形,或超文本解析差异造成一些影响:LODOP纸张高度不定的纯文本累计高度 上面的链接的博文里,纯文本可通过间距和高度值累计,得出最 ...
- JS 回车提交,兼容IE、火狐、Opera、Chrome、Safari……
1.JavaScript 方法: <script> document.onkeydown=function(event){ e = event ? event ...
- swift ClassNameFromString 的替换方法 + 创建TableviewHelper
1. ClassNameFromString 的方法oc 可以正常使用,但是swift 不能直接使用的,下面的代码 func getAPPName() -> String?{ let nameK ...
- 解决kalilinux:“下列签名无效: KEYEXPIRED 1425567400"
Kali linux由于太长时间未更新,而出现GPG错误 KEYEXPIRED 1425567400.经检查源未出现问题可以解析,deb也不冲突,就是密钥过期了. 解决方式 使用一条命令,添加新的密钥 ...
- 股票PE的应用
投资股票前,需要先分析公司,然后做估值.最后拿这估值对比现在它的现价,如果现价远低于估值,那就买入,因为这时候相当于打折价. 分析要怎么分析,估值要怎么估值 就像拿不同的旋头去维修不同的电器是一样的原 ...
- 人工智能_2_特征处理.py
# 特征处理 # 特征预处理:通过统计方法将数据转换为算法需要的数据 # 数值型数据:标准缩放 # 规依法,标准化(常用,适用于当前大数据),缺失值处理(删除,填补中位数平均数,通常按照列填补) # ...
- php实现支付宝在线支付和扫码支付demo
### php实现支付宝在线支付和扫码支付demo 背景:在做一个公众号时增加了h5端,需要接入支付,非微信环境,选择了支付宝,以下简单记录下实现过程,并做了简单的封装,拿来即可使用,注意:本项目只是 ...
- consul 初体验
consul server: 192.168.48.134: #!/bin/bash cd /data/server/consuls nohup /data/server/consuls/consul ...
- MySQL explain功能展示的各种信息的解释
1.id: MySQL Query Optimizer 选定的执行计划中查询的序列号. 2.select_type: 所使用的查询类型,主要有以下这几种查询类型. DEPENDENT SUBQUER ...