Ngnix基础加权轮询负载均衡算法
-
Ngnix基础加权负载均衡算法(Weighted Round
Robin)是通过为每台后端服务器配置不同的权重值来实现请求的按比例分配。其核心思想是:权重越高的服务器,接收到的请求越多,从而更合理地利用服务器资源。 -
配置权重:在 upstream 块中定义后端服务器时,使用 weight 参数指定每台服务器的权重。
例如:yamlupstream backend { server 192.168.0.14:80 weight=5; server 192.168.0.15:80 weight=10; }
在这个例子中,服务器 192.168.0.15 的权重是 10,而 192.168.0.14 的权重是 5。这意味着在长期运行中,大约有 2/3 的请求会被转发到权重为 10 的服务器上,而 1/3 的请求则被转发到权重为 5 的服务器上。
- 算法原理:
- Nginx 会为每台服务器维护一个当前权重(current_weight)和配置权重(weight)。
- 每次有新请求到来时,Nginx 会遍历所有服务器,累加它们的当前权重。 然后选择当前权重总和最大的服务器来处理请求。
- 处理完请求后,该服务器的当前权重会减去所有服务器的配置权重总和,然后重新计算,直到下一次请求到来
- 动态调整:当服务器宕机或恢复时,Nginx 会自动调整其状态,并在服务器恢复后重新参与负载均衡。
通过这种方式,Nginx 能够根据服务器的性能差异进行智能调度,使得高性能服务器承担更多请求,从而优化整体系统的资源利用率。
C++实现的基础加权轮询负载均衡算法
cpp
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
struct Server {
std::string name;
int weight;
int currentWeight;
Server(const std::string& n, int w) : name(n), weight(w), currentWeight(0) {}
};
class WeightedRoundRobin
{
private:
std::vector<Server> servers;
int totalWeight;
public:
WeightedRoundRobin(const std::vector<std::pair<std::string, int>>& serverList)
{
for (const auto& server : serverList)
{
servers.emplace_back(server.first, server.second);
}
totalWeight = std::accumulate(serverList.begin(), serverList.end(), 0,
[](int sum, const std::pair<std::string, int>& s) {
return sum + s.second;
});
}
std::string getNextServer()
{
int maxWeight = -1;
int selectedIdx = -1;
for (size_t i = 0; i < servers.size(); ++i)
{
servers[i].currentWeight += servers[i].weight;
if (servers[i].currentWeight > maxWeight)
{
maxWeight = servers[i].currentWeight;
selectedIdx = static_cast<int>(i);
}
}
if (selectedIdx != -1)
{
servers[selectedIdx].currentWeight -= totalWeight;
return servers[selectedIdx].name;
}
return ""; // Should not happen
}
void printServerStatus() const
{
std::cout << "当前服务器状态:\n";
for (const auto& server : servers)
{
std::cout << " " << server.name << " - 权重: " << server.weight
<< ", 当前权重: " << server.currentWeight << "\n";
}
std::cout << "总权重: " << totalWeight << "\n\n";
}
};
int main()
{
// 定义服务器及其权重
std::vector<std::pair<std::string, int>> serverList =
{
{"ServerA", 5},
{"ServerB", 10},
{"ServerC", 15}
};
// 创建负载均衡器
WeightedRoundRobin lb(serverList);
std::cout << "加权轮询负载均衡算法演示\n";
std::cout << "========================\n\n";
// 显示初始状态
lb.printServerStatus();
// 模拟请求分发
std::cout << "请求分发结果:\n";
for (int i = 1; i <= 15; ++i)
{
std::string server = lb.getNextServer();
std::cout << "请求 " << i << ": 分配到 " << server << "\n";
// 每5个请求显示一次状态
if (i % 5 == 0) {
std::cout << "\n";
lb.printServerStatus();
}
}
return 0;
}
bash
[banting@localhost test]$ g++ -g -std=c++11 test1.cpp -o test1
[banting@localhost test]$ ./test1
加权轮询负载均衡算法演示
========================
当前服务器状态:
ServerA - 权重: 5, 当前权重: 0
ServerB - 权重: 10, 当前权重: 0
ServerC - 权重: 15, 当前权重: 0
总权重: 30
请求分发结果:
请求 1: 分配到 ServerC
请求 2: 分配到 ServerB
请求 3: 分配到 ServerA
请求 4: 分配到 ServerC
请求 5: 分配到 ServerB
当前服务器状态:
ServerA - 权重: 5, 当前权重: -5
ServerB - 权重: 10, 当前权重: -10
ServerC - 权重: 15, 当前权重: 15
总权重: 30
请求 6: 分配到 ServerC
请求 7: 分配到 ServerC
请求 8: 分配到 ServerB
请求 9: 分配到 ServerA
请求 10: 分配到 ServerC
当前服务器状态:
ServerA - 权重: 5, 当前权重: -10
ServerB - 权重: 10, 当前权重: 10
ServerC - 权重: 15, 当前权重: 0
总权重: 30
请求 11: 分配到 ServerB
请求 12: 分配到 ServerC
请求 13: 分配到 ServerC
请求 14: 分配到 ServerB
请求 15: 分配到 ServerA
当前服务器状态:
ServerA - 权重: 5, 当前权重: -15
ServerB - 权重: 10, 当前权重: 0
ServerC - 权重: 15, 当前权重: 15
总权重: 30