反转夜刀神十香h抱枕:(一)Socket服务器整体架构概述

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 19:42:51

(一)Socket服务器整体架构概述

2010-10-28 16:50 by 田志良, 4613 visits, 收藏, 编辑

  Socket服务器主要用于提供高效、稳定的数据处理、消息转发等服务,它直接决定了前台应用程序的性能。我们先从整体上认识一下Socket服务器,Socket服务器从架构上一般分为:网络层、业务逻辑层、会话层、数据访问层,如图:

                        (图1)

(一) 网络层

网络层主要用于侦听socket连接、创建socket、接受消息、发送消息、关闭连接。作为socket通信服务器,网络层的性能相当重要,所以我们在设计网络层时,要着重在以下几方面获得突破:最大连接数、最大并发数、秒处理消息数。如何突破呢?下面我为大家介绍几种网络层常用到的一些技术和技巧(具体实现,我将在博文中逐一具体阐述):

1)Buffer管理

       每一个SocketAsyncEventArgs对象(以下简称SAEA)在内存中都有其对应的缓存空间,如果不对这些缓存空间进行同一管理,当SAEA对象逐渐增多时,这些SAEA对象的缓存空间会越来越大,它们在系统内存中不是连续的,造成很多内存碎片,而且这些缓存不能重复利用,当创建、销毁SAEA对象时,造成CPU很多额外消耗,影响服务器性能。面对这问题如何解决呢?用Buffer池管理!

2)双工通信

       Socket服务器提高通信效率是一个永恒的话题,提高通信效率有很多种方法,双工通信就是其中之一。一个SAEA对象在同一时刻只能用来接收数据或发送数据,有人想,如果一个SAEA对象在同一时刻既能发送数据又能接受数据,那肯定会提高socket通信效率。恩,很有想法!可是你能让你的头在同一时刻既往左转又往右转吗?答案是不行的,那如何实现双工通信呢?既然一个SAEA对象在同一时刻只能做一件事,那我自定义DuplexSAEA对象,在该对象中封装两个SAEA,一个用于接受,一个用于发送,问题不就解决了吗。

3)poolOfAcceptEventArgs

       poolOfAcceptEventArgs是个什么东西?它不是个东西,是一个容器,一个容纳AcceptSAEA对象的容器。给你两个socket服务器,你能很快判别两个服务器性能的优异吗?很简单,你瞬间向一台服务器打入5、6万的连接,看看会不会都连上,如果都连上,说明这台socket服务器的并发处理连接的能力还是不错的。那如何提高socket服务器的并发连接能力呢?答案:poolOfAcceptEventArgs!

4)消息队列调度器

       消息队列调度器主要分为两种:接受消息队列、发送消息队列。为什么要用消息队列呢?主要是提高socket服务器的吞吐量。首先我们定义一个队列Queue,然后编写N个调度器,不断从队列中调度消息,接受队列调度器用于将消息抛至业务逻辑层处理,发送队列调度器用于调用网络层发送消息接口,向指定端口发送数据。

5)心跳扫描

       有一个困惑:客户端连接socket服务器,连接没有断开,但客户端挂了,这样这条连接在socket服务器中就成了钉子户,落地生根不走了!一个钉子户还可以忍受,千千万万个呢?那就崩溃了!怎样解决这个问题呢?定时扫描每条连接,如果该条连接在超时时间内没有IO响应,则关闭它。

6)粘包

       服务器在接受消息包时,如果两个数据包同时被你服务器收了怎么办?你会把他当成一个数据包吗?如果一个数据包断了,分成两次被你服务器收了,你会把他们拼接起来吗?这些就是粘包了,怎么解决?正则表达式扫描!

7)多线程编程

       Socket服务器的编程就是多线程编程,面对多线程,线程间怎样同步、怎样避免死锁?多线程访问公共资源如何处理,在下面的博文中,我将会为大家具体阐述。

(二) 业务逻辑层

  网络层将解包后的消息包抛至业务逻辑层,业务逻辑层收到消息包后,解析消息类型,然后转入相应的处理流程处理。

  网络层应提供发送消息的接口供业务逻辑层调用,因为网络层不会主动发送消息,发送消息的操作是由业务逻辑层来控制的,所以业务逻辑层应根据具体的业务应用,封装不同功能的发送消息的方法。

(三) 会话层

  会话层主要用于记录在线用户信息,该层隶属于业务逻辑层。既然隶属于业务逻辑层,那为什么还要独立出来呢?这主要为以后分布式开发拓展用,试想,一台服务器最大能支持多少人同时在线?中国有多少人?如果1亿人同时在线,你一台服务器能支持得了吗?答案肯定是否定的,所以要分布式开发。分布式开发涉及到用户信息同步的问题,所以会话层就要独立出来了。

(四) 数据访问层

  数据库执行效率是整个socket服务器的瓶颈?为什么呢?举个例子:假设我们的socket服务器的秒处理消息的条数为3000,每处理一条消息都会保存历史记录,那么,如果数据访问层不想拖网络层的后腿,那么他的执行sql语句的效率也必须达到每秒3000!如果socket服务器和数据库服务器部署在同一网段上,这个速度是没有问题的,但如果数据库服务器部署在外网呢?你的sql语句的执行效率能达到那么高吗?很困难!

  再思考一个问题:如果网络层执行线程和数据库执行线程是同一个线程,那么网络层的处理必须等待数据库执行完毕后,才能进行!如果数据库执行效率比较慢,那对整个socket服务器将是一个毁灭性的打击。

  那么怎样将数据访问层与网络层分离,让他们互不影响?如何提高数据库执行效率,让网络层的处理速度和数据访问层的处理速度达到一个平衡?答案:连接池+sql调度器+主从数据库。

