服务器如何处理不同成本的请求

2 views
Skip to first unread message

benegg

unread,
Jun 8, 2009, 7:22:06 AM6/8/09
to online_game_dev
服务器的各种不同服务占用的资源(成本)各不相同, 即使使用排队和重新安排次序的方式, 仍然不可避免低成本服务被高成本服务阻塞的情况出现. 一般
会利用操作系统的多进程或者多线程将服务分成流水线, 交替的处理各个服务的一小段.

不过, 具体应该开多少个进程, 如何分发请求, 处理进程的分发请求的进程如何通信, 编程接口如何设计, 等等, 都需要确定. 本文讨论了我自己
的一种想法.

服务器提供了多种服务, 但这些服务的成本相关极大. 假设有a和b两种服务, a的成本是3000, 而b的成本是3. 在网络服务器中, 服务器的
成本可以用消耗时间来衡量, 消耗时间是最重要的服务成本之一. 一条服务线路可以用编程语言表示为:

while(1){
request = clients.wait();
result = handle(request);
}

在同一个进程内处理两种服务请求, 高成本的服务a会阻塞低成本的服务b, 可以表示为:

while(1){
request = clients.wait();
switch(request.type){
case a:
handle_a(request); // cost = 3000
break;
case b:
handle_b(request); // cost = 3
break;
}
}

显然, 如果使用同一条服务线路来处理a和b两种类型的服务请求, a的请求会导致最多1000个b请求被阻塞. 显然, 应该使用两条服务线路, 一
条用来处理a请求, 一条用来处理b请求, 通过线路的管理机制来避免b被a阻塞. 在计算机系统中, 服务器线路的对应物便是进程或者线程.

在不同的进程处理不同的需求:

// 分发器进程 dispatcher
while(1){
request = clients_and_processes.wait(); // wait for clients and
processes
switch(request.type){
case a:
send_to_process_a(request); // cost = 1
break;
case b:
send_to_process_b(request); // cost = 1
break;
case a_result:
result = recv_from_process_a(request); // cost = 1
break;
case b_result:
result = recv_from_process_b(request); // cost = 1
break;
}
}

// 服务进程 a
while(1){
request = dispatcher.wait();
result = handle_a(request); // cost = 3000
}

// 服务进程 b
while(1){
request = dispatcher.wait();
result = handle_b(request); // cost = 3
}

这种作法增加了分发器进程. 当然, 也可以不使用独立的分发器进程, 而由某个服务进程担当分发器的角色. 不管怎么样, 分发器的角色是必须存在
的.

另外, 对于分发器来说, 服务进程的请求者(客户端)都是相同的. 在分发器看来, 服务进程和请求者的接口都完全一样. 这里有一个假设, 就是分
发器和服务进程的通讯的成本是非常低廉的.

因为通讯的角色增加了, 所以系统的复杂度也增加了. 需要设计分发器和服务进程的通讯协议. 另外, 虽然假设通讯成本低廉, 但还是会有消耗的.
每一个服务的平均成本增加了, 可以认为增加了管理成本. 而且, clients_and_processes.wait()接口的实现变得更加复杂
和困难.

高成本的部分也可以用Lua, Python等脚本语言来处理, 或者做成独立的进程, 用C#, VB也行.

--------------------------------
http://www.benegg.com/?p=31

Reply all
Reply to author
Forward
0 new messages