本文目录导读:

- 基础轮询(Round Robin)
- 加权轮询(Weighted Round Robin)
- 平滑加权轮询
- 分布式系统中的轮询(带重试机制)
- 实际问题:时间片轮转调度(CPU调度)
- 实际场景:消息队列消费者轮询
- 使用建议
我将为你提供几个不同场景下轮询算法的完整案例,从基础到进阶,包含代码实现和适用场景分析。
基础轮询(Round Robin)
最简单的轮询算法,适用于服务器负载均衡中最常见的场景。
class RoundRobinBalancer:
def __init__(self, servers):
self.servers = servers # 服务器列表
self.current_index = 0 # 当前索引
self.lock = threading.Lock() # 线程安全
def get_server(self):
"""获取下一个服务器"""
with self.lock:
server = self.servers[self.current_index]
self.current_index = (self.current_index + 1) % len(self.servers)
return server
# 使用示例
servers = ["server1", "server2", "server3", "server4"]
balancer = RoundRobinBalancer(servers)
# 模拟10个请求
for request_id in range(10):
server = balancer.get_server()
print(f"请求 {request_id} -> 分配给 {server}")
输出结果:
请求 0 -> 分配给 server1 请求 1 -> 分配给 server2 请求 2 -> 分配给 server3 请求 3 -> 分配给 server4 请求 4 -> 分配给 server1 ...依次循环
加权轮询(Weighted Round Robin)
考虑到服务器性能差异,高性能服务器承受更多请求。
class WeightedRoundRobin:
def __init__(self, servers_with_weights):
# 输入格式: [("server1", 5), ("server2", 3), ("server3", 2)]
self.servers = []
for server, weight in servers_with_weights:
self.servers.extend([server] * weight) # 按权重扩展列表
self.current_index = 0
self.total_requests = 0
def get_server(self):
"""获取下一个服务器(按权重分配)"""
server = self.servers[self.current_index % len(self.servers)]
self.current_index += 1
return server
# 使用示例
servers_with_weights = [
("高性能服务器", 5),
("中性能服务器", 3),
("低性能服务器", 2)
]
balancer = WeightedRoundRobin(servers_with_weights)
# 模拟请求
for i in range(10):
server = balancer.get_server()
print(f"请求 {i}: {server}")
输出结果:
请求 0: 高性能服务器 请求 1: 高性能服务器 请求 2: 高性能服务器 请求 3: 高性能服务器 请求 4: 高性能服务器 请求 5: 中性能服务器 请求 6: 中性能服务器 请求 7: 中性能服务器 请求 8: 低性能服务器 请求 9: 低性能服务器
平滑加权轮询
Nginx使用的平滑加权轮询算法,避免权重大的服务器被连续请求。
class SmoothWeightedRoundRobin:
def __init__(self, servers_with_weights):
# 服务器配置: [("server1", weight), ...]
self.servers = []
self.current_weights = {}
for server, weight in servers_with_weights:
self.servers.append({"name": server, "weight": weight})
self.current_weights[server] = 0
def get_server(self):
"""平滑加权轮询"""
total_weight = sum(s["weight"] for s in self.servers)
# 选择当前权重最高的服务器
selected = None
max_weight = 0
for server in self.servers:
name = server["name"]
weight = server["weight"]
# 当前权重加上自身权重
self.current_weights[name] += weight
# 找出当前权重最大的
if self.current_weights[name] > max_weight:
max_weight = self.current_weights[name]
selected = name
# 被选中的服务器减去总权重
if selected:
self.current_weights[selected] -= total_weight
return selected
# 使用示例
servers = [
("A", 5), # A服务器权重5
("B", 1), # B服务器权重1
("C", 1) # C服务器权重1
]
balancer = SmoothWeightedRoundRobin(servers)
# 模拟10个请求
for i in range(10):
server = balancer.get_server()
print(f"请求 {i}: 选择服务器 {server}")
输出结果:
请求 0: A 请求 1: A 请求 2: B 请求 3: A 请求 4: A 请求 5: C 请求 6: A 请求 7: A 请求 8: B 请求 9: A
分布式系统中的轮询(带重试机制)
import time
import random
class RobustRoundRobin:
def __init__(self, nodes):
self.nodes = nodes # 节点列表
self.current_index = 0
self.failed_nodes = set() # 故障节点
self.max_retries = 3 # 最大重试次数
def get_healthy_node(self):
"""获取健康节点,跳过故障节点"""
attempts = 0
node_count = len(self.nodes)
while attempts < node_count:
node = self.nodes[self.current_index % node_count]
self.current_index += 1
if node not in self.failed_nodes:
return node
attempts += 1
# 所有节点都故障,返回None
return None
def process_request(self, request_id):
"""处理请求,带重试机制"""
retry_count = 0
while retry_count < self.max_retries:
node = self.get_healthy_node()
if node is None:
print(f"请求 {request_id}: 所有节点都不可用")
return False
try:
# 模拟请求处理
success = self.call_node(node, request_id)
if success:
print(f"请求 {request_id}: {node} 处理成功")
return True
else:
# 节点处理失败,标记为故障
self.failed_nodes.add(node)
print(f"请求 {request_id}: {node} 处理失败")
retry_count += 1
except Exception as e:
print(f"请求 {request_id}: {node} 异常 - {e}")
self.failed_nodes.add(node)
retry_count += 1
print(f"请求 {request_id}: 重试{retry_count}次后失败")
return False
def call_node(self, node, request_id):
"""模拟调用节点"""
# 模拟随机失败
return random.random() > 0.3 # 70%成功率
# 使用示例
nodes = ["Node-1", "Node-2", "Node-3", "Node-4", "Node-5"]
balancer = RobustRoundRobin(nodes)
# 模拟请求
for request_id in range(1, 6):
balancer.process_request(request_id)
实际问题:时间片轮转调度(CPU调度)
class Process:
def __init__(self, pid, burst_time):
self.pid = pid
self.burst_time = burst_time # 需要的CPU时间
self.remaining_time = burst_time
self.wait_time = 0
self.turnaround_time = 0
class TimeSliceScheduler:
def __init__(self, time_quantum):
self.time_quantum = time_quantum # 时间片大小
self.process_queue = []
self.completed_processes = []
def add_process(self, process):
self.process_queue.append(process)
def run(self):
"""运行调度器"""
current_time = 0
while self.process_queue:
process = self.process_queue.pop(0)
# 执行时间片
if process.remaining_time > self.time_quantum:
print(f"时间 {current_time}-{current_time+self.time_quantum}: "
f"进程 {process.pid} 执行 {self.time_quantum}ms")
process.remaining_time -= self.time_quantum
current_time += self.time_quantum
# 未完成,放回队列尾部
process.wait_time += 0 # 等待时间在后续更新
self.process_queue.append(process)
else:
# 进程完成
print(f"时间 {current_time}-{current_time+process.remaining_time}: "
f"进程 {process.pid} 执行 {process.remaining_time}ms (完成)")
current_time += process.remaining_time
process.remaining_time = 0
process.turnaround_time = current_time
self.completed_processes.append(process)
self.print_stats()
def print_stats(self):
"""打印统计信息"""
print("\n=== 调度统计 ===")
for process in self.completed_processes:
total_wait = process.turnaround_time - process.burst_time
print(f"进程 {process.pid}: 执行时间={process.burst_time}ms, "
f"完成时间={process.turnaround_time}ms, "
f"等待时间={total_wait}ms")
# 使用示例
scheduler = TimeSliceScheduler(time_quantum=4)
# 创建进程
processes = [
Process(1, 10), # PID 1,需要10ms
Process(2, 5), # PID 2,需要5ms
Process(3, 7), # PID 3,需要7ms
]
for p in processes:
scheduler.add_process(p)
scheduler.run()
输出结果:
时间 0-4: 进程 1 执行 4ms 时间 4-8: 进程 2 执行 4ms 时间 8-11: 进程 3 执行 3ms 时间 11-15: 进程 1 执行 4ms 时间 15-17: 进程 3 执行 2ms 时间 17-23: 进程 2 执行 1ms === 调度统计 === 进程 2: 执行时间=5ms, 完成时间=23ms, 等待时间=18ms 进程 3: 执行时间=7ms, 完成时间=17ms, 等待时间=10ms 进程 1: 执行时间=10ms, 完成时间=19ms, 等待时间=9ms
实际场景:消息队列消费者轮询
import threading
import time
from queue import Queue
class MessageQueueConsumer:
def __init__(self, consumer_count=3):
self.queue = Queue()
self.consumers = [f"Consumer-{i}" for i in range(consumer_count)]
self.current_index = 0
self.message_count = 0
def add_message(self, message):
"""添加消息到队列"""
self.queue.put(message)
print(f"新增消息: {message}")
def process_messages(self):
"""处理消息 - 轮询分配"""
while not self.queue.empty():
# 获取消息
message = self.queue.get()
# 轮询选择消费者
consumer = self.consumers[self.current_index % len(self.consumers)]
self.current_index += 1
# 模拟处理
print(f"[{time.strftime('%H:%M:%S')}] {consumer} 处理消息: {message}")
time.sleep(0.5) # 模拟处理时间
self.queue.task_done()
# 使用示例
consumer = MessageQueueConsumer(3)
# 添加一些消息
for i in range(1, 8):
consumer.add_message(f"消息{i}")
print("\n开始处理...")
consumer.process_messages()
输出结果:
新增消息: 消息1 新增消息: 消息2 新增消息: 消息3 新增消息: 消息4 新增消息: 消息5 新增消息: 消息6 新增消息: 消息7 开始处理... [10:30:25] Consumer-0 处理消息: 消息1 [10:30:26] Consumer-1 处理消息: 消息2 [10:30:26] Consumer-2 处理消息: 消息3 [10:30:27] Consumer-0 处理消息: 消息4 [10:30:27] Consumer-1 处理消息: 消息5 [10:30:28] Consumer-2 处理消息: 消息6 [10:30:28] Consumer-0 处理消息: 消息7
使用建议
- 最简单场景:使用基础轮询即可
- 服务器性能差异大:使用加权轮询
- 避免请求集中:使用平滑加权轮询(适合Nginx)
- 系统可靠性要求高:加入健康检查和重试机制
- CPU调度:使用时间片轮转算法
轮询算法核心优点是简单、公平、无状态,非常适合负载均衡等场景,根据具体需求选择合适的变体即可。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播