Socket服务器的整体架构就为大家介绍到这里,下面我将会为大家具体阐述各个技术的实现。

分类: Socket标签: 多线程, Buffer, socket, 双工通信, 粘包, 心跳, 消息队列, 连接池绿色通道:好文要顶关注我收藏该文与我联系 田志良
关注 - 11
粉丝 - 118荣誉:推荐博客+加关注230(请您对文章做出评价) 博主前一篇:Try-Catch机制使用场景分析
博主后一篇:如何避免System.OutOfMemonryException异常
Add your comment

27 条回复

  1. #1楼 BenBen789      2010-10-28 17:02
    分析几乎涉及了Socket的方方面面,期待你的精彩后文。。。  回复 引用 查看   
  2. #2楼 何必      2010-10-28 17:14
    很想好好学学socket 期待精彩后文  回复 引用 查看   
  3. #3楼 田户名      2010-10-28 17:29
    good  回复 引用 查看   
  4. #4楼 阿瑞|www.16hi.com      2010-10-28 17:47
    飘过 关注一下  回复 引用 查看   
  5. #5楼 温景良(Jason)      2010-10-28 18:00
    最后那个才是我关心的  回复 引用 查看   
  6. #6楼 zhenjing      2010-10-28 20:21
    到目前为止,从没见过通用的服务器架构,总是因背景不同而不同  回复 引用 查看   
  7. #7楼 onlyfew      2010-10-28 20:44
    拭目以待  回复 引用 查看   
  8. #8楼 hhshuai      2010-10-28 22:26
    拭目以待  回复 引用 查看   
  9. #9楼 clound      2010-10-28 23:00
    LZ 继续,哈哈  回复 引用 查看   
  10. #10楼 wufm      2010-10-29 09:25
    期待  回复 引用 查看   
  11. #11楼 张磊(Rey)      2010-10-29 10:33
    精彩,LZ继续  回复 引用 查看   
  12. #12楼 诗雨流苏飘      2010-10-29 11:34
    good!不错,顶!  回复 引用 查看   
  13. #13楼 ToBin      2010-10-29 12:30
    灰常期待,不知道是不是.net底下的  回复 引用 查看   
  14. #14楼 Sylvester      2010-10-29 13:41
    正好需要,赞一个。  回复 引用 查看   
  15. #15楼 liveshow021_jxb      2010-10-29 14:46
    学习一记,一直想加强这方面的能力  回复 引用 查看   
  16. #16楼 爱在两腿间      2010-10-31 17:59
    期待你的分享  回复 引用 查看   
  17. #17楼 小罗      2010-11-11 10:24
    楼主, 很期待你的博文. 个人爱好和工作都设计到这一块.  回复 引用 查看   
  18. #18楼 大头猪      2010-11-11 13:42
    我刚刚开始学习有关socket通讯的技巧,非常期待楼主下一篇博文。呵呵,俺就天天关注啦  回复 引用 查看   
  19. #19楼 ToBin      2010-11-25 17:34
    博主,你这文章出了很久了也没出下面的文章,天天看RSS都没有,实在等的蛋蛋疼了上来问问博主,啥时候能出下文啊。。。  回复 引用 查看   
  20. #20楼 qiuqingpo      2010-11-29 10:23
    楼主.你把你的精彩讲述出一本书吧.我第一个去买!期待下下...  回复 引用 查看   
  21. #21楼 ToBin      2010-11-29 18:01
    文中提到"那我自定义DuplexSAEA对象,在该对象中封装两个SAEA,一个用于接受,一个用于发送,问题不就解决了吗"
    有个问题,虽然用了两个saea对象,但都是使用的一个socket连接啊,能同时即接受又发送嘛 ?
     回复 引用 查看   
  22. #22楼 sofakeer      2010-12-01 14:56
    老大 期待你的这个系列。。。。。
    关注中。。  回复 引用 查看   
  23. #23楼 sofakeer      2010-12-09 20:52
    老大 啥时候 继续写啊!
    期待死我了!
    我要。。。。。看!

    呵呵
     回复 引用 查看   
  24. #24楼 彭杰斌      2010-12-24 11:09
    看到楼主的开篇,眼前一亮,期待后续大作。  回复 引用 查看   
  25. #25楼 o﹎Lin      2011-07-08 09:00
    不错,,  回复 引用 查看   
  26. #26楼 海市蜃楼      2011-11-02 22:48
    学习了。。。  回复 引用 查看   
  27. #27楼 edwardxh      2011-11-16 09:59
    引用ToBin:
    文中提到"那我自定义DuplexSAEA对象,在该对象中封装两个SAEA,一个用于接受,一个用于发送,问题不就解决了吗"
    有个问题,虽然用了两个saea对象,但都是使用的一个socket连接啊,能同时即接受又发送嘛 ?

    刚刚接触Socket通信知识,对此问题也比较关心,不知志良兄是否分析一下?