server是如何彪悍起来的(一)

 某年某月某一天,我需要搞一个server来向众多的client分发数据。于是,首先,我来研究下这个server面对的要求。
1.首先,我希望能够应付尽可能多的client,这样可以为老板省钱;
2.其次,这些个client都是老不死的(tcp长连接),我希望我的server能很好的应付他们;
3.再次,这些老不死的还非常烦人,jjww个不停(数据交换大且频繁);
ok,我们得出暂时的结论,此server要求应对尽可能多的长连接,和大数据量交换,同时要求尽可能的降低cpu负载和内存使用率,简而言之,我把老板对我的期望加诸到此server身上:既要马儿跑的快又要马儿不吃草。

由上分析可见,首先,我们的server需要一个快速有效的I/O处理模型来应付众多client的折磨。那么我们有什么选择呢?


1.克隆
    没错,既然一个server无暇应对如此来势汹汹的client,我们决定把自己复制n份,将client们分而化之。
    正如我们在古老(经典)的网络编程教程所见,server的每次accept都伴随着一次fork(pthread_create)操作,使得这个fork出来的复制品来对付一个client。以一对一,公平合理。
    等一下,光这样够吗?如果来了1000个,10000个client我们的server会怎么样呢?此时,众多的process(thread)用于处理client的请求,而cpu忙于在众多的process(thread)间切换,调度,处理锁,自顾应接不暇,实在没有功夫搭理client的请求了。
    由此可见,克隆对付少数client时可以,对付成千上万的client就只能捉襟见肘了。


2.异步
    为了避免众多进程导致的问题,异步模型开始引入。经典的如select,poll,最新的如我们的主角epoll。
    那么,他们是怎么干活的呢?
    首先,异步模型中只有一个进程,可是他能对付众多的client吗?我们从cpu的处理说起。
    在单核的cpu中,所有的指令其实都是顺序执行,这就是说,一条指令在执行时,后续的指令必须等待前者的完成(部分完成,流水线可有效缩短等待时间),因此,我们前面所是的多进(线)程并不能真正的同时执行,那他们是怎么被处理的呢?
    很简单,管理这些进(线)程的os使用了障眼法,它使用某种调度算法,给每个进(线)程一小段cpu时间工作。话说回来,就是当A进(线)程工作了一段时间后,会被os强制切换出去,换B进(线)程工作一段时间,如此A和B轮流坐庄,看起来似乎是并行工作了。
    当我们拆穿这个把戏之后,因为os对众多线程时的差劲表现,我们可以自己玩了。就是说,我们通过使用单进(线)程模拟这个os对多进(线)程处理的过程来避免多进(线)程带来的副作用。
    当然,这个模拟还是需要内核的配合的。
    拿select举例,这个过程如下:
    1.众多client的连接对应于不同socket上;
    2.select向内核询问有没有他感兴趣的sockt可以操作;
    3.若没有则等待或返回;
    4.若有,挨个对准备就绪的socket进行读写操作
    这样,就相当于每个client被分到相应的时间片得到了处理。所以,尽管整个工作是串行完成的,但是就我们看来,我们的server同时应付了众多的client。
 
3.克隆 + 异步
    尽管异步相当完美的完成了我们交给他的任务,但是在负载巨大的情况下,我们还可以让克隆和异步一起工作。
    一种做法是,一个server复制若干份,然后他们独立地进行异步处理(lighthttpd)。这也是目前非常实用高效的做法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值