Python中如何实现负载均衡?

https://i.v2ex.co/Cu8woxB3l.jpeg

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。

一、lvs Linux Virtual Server (lvs) 是 Linux 内核自带的负载均衡器,也是目前性能最好的软件负载均衡器之一。

1、转发模式

https://i.v2ex.co/60Te2A6rl.jpeg

2、调度算法

( 1 )轮叫调度( Round-Robin Scheduling )

( 2 )加权轮叫调度( Weighted Round-Robin Scheduling )

( 3 )最小连接调度( Least-Connection Scheduling )

( 4 )加权最小连接调度( Weighted Least-Connection Scheduling )

( 5 )基于局部性的最少链接( Locality-Based Least Connections Scheduling )

( 6 )带复制的基于局部性最少链接( Locality-Based Least Connections with Replication Scheduling )

( 7 )目标地址散列调度( Destination Hashing Scheduling )

( 8 )源地址散列调度( Source Hashing Scheduling )

( 9 )最短预期延时调度( Shortest Expected Delay Scheduling )

( 10 )不排队调度( Never Queue Scheduling )

3、lvs 配置示例

安装 ipvs 包并开启 ip 转发

yum -y install ipvsadm keepalived sysctl -w net.ipv4.ip_forward=1 修改 /etc/keepalived/keepalived.conf,增加 vip 和 lvs 的配置

vrrp_instance VI_3 { state MASTER # 另一节点为 BACKUP interface eth0 virtual_router_id 11 priority 100 # 另一节点为 50 advert_int 1 authentication { auth_type PASS auth_pass PASSWORD }

track_script {
    chk_http_port
}

virtual_ipaddress { 192.168.0.100 }

}

virtual_server 192.168.0.100 9696 { delay_loop 30 lb_algo rr lb_kind DR persistence_timeout 30 protocol TCP

real_server 192.168.0.101 9696 {
    weight 3
    TCP_CHECK {
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 9696
    }
}

real_server 192.168.0.102 9696 { weight 3 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 9696 } }

} 重启 keepalived:

systemctl reload keepalived 最后在 neutron-server 所在机器上为 lo 配置 vip,并抑制 ARP 响应:

vip=192.168.0.100 ifconfig lo:1 ${vip} broadcast ${vip} netmask 255.255.255.255 route add -host ${vip} dev lo:1 echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

4、LVS 缺点

( 1 ) Keepalived 主备模式设备利用率低;不能横向扩展; VRRP 协议,有脑裂的风险。

( 2 ) ECMP 的方式需要了解动态路由协议,LVS 和交换机均需要较复杂配置;交换机的 HASH 算法一般比较简单,增加删除节点会造成 HASH 重分布,可能导致当前 TCP 连接全部中断;部分交换机的 ECMP 在处理分片包时会有 BUG。

二、Haproxy

Haproxy 也是 Linux 最常用的负载均衡软件之一,兼具性能和功能的组合,同时支持 TCP 和 HTTP 负载均衡。

配置和使用方法请见 https://nginx.org/en/。

三、Nginx

Nginx 也是 Linux 最常用的负载均衡软件之一,常用作反向代理和 HTTP 负载均衡(当然也支持 TCP 和 UDP 负载均衡)。

配置和使用方法请见 https://nginx.org/en/。

四、自研负载均衡

1、Google Maglev

Maglev 是 Google 自研的负载均衡方案,在 2008 年就已经开始用于生产环境。Maglev 安装后不需要预热 5 秒内就能处理每秒 100 万次请求。谷歌的性能基准测试中,Maglev 实例运行在一个 8 核 CPU 下,网络吞吐率上限为 12M PPS (数据包每秒)。如果 Maglev 使用 Linux 内核网络堆栈则速度会慢下来,吞吐率小于 4M PPS。

https://i.v2ex.co/gsi6N7Ifl.jpeg

( 1 )路由器 ECMP (Equal Cost Multipath) 转发包到 Maglev (而不是传统的主从结构)

( 2 ) Kernel Bypass, CPU 绑定,共享内存

( 3 )一致性哈希保证连接不中断

2、UCloud Vortex

Vortex 参考了 Maglev,大致的架构和实现跟 Maglev 类似:

( 1 ) ECMP 实现集群的负载均衡

( 2 )一致性哈希保证连接不中断

即使是不同的 Vortex 服务器收到了数据包,仍然能够将该数据包转发到同一台后端服务器

后端服务器变化时,通过连接追踪机制保证当前活动连接的数据包被送往之前选择的服务器,而所有新建连接则会在变化后的服务器集群中进行负载分担

( 3 ) DPDK 提升单机性能 (14M PPS,10G, 64 字节线速)

通过 RSS 直接将网卡队列和 CPU Core 绑定,消除线程的上下文切换带来的开销

Vortex 线程间采用高并发无锁的消息队列通信

( 4 ) DR 模式避免额外开销

五、总结

本文为大家详细讲解了关于 Linux 配置中的负载均衡的装置,适应现代社会的需求, 作为运维工程师的你,学会了吗?


Python中如何实现负载均衡?

7 回复

Haproxy 链接给错了


在Python里实现负载均衡,通常不是自己从头写轮子,而是用现成的库或者结合现有系统。核心思路就一个:把进来的请求,按照某种策略(比如轮询、随机、最少连接数)分发给后端的多个服务器。

这里给你两个最实用的方向:

1. 用现成的反向代理/负载均衡器 这是生产环境的标准做法。比如用 NginxHAProxy。你只需要配置一下upstream,它们就能搞定健康检查、会话保持等复杂功能。Python应用本身是无状态的,跑在多个实例上就行。

2. 在应用层用代码实现简单的客户端负载均衡 如果你需要在Python客户端里自己决定请求发到哪台服务器,可以用一些轻量级库。下面是一个使用 randomrequests 实现随机选择的例子:

import random
import requests

# 假设你有多个后端服务器地址
backend_servers = [
    'http://server1:8000',
    'http://server2:8000',
    'http://server3:8000'
]

def get_random_server():
    """随机选择一个后端服务器"""
    return random.choice(backend_servers)

def make_request(path):
    """向负载均衡后的后端发送请求"""
    server = get_random_server()
    url = f"{server}{path}"
    try:
        response = requests.get(url, timeout=5)
        return response.json()
    except requests.exceptions.RequestException as e:
        # 简单的故障处理:这里可以标记服务器不可用,然后重试其他服务器
        print(f"请求失败 {url}: {e}")
        # 在实际应用中,应该从可用服务器列表中移除故障节点
        return None

# 示例:调用API
if __name__ == "__main__":
    result = make_request("/api/data")
    print(result)

对于更复杂的策略(如加权轮询、最少连接),你可以看看 py负载均衡 这个库,或者用 aiohttpClientSession 配合自定义连接器来实现异步场景下的负载均衡。

总结:生产用Nginx,自己玩可以用库简单实现。

由于一些问题,图片链接没有加载出来,大家可以点开链接查看哦

错误地址

回到顶部