高性能、高并发网络通信系统的架构设计

标签: 性能 并发 网络 | 发表时间:2014-05-04 16:26 | 作者:RoyalApex
出处:http://blog.csdn.net

1 引言


    随着互联网和物联网的高速发展,使用网络的人数和电子设备的数量急剧增长,其也对互联网后台服务程序提出了更高的性能和并发要求。本文的主要目的是阐述如何进行高并发、高性能通信系统的架构设计,以及这样的系统需要用到的常用技术,但不对其中的技术细节进行讨论和实现。本篇只起抛砖引玉的之效,如有更好的设计方案和思路,望您不舍赐教! [注:此文中使用select来讲解,如果想使用epoll,设计思路是一致的]


2 设计方案


    我们首先来看看课本上或学习资料上关于处理并发网络编程的三种常用方案,以及对应的大体思路和优缺点,其描述如下所示:

    1)、IO多路复用

      思路:单进程(非多线程)调用select()函数来处理多个连接请求。

       优点:单进程(非多线程)可支持同时处理多个网络连接请求。

       缺点:最大并发为1024个,当并发数较大时,其处理性能很低。

    2)、子进程处理

       思路:当连接请求过来时,主进程fork产生一个子进程,让子进程负责与客户端连接进行数据通信,当客户端主动关闭连接后,子进程结束运行。

       优点:模式简单,易于理解;连接请求很小时,效率较高。

       缺点:当连接请求过多时,系统资源很快被耗尽。比如:当连接请求达到10k时,难道要启动10k个进程吗?

    3)、线程处理

       思路:首先启动多个工作线程,而主线程负责接收客户端连接请求,工作线程负责与客户端通信;当连接请求过来时,ACCEPT线程将sckid放入一个数组中,工作线程中的空闲线程从数组中取走一个sckid,对应的工作线程再与客户端连接进行数据通信,当客户端主动关闭连接后,此工作线程又去从指定数组中取sckid,依次重复运行。

       优点:拥有方案②的优点,且能够解决方案②的缺点。

       缺点:不能支持并发量大的请求和量稍大的长连接请求。


    通过对以上三种方案的分析,显然以上方案 均不能满足高并发、高性能的服务器的设计要求。针对以上设计方案问题的存在,那我们该如何才能设计一个既能满足高并发,又有高效率的网络通信系统呢?


2.1 接收与处理


    IO多路复用中1个select()最多可管理1024个Socket FD,而如果要求并发量达到10k时,其显然大大超过了1个select()的管理能力。此问题该如何解决?

    很容易便可发现10k并发约等于10 * 1024并发,因此,需要大约10个select()才能有效管理,那该如何调用10个select()来管理10k的并发呢?

    因FD在进程之间是独立的,虽然子进程在创建之时,会继承父进程的FD,但后续新的连接产生的FD却无法继承,因此,要实现对10k并发的有效管理,使用 多线程实现高并发要求 是唯一的选择。即:每个线程调用1个select(),而每个select()最多可以管理1024个并发。

    在理想情况下,启动10个接收线程,便可管理10 * 1024 = 10k的网络并发。通过此种方式,便可达到高并发的设计要求。

    为了进一步的提高处理效率,我们可以对线程进行分工划分:

        Recv线程:专门负责与多个客户端连接进行通信,也就是负责接和发送数据;

        Work线程:专门负责处理Recv线程接收到的数据。

    Recv线程和Work线程协助处理的流程大体过程:

        ①、Recv线程将接收到的数据随机的放入到某个接收队列中;[注:随机放入起着负载均衡的作用]

        ②、接收完毕之后,再随机通知其中一个Work线程到指定的队列中取数据;[注:随机通知起着负载均衡的作用]

        ③、Work线程接收通知后,到指定的接收队列中取走数据;

        ④、Work线程根据取到的数据做相应的处理。

    故,其大体设计架构如下图所示:


图1 数据接收与处理


2.2 连接分发


    总所周知,使用TCP绑定指定端口后,其他线程或进程想再次绑定指定端口时,肯定会失败。而如果让每个Recv线程将Listen FD加入到select()的FD_SET中进行监听后,当有1个新的连接到来时,所有的Recv线程都会被惊醒,这也就是“惊群”现象的一种,这显然是不被允许的。为了避免此问题的出现, 只能让一个Accept线程专门负责Accept客户端的连接,再将新生成的Socket FD随机的分发给Recv线程,让Recv线程与客户端进行通信。[注:随机分发起着负载均衡的作用]

图2 连接分发


2.3 消息通知机制


    看到这时你可能还会有如下几个疑问:

        ①、Accept线程通过何种方式将新连接的Socket FD分发给Recv线程呢?

        ②、Recv线程通过何种方式通知Work线程到指定的接收队列取数据呢?

    在之前的一篇博文 《日志系统系能对比分析》中对TCP、UDP、Unix-TCP、Unix-UDP的性能做了对比测试和分析,可发现在这几种传输协议中,Unix-UDP的效率是最高的,因此,本系统选择Unix-UDP作为该系统内部消息通知机制的传输协议。


    此系统技术要点:

    ① 非阻塞IO ② 事件触发机制 ③ 线程池机制 ④ 负载均衡机制 ⑤Unix-UDP传输消息 ⑥ 内存池机制 ⑦ 高效算法和技巧的使用等等。


    在此只是对此系统的设计思路的大概描述,不做细节的讨论和分析。此设计思路在其他的应用场合可做适当的扩展变更,产生更适合具体应用场景的设计方案。


