这两天家里新装了一个千兆宽带,因为之前就了解过梅林固件,知道其实路由器也有很多玩法。然后最近不是失业了嘛,就想着可以做一些网络相关的东西,提升一下技术,也顺便丰富一下简历,方便找工作。所以,这里我先试着搞一个智能负载均衡器吧… 目前的想法是写一个专注于流量管理、路由策略优化和网络性能监控的网络编程,比如监控单一宽带连接的网络性能(如延迟、带宽、丢包率等)、实现负载均衡(这里我只有一个宽带,需要模拟多WAN环境)。

Smart_load_balancer

使用 Kratos 框架,实现基础的网络监控和负载均衡功能。Kratos 是 Go 开发的微服务框架,非常适合构建高扩展性和可维护性的项目。

1. Monitor

1.1 ICMP Ping

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
func (m MonitorBiz) Ping(ctx context.Context, address string) (*PingResult, error) {
addr, err := net.ResolveIPAddr("ip4:icmp", address)
if err != nil {
return nil, fmt.Errorf("解析地址失败: %v", err)
}

pinger := fastping.NewPinger()
pinger.AddIPAddr(addr)

resChan := make(chan PingResult, 1)
errChan := make(chan error, 1)
pinger.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
resChan <- PingResult{
Address: addr.String(),
RTT: rtt,
}
}

pinger.OnIdle = func() {
close(resChan)
close(errChan)
}

go func() {
if err := pinger.Run(); err != nil {
errChan <- err
}
}()

select {
case result := <-resChan:
return &result, nil
case err := <-errChan:
return nil, err
case <-ctx.Done():
return nil, ctx.Err()
}
}

这段代码的核心功能是通过发送 ICMP 回显请求(Echo Request)来检测目标地址是否可达,并测量往返时间(RTT)。ICMP(Internet Control Message Protocol) 是网络层协议,用于发送错误消息和操作信息。不过 ICMP 需要管理员权限才能发送报文,因为普通管理员不能创建原始的套接字,可以考虑使用 TCP Ping 代替。TCP Ping 的原理是发送 TCP SYN 数据包(三次握手),等待目标返回 SYN-ACK,测量往返时间(不需要管理员权限)。

1.2 协议的选择(TCP Ping 和 ICMP Ping)

TCP Ping 是传输层协议,IMCP 是网络层协议。如何决定使用什么协议?TCP Ping 适用于判断特定端口(如80、443),不仅能测试网络链路,还能判断服务是否正常运行。ICMP 则是直接测试目标网络的连通性,反映的是底层网络的状态,并且有可能被路由器或防火墙组织。但是相比于 TCP Ping,ICMP 没有额外的开销,且可以检测目标主机的整个网络链路状态,而不仅仅是测试某个端口是否可用。

由于我们实现的 Ping 接口主要功能是对上游路由器的健康监测,检测网络链路的质量和连通性,比如 判断 WAN1 和 WAN2 是否在线。所以我们使用 ICMP Ping。

2. 负载均衡算法

2.1 需求

在网络环境中,特别是多出口路由器或多服务实例的场景中,单一出口或服务的性能瓶颈会限制整个系统的效率和可靠性。例如:

  • 多个广域网(WAN)连接时:
    • 某些出口的延迟较低(如实时流量的视频会议),某些出口的带宽较大(如大流量传输的文件下载),当出现网络故障时,未能及时切换,就会导致用户体验下降。
    • 多后端服务时(虽然不是这次的场景,但是可以适用):
      • 如果没有动态调整流量,可能会导致某些服务实例过载,而其他实例空闲。

负载均衡算法的目的是:

  1. 优化资源利用,充分利用多出口或多服务实例,避免资源浪费。
  2. 提高系统性能,通过动态分配流量,降低延迟,提高吞吐量。
  3. 提升系统可靠性,在某个出口或服务实例出问题时,实现无缝切换,保障用户体验。

结合路由器…(突然接到一个面试通知,我要先去准备面试去了…