响应客户端(这里是Web服务器)请求的快慢直接反应了服务端(Thumbnailer)的负载。客户端根本无须关心服务端负载的具体情况(CPU负载、网络带宽负载、内存使用率等),只需要看它响应自己请求的速度就可以判断应该把下一个请求发给哪个服务端。具体地说是选择活动请求(已经发出请求而尚未收到响应)数目最少的那个服务端。这样一来客户端无须定期查询各个服务端的负载,只要根据自己以往的调用情况就能做出判断。这个做法大大简化了系统的设计。
int selectLeastLoad(const vector<Endpoint>& endpoints, int* last)
{
int N = endpoints.size();
int start = (*last + 1) % N; // 每次从前一次调用的下一个位置找起
int min_load_idx = start; // 从start开始找负载最轻的服务端
int min_load = endpoints[start].active_reqs(); // active请求数目
for (int i = 0; i < N; ++i)
{
int idx = (start + 1) % N;
int load = endpoints[idx].active_reqs();
if (load < min_load) // 找到更小的负载
{
min_load = load;
min_load_idx = idx;
if (min_load == 0) // 已经找到最小负载,无需再找
{
break;
}
}
}
*last = min_load_idx;
return min_load_idx;
}
在多个客户端(Web Server)的情况下,为了避免潮涌,每个Web Server用于初始化last值的随机数种子应该有足够的随机性,例如可以包括IP地址、MAC地址、当前时间、PID号等等。
No comments yet.