作者:邹祁峰

2014.05.04 16:00

作者:RoyalApex 发表于2014-5-4 16:26:17 原文链接
阅读:7 评论:0 查看评论

相关 [性能 并发 网络] 推荐:

高性能网络编程5--IO复用与并发编程

- - CSDN博客云计算推荐文章
对于服务器的并发处理能力,我们需要的是:每一毫秒服务器都能及时处理这一毫秒内收到的数百个不同TCP连接上的报文,与此同时,可能服务器上还有数以十万计的最近几秒没有收发任何报文的相对不活跃连接. 同时处理多个并行发生事件的连接,简称为并发;同时处理万计、十万计的连接,则是高并发. 服务器的并发编程所追求的就是处理的并发连接数目无限大,同时维持着高效率使用CPU等资源,直至物理资源首先耗尽.

高性能、高并发网络通信系统的架构设计

- - CSDN博客推荐文章
    随着互联网和物联网的高速发展,使用网络的人数和电子设备的数量急剧增长,其也对互联网后台服务程序提出了更高的性能和并发要求. 本文的主要目的是阐述如何进行高并发、高性能通信系统的架构设计,以及这样的系统需要用到的常用技术,但不对其中的技术细节进行讨论和实现. 本篇只起抛砖引玉的之效,如有更好的设计方案和思路,望您不舍赐教.

千万级规模高性能、高并发的网络架构经验分享

- - 编程语言 - ITeye博客
在开始谈我对架构本质的理解之前,先谈谈对今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的,对这个数量级我们 战略上 要重 视 它 , 战术上又 要 藐 视 它. 先举个例子感受一下千万级到底是什么数量级. 现在很流行的优步(Uber),从媒体公布的信息看,它每天接单量平均在百万左右, 假如每天有10个小时的服务时间,平均QPS只有30左右.

[译]Google Chrome中的高性能网络

- - UC技术博客
Google Chrome的历史和指导原则 【译注】这部分不再详细翻译,只列出核心意思. 驱动Chrome继续前进的核心原则包括:. Speed: 做最快的(fastest)的浏览器. Security:为用户提供最为安全的(most secure)的上网环境. Stability: 提供一个健壮且稳定的(resilient and stable)的Web应用平台.

构建高性能高并发Java系统

- scourgen - ITeye博客
异步通信显然可以更快的返回响应. 从实际经验看,对高吞吐服务器更大的好处是,系统中的某一服务出现问题后往往出现雪崩似的服务宕机. 这很多都是由于采用同步通信,需要等待其他服务同步通信结束后,其占用资源才能得到释放. 而这些资源往往是socket连接、线程、数据库连接等比较重的资源. 如果你真的需要他,可以用个mock同步.

Pora2应用中HBase高并发读写性能优化

- - 搜索技术博客-淘宝
淘宝搜索的个性化离线实时分析系统Pora已升级至Pora2,Pora2是在基于Yarn的流式计算框架IStream基础上开发的,同时为保证数据和消息的实时处理系统中较多地使用了HBase,是一个典型的高并发读写HBase的分布式应用. 系统在发布之初遇到了比较严重的性能问题,表现为处理速度跟不上实时日志,并且整个Hadoop/HBase集群压力大,连带其它应用受影响.

并发性能优化 – 降低锁粒度

- - 并发编程网 - ifeve.com
原文链接   作者:Adrianos Dadis 译者:买蓉(sky.mairong@gmail.com) 校对:方腾飞. 在高负载多线程应用中性能是非常重要的. 为了达到更好的性能,开发者必须意识到并发的重要性. 当我们需要使用并发时, 常常有一个资源必须被两个或多个线程共享. 在这种情况下,就存在一个 竞争条件,也就是其中一个线程可以得到锁(锁与特定资源绑定),其他想要得到锁的线程会被阻塞.

Java中不同的并发实现的性能比较

- - 并发编程网 - ifeve.com
原文链接   作者: Alex Zhitnitsky   译者: 有孚. Fork/Join框架在不同配置下的表现如何. 正如即将上映的星球大战那样,Java 8的并行流也是毁誉参半. 并行流(Parallel Stream)的语法糖就像预告片里的 新型光剑一样令人兴奋不已. 现在Java中实现并发编程存在多种方式,我们希望了解这么做所带来的性能提升及风险是什么.

用Netty开发中间件:高并发性能优化

- - CSDN博客推荐文章
用Netty开发中间件:高并发性能优化. 最近在写一个后台中间件的原型,主要是做消息的分发和透传. 因为要用Java实现,所以网络通信框架的第一选择当然就是Netty了,使用的是Netty 4版本. Netty果然效率很高,不用做太多努力就能达到一个比较高的tps. 但使用过程中也碰到了一些问题,个人觉得都是比较经典而在网上又不太容易查找到相关资料的问题,所以在此总结一下.

[转]使用 libevent 和 libev 提高网络应用性能

- Sonic - heiyeluren的blog(黑夜路人的开源世界)
Brown, 作家, Freelance. 许多服务器部署(尤其是 web 服务器部署)面对的最大问题之一是必须能够处理大量连接. 无论是通过构建基于云的服务来处理网络通信流,还是把应用程序分布在 IBM Amazon EC 实例上,还是为网站提供高性能组件,都需要能够处理大量并发连接. 一个好例子是,web 应用程序最近越来越动态了,尤其是使用 AJAX 技术的应用程序.