netty(十五)负载均衡实践
理论:
https://www.cnblogs.com/silyvin/p/9469754.html

client 与后端之间同样要建立心跳,之所以由proxy发起到后端的tcp连接而不是反过来,是因为保持后端的独立性
参考:https://blog.csdn.net/admin1973/article/details/71424160?utm_source=itdadao&utm_medium=referral
在此基础上,作实践,写一个负载均衡服务
本次作实践,序列号承接 netty(十四)netty client重连模型
主函数:轮询(1分钟)本地配置文件,文件中保存信任的后端服务ip port,两次读取不一致,干掉老的(不再信任的),新增新的
public class ProxyServer {
public static void main(String[] args) throws InterruptedException {
ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
Runnable runnable = new LoadProperty();
scheduledThreadPoolExecutor.scheduleAtFixedRate(runnable, 0, 60, TimeUnit.SECONDS);
}
private static class LoadProperty implements Runnable {
private static Set<String> lastPropertySet = new HashSet<>();
@Override
public void run() {
System.out.println("开始读取配置");
Set<String> thisTime = null;
try {
thisTime = readProperties();
} catch (Exception e) {
e.printStackTrace();
}
Set<String> delSet = getFormer(lastPropertySet, thisTime);
for(String item : delSet) {
System.out.println("***************去除信任服务" + item);
// Client4Reconnect.interrupt(item);
}
Set<String> newSet = getFormer(thisTime, lastPropertySet);
for(String item : newSet) {
System.out.println("***************新增信任服务" + item);
// Client4Reconnect.create(item);
}
lastPropertySet = thisTime;
System.out.println("结束读取配置");
}
}
private static Set<String> readProperties() throws Exception {
InputStreamReader read = null;
Set<String> set = new HashSet<>();
try {
String encoding = "UTF-8";
File file = new File("servers.config");
if (file.isFile() && file.exists()) {
read = new InputStreamReader(new FileInputStream(file), encoding);
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
while ((lineTxt = bufferedReader.readLine()) != null) {
set.add(lineTxt);
}
} else {
throw new Exception("找不到指定的文件");
}
return set;
} catch (Exception e) {
throw new Exception(e);
} finally {
read.close();
}
}
/**
* 返回前者set独有的
* @param former
* @param batter
* @return
*/
private static Set<String> getFormer(Set<String> former, Set<String> batter) {
Set<String> set = new HashSet<>();
for(String item : former) {
if(!batter.contains(item)) {
set.add(item);
}
}
return set;
}
}
首先注释掉真正执行连接的代码:
// Client4Reconnect.interrupt(item);
// Client4Reconnect.create(item);
查看这个轮询读取程序是否ok:
servers配置文件初始:
127.0.0.1:8867
127.0.0.1:8868
127.0.0.1:8866
第2个1分钟
127.0.0.1:8867
127.0.0.1:8868
127.0.0.1:8869
第3个1分钟
127.0.0.1:8867
127.0.0.1:8868
127.0.0.1:8869
127.0.0.1:6666
开始读取配置
***************新增信任服务127.0.0.1:8867
***************新增信任服务127.0.0.1:8868
***************新增信任服务127.0.0.1:8866
结束读取配置
开始读取配置
***************去除信任服务127.0.0.1:8866
***************新增信任服务127.0.0.1:8869
结束读取配置
开始读取配置
***************新增信任服务127.0.0.1:8866
结束读取配置
完成了轮询扫描信任服务清单后,真正连接到后端,方案如下:


代码参见(十四)netty client 重连模型
设计如下的实验:

输出:
开始读取配置
***************新增信任服务127.0.0.1:8867
***************开启信任线程-127.0.0.1:8867:Thread-1
***************新增信任服务127.0.0.1:8868
***************开启信任线程-127.0.0.1:8868:Thread-2
***************新增信任服务127.0.0.1:8866
***************开启信任线程-127.0.0.1:8866:Thread-3
结束读取配置
连接成功-127.0.0.1:8867
--------------新增可用服务127.0.0.1:8867:ALL - [127.0.0.1:8867]
连接成功-127.0.0.1:8866
--------------新增可用服务127.0.0.1:8866:ALL - [127.0.0.1:8867, 127.0.0.1:8866]
连接失败-127.0.0.1:8868
SERVER'S general msg RESPONSE : code: 2
msg: "SERVER:hello"
SERVER'S general msg RESPONSE : code: 2
msg: "SERVER:hello"
重新连接-127.0.0.1:8868
连接失败-127.0.0.1:8868
重新连接-127.0.0.1:8868
连接失败-127.0.0.1:8868
重新连接-127.0.0.1:8868
连接失败-127.0.0.1:8868
重新连接-127.0.0.1:8868
连接失败-127.0.0.1:8868
重新连接-127.0.0.1:8868
连接失败-127.0.0.1:8868
重新连接-127.0.0.1:8868
连接成功-127.0.0.1:8868
--------------新增可用服务127.0.0.1:8868:ALL - [127.0.0.1:8867, 127.0.0.1:8868, 127.0.0.1:8866]
SERVER'S general msg RESPONSE : code: 2
msg: "SERVER:hello"
连接异常中断,重新连接-127.0.0.1:8867
--------------去除可用服务127.0.0.1:8867:ALL - [127.0.0.1:8868, 127.0.0.1:8866]
channelInactive
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
* CLIENT WRITER_IDLE send msg heart_beat...
* CLIENT receive back heart
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
* CLIENT WRITER_IDLE send msg heart_beat...
* CLIENT receive back heart
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
重新连接-127.0.0.1:8867
连接失败-127.0.0.1:8867
开始读取配置
***************去除信任服务127.0.0.1:8867
***************退出信任线程-127.0.0.1:8867:Thread-1
***************去除信任服务127.0.0.1:8868
终止信任,不再重连-127.0.0.1:8867
***************退出信任线程-127.0.0.1:8868:Thread-2
终止信任,断开连接,服务不再启用-127.0.0.1:8868
--------------去除可用服务127.0.0.1:8868:ALL - [127.0.0.1:8866]
***************新增信任服务127.0.0.1:8869
channelInactive
***************开启信任线程-127.0.0.1:8869:Thread-4
结束读取配置
连接成功-127.0.0.1:8869
--------------新增可用服务127.0.0.1:8869:ALL - [127.0.0.1:8866, 127.0.0.1:8869]
SERVER'S general msg RESPONSE : code: 2
msg: "SERVER:hello"
* CLIENT WRITER_IDLE send msg heart_beat...
* CLIENT receive back heart
* CLIENT WRITER_IDLE send msg heart_beat...
* CLIENT receive back heart
* CLIENT WRITER_IDLE send msg heart_beat...
* CLIENT receive back heart
连接异常中断,重新连接-127.0.0.1:8869
channelInactive
--------------去除可用服务127.0.0.1:8869:ALL - [127.0.0.1:8866]
连接失败-127.0.0.1:8869
连接异常中断,重新连接-127.0.0.1:8866
--------------去除可用服务127.0.0.1:8866:ALL - []
channelInactive
连接失败-127.0.0.1:8866
重新连接-127.0.0.1:8869
连接失败-127.0.0.1:8869
重新连接-127.0.0.1:8866
连接失败-127.0.0.1:8866
重新连接-127.0.0.1:8869
连接失败-127.0.0.1:8869
重新连接-127.0.0.1:8866
连接失败-127.0.0.1:8866
重新连接-127.0.0.1:8869
连接失败-127.0.0.1:8869
文件:
链接: https://pan.baidu.com/s/1om4nTH_3tS9utmaO3AI5-w 提取码: fkkg
浙公网安备 33010602011771号