Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57669
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-15 10:25
个人简介

知识都是相通的--学无止境

文章分类

全部博文(19)

文章存档

2017年(8)

2015年(11)

我的朋友

分类: 服务器与存储

2015-07-01 14:09:31

上回说了介个概念的介绍,这回我们说说几种模型的对比。

通过上图,我们可以发现如下内容:
1  除了第10个方案是多进程的,其它几个都是多线程的;
      进程间通信肯定没有线程间通信方便,共享同一进程空间的线程,那不是白共享的。
2  都使用非阻塞IO,并且使用复用技术,即 select/poll/epoll;
      阻塞的IO操作是等待在read上,直到有数据来,如果没有数据,当前线程就一直等啊,等啊,也就累啊,累啊。非阻塞的IO操作呢,我read,没有数据,ok,没有我先去干会别的,等有了IO动静说给我就可以了,我到时候再来read。也就是说这个read等待的线程可以把cpu让出来给其它线程用。整体上效率就上来了啊。
3  第6和第7种方案和其它几种方案相比较,并发性偏低,开销大,线程数根据实际连接情况变化;
     在多核cpu上,cpu的数量总归是有限的,来一个请求或者连接就建立一个线程去处理,当线程数量超过cpu时,甚至超过很多时,这个线程切换代价将是性能下降的主要根源,如果线程数量有限的话,由于每个线程都是专门为每个请求或者连接服务,其它请求或连接就得等待,这样的并发性势必偏低。
      开销大,连接或请求到达,才建立线程,开销肯定比先建立好多个线程等待连接的开销要大。
      线程数量可变指的是,由于连接或请求到了才建立线程,也就是说线程受连接或请求数量决定。当线程数量较多时,性能也就下降了。 
4  都支持多核体系
        这个主要是现在为了提高性能,让线程或进程最大限度的都正常运转起来,必须都是可以在多cpu结构上运行的,让这没有啥说的,多个进程或者线程在多个cpu上运行总比在一个cpu跑的顺溜。当然得使用得当。

    下面说说各个模型的特点:几本上描述就是按照原书作者的观点
方案6:reactor主要负责网络IO,服务器收到请求,reactor不做计算或处理,而是创建一个新线程去处理。因为线程的建立是根据请求而进行的,如果一个连接上在某一时间段有好多请求,那么多个线程将用于处理这一个连接上的请求,有的请求执行时间短,有的执行时间长,先执行完的结果就返回给请求了,但是这个先执行完的请求由可能不是先提出请求的,这就是说如果执行结果有顺序要求的话,就需要特殊处理了。

方案7:这个方案是是为每个连接创建线程,连接上的请求都分配给一个线程。这个就可以保证一个连接上的执行顺序。与方案6的比较,二者还有一个区别,就是方案6在处理一个连接上有大量突发请求时,可以把各个请求分配给多个线程同时处理,但是方案7呢,突发请求只能排队等待同一个线程按照顺序来处理。这就取决于实际场景需要什么样的取舍。

方案8:首先建立固定线程数量的线程池,网络IO操作都放在一个线程,而每个连接的具体计算交给线程池。这种方案适合计算任务彼此独立,IO压力也不大的场景。但是这种方案,由于线程池中线程的独立处理,也会导致不安顺序返回执行结果的情况。线程池的另外一个作用还有执行阻塞操作,在这里阻塞不会导致io性能下降而直接影响用户体验。如果一个IO操作压力大的话,那么把IO分给其它线程,也就是下面的方案9了。

方案9:用原书作者的话说就是one loop per thread,每个线程都是一个select/poll/epoll循环。主IO线程还是负责收集连接,然后根据某种算法把连接分配给子IO线程,每个子IO线程在循环里处理多个连接或者请求。在子IO线程里也处理一些小规模或者压力不大的计算任务。这种方案,连接到来呢,直接分配给子IO线程,主Io线程就不用去关心这个链接或者请求了,而方案8,主IO线程把连接或请求给了线程池里的线程,计算完了,再给主IO线程,二者比较呢,方案8的进出线程池代价比方案9的要大。
原书作者陈硕写的muduo库就是用的这种方案。

方案10:这个方案是nginx使用的方案,这个服务器模型貌似最近几年挺火,一个高性能的 HTTP 和反向代理 服务器俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:新浪、网易、腾讯等,听说淘宝也用的是这个方案。

方案11:这个就是在方案9的基础啊上,再添加一个线程池来计算。小规模的计算可以在子IO线程处理,压力较大的计算处理就放到专用的计算线程池计算,这样,既可以处理突发性IO,又可以用于有突发的计算情况。

总结,按照陈硕原书的说法,一个程序使用一个event loop还是多个event loop,按照每千兆比特每秒的吞吐量配置一个event loop的原则来设定loop的数量。如果这样的话,千兆网卡用一个loop足以,这下大家了解到了吧,一般情况,我们平时的网卡其实一个loop就可以应付了。


完,不知道说的是不是有不合理的地方,大家看到,多多交流,互相改进。















阅读(1367) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~