May 15

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
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阻塞. 在计算机系统中, 服务器线路的对应物便是进程或者线程.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 分发器进程 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也行.

Related posts:

  1. 用SDL在Linux实现图像的移动
  2. C语言网络程序惯用法-参数传递
  3. svc_process函数
  4. 潘金莲醉闹葡萄架(视频)
  5. 用脚本语言开发网游 – C整合Python

Written by benegg at 2009-05-15 22:43:02 | Views: 2454

Leave a Reply

必须登录, 或者浏览器开启JavaScript支持才可以评论!