【发布时间】:2017-08-03 11:21:58
【问题描述】:
我想编写一个简单的负载均衡器。
假设,我有两台服务器运行完全相同的 web 服务。负载均衡器需要知道最近在每台服务器上调用了多少次 web 服务。下层调用的服务器会被推荐给客户端使用。
webservice 可以被多个客户端同时调用。
我需要一种方法来计算一个方法在最后一分钟被调用了多少次。 最好不要使用任何锁来阻塞并发调用,也不要使用太多内存。调用方法的次数不一定要准确。
【问题讨论】:
我想编写一个简单的负载均衡器。
假设,我有两台服务器运行完全相同的 web 服务。负载均衡器需要知道最近在每台服务器上调用了多少次 web 服务。下层调用的服务器会被推荐给客户端使用。
webservice 可以被多个客户端同时调用。
我需要一种方法来计算一个方法在最后一分钟被调用了多少次。 最好不要使用任何锁来阻塞并发调用,也不要使用太多内存。调用方法的次数不一定要准确。
【问题讨论】:
那么,单线程异步 io(即 node.js 或 twisted/tornado?)负载均衡器将路由请求,同时保持必要的计数(不需要锁)?在我们传递请求时更新单个计数都应该是快速的“非阻塞”操作。
这两个库基本上都是 io 多路复用工具,它们充分利用单个线程而不是创建多个线程。鉴于网络应用程序的大部分运行时都在等待 i/o,单线程在 i/o 到来时执行其他代码的能力使其能够匹配或超过多线程服务器的性能。它使用 epoll/select 之类的 os 函数来执行此操作。好处之一是不需要同步。
tornado (python) 和 node.js 中代理的一些相当少的工作示例: https://codeforgeek.com/2015/12/reverse-proxy-using-expressjs/ https://gist.github.com/netdesign/1267537/635425784393fc8397fb928d1e573e4495696d82
要使用移动总计,您需要定义一个窗口(窗口中定义的每个时段的估计调用次数)。
那么(伪代码):
var server1sum = 0,
server2sum = 0,
routes = [],
window = <number of requests to keep>;
function route(request):
if server1sum < server2sum :
route_request(server1)
routes.push(1)
server1sum += 1
else :
route_request(server2)
routes.push(2)
server2sum += 1
while routes.length > window :
x = routes.shift()
if x == 1 :
server1sum -= 1
else :
server2sum -= 2
【讨论】: