IOCP三层结构
本文作者:sodme
本文出处:http://blog.csdn.net/sodme
声明:本文可以不经作者同意任意转载,但请保留文章开始前的作者、出处及声明信息。谢谢。
由于个人工作的关系,接触高性能服务器的研发已经有一段时间了,在没有接触这个话题之前,我也和许多人一样,认为服务器的设计无非就是用一下winsock,调用调用函数那么简单。当亲自完成了一个在win平台上能承载上万连接的测试模型后,才知道,原来,作高性能服务器是这么有挑战性。你不仅需要在细支末节上对模型进行精雕细琢,更需要在总体架构方面进行权衡选择。这两方面,都会影响到你的服务器性能的正常发挥。作为对“细枝末节”方面的介绍,请参照我之前写的系列文章“完成端口之性能优化”。而从此篇文章开始的系列文章,将就一个完整的高性能服务器模型进行介绍,而对于服务器集群架构方面,则不在此系列的讨论范围,那将是未来数周我将要完成的事。有朋友跟我说,希望我能提供底层模型的完整代码或可供使用的动态链接库及LIB文件。对于这个要求,我现在还在考虑之中。确实,有了代码,要学得更快一点,但由于模型里牵涉到一定的版权问题,所以,我会考虑将其进行必要的修改,而后再考虑是否向大家提供源代码。不过,可以肯定的是,对于LIB及DLL的要求,我想我会尽快提交上来的。
所谓的“高性能”,我想不外乎两个方面:
1、处理的并发请求要尽可能地多,具体表现为同一时间内同时连接的客户端数量;
2、数据包的吞吐量要尽可能地大,具体表现为单位时间内服务器的收、发数据量。
win平台下,IOCP(完成端口)是处理大量并发连接的最佳处理方案,所以,此后讨论的文章,也是基于这个模型的。有关一个独立的IOCP模型到底是如何工作的,请大家下载微软的SDK,在那个例子里,有基本的IOCP示例。但那仅仅是个示例,于实际的应用中,还需要作很多工作。阅读以下的内容时,最好具备以下条件:知道IOCP的基本概念,以及它所调用的几个必备函数(Create、Get、Post函数等)的使用。注:为嫌麻烦,这几个函数,我采用的都是简单叫法,完整的函数名请查看完成端口相关资料。
为了使大家能有一个宏观概念的把握,我先介绍一下基于三层结构的服务器通信底层模型。对于软件架构而言,没有最好之说,放在不同的应用环境其表现都可能千差万别,所以,我不保证这个架构是能让所有人都看着舒服的,我只保证,在我当前的项目应用中,这个架构充分考虑了“性能”和“可扩展性”两者的兼顾,让我在很容易地开发新的服务器时,仍然可以享受到很好的性能。
一、三层架构图及简单说明
三层架构图如下:
CIOCPServer
||
||
CCutomHPServer
||
||
CTestServer
以后我们要讨论的就是这个看上去并不复杂的三层架构图,下面就此架构图中的主要类进行简要说明。
CIOCPServer:
完成端口服务器基本通信类,它使用winnt/2000/xp平台特有完成端口特性,对通信模型进行封装,向它的派生类提供以下基本扩展接口(可被重载的虚函数):
1、有客户端连接时的处理接口;
2、客户端断开时的处理接口;
3、从客户端收完数据后的处理接口;
4、向客户端发送完数据后的处理接口;
5、网络通信及服务器处理出现错误时的处理接口。
CCustomHPServer:
典型的高性能服务器类,CIOCPServer是其基类之一(之一?难道还有另外的基类,回答是:当然,呵呵,别急,后面会介绍),此类在CIOCPServer的基础上,封装了三个数据队列及三类处理线程,介绍如下:
1、接收数据包队列及接收线程:用于存放刚收到的数据包,此数据包还没有进行逻辑意义上的拆解,接收线程从此队列中取出数据包,并将其形成一个逻辑意义上完整的数据包加入到“处理数据包队列”中;
2、处理数据包队列及逻辑处理线程:已经拆解成了逻辑意义上的数据包,逻辑处理线程对此类数据包进行逻辑解析,这里就是服务器的主要逻辑部分,有的数据包在处理完成后,可能是需要向客户端返回处理结果的,此时就需要逻辑线程在处理完成后将返回结果的数据包放入“发送数据包队列”中;
3、发送数据包队列及发送线程:待发送的数据包队列,由发送线程根据数据包里的客户端套接字发送给特定客户端。
CTestServer:
此类是一个测试类,主要用于演示如何在CCustomHPServer的基础上派生一个真正的应用服务器,并用于说明它需要重载实现CCustomHPServer的哪些重要虚函数。
基于以上的结构,我们的服务器通信模型,可以一层一层地实现,一层一层的测试。在CIOCPServer中,它本身是不带有任何数据队列的,所有的网络数据都是即来即处理,没有保存数据,实现的是即时响应。在CIOCPServer里,有两类重要线程:AcceptThread线程和WorkerThread线程。其中,AccetpThread线程使用Accept或AcceptEx函数来接收客户端的连接请求,并实现客户端socket与完成端口句柄的绑定,“有客户端连接时的处理接口”就是在这里封装的;而WorkerThread线程是我们在完成端口中常说的“工作者线程”,它由get函数触发工作,除“有客户端连接时的处理接口”之外的其它接口,都在这里进行封装。
在真正实现一个高性能服务器模型时,我们可能需要逐层地加以实现,这样作,一是因为测试起来要简单一些,二是因为在我们逐层实现时可以清楚地知道每一层在实现时的效率是什么样的,这样就有利于我们找出提高效率的突破口。可以先从CIOCPServer类开始,实现一个简单的ECHO服务器,即:回显服务器。不用维护数据包队列,对客户端发过来的数据,即时返回给客户端。作完这一层,属于完成端口该作的事基本上就作完了,它包括:有大量客户端连接时的客户端连接队列维护,客户端连接、断开、发送、接收数据时的事件处理及线程同步。根据我的经验,在处理底层的客户端断开事件时是一个难点,新手往往会在接收到断开事件时直接释放掉当前客户端对象,但比较好的作法是使用引用计数机制,而不是直接释放。另外,在“释放”这一点上,我也有自己的一个看法,即:客户端对象最好不要释放,而把它放入闲置队列或者关闭原来的socket之后,再重新生成一个新的socket让它与原客户端对象关联,把它作为一个新的客户端对象使用,这样就避免了频繁的客户端对象的建立与释放,当然,这样作的前提是在接受客户端连接方面最好使用AcceptEx函数而不是Accept。
IOCP三层结构的更多相关文章
- Atitit.软件开发的三层结构isv金字塔模型
Atitit.软件开发的三层结构isv金字塔模型 第一层,Implements 层,着重与功能的实现.. 第二次,spec层,理论层,设计规范,接口,等.流程.方法论 顶层,val层,价值观层,原则, ...
- C#-WebForm-WebForm开发基础、如何给控件注册事件?——事件委托写法、http无状态性、三层结构
(小知识 - xml:可扩展的标记语言 html:超文本标记语言) 一.创建WebForm:新建→网站 此时文件夹中只有一个 config 文件,打开后 二.在项目下右键添加新项 在设计页面中打开 从 ...
- 在VS2010中建立C#三层结构
转自:http://www.blueidea.com/microsoft/vs2010/2010_con/2010081301.htm 三层结构,会有多个项目.为了让各项目之间的关系反映在目录结构上所 ...
- android的四层体系结构,基于mvc三层结构浅析
从多方面理解Android体系结构 1.以分层的方式来看Android 安卓体系结构分为四层. 首先看一下官方关于Android体系结构的图: 1).Linux Kernel:负责硬件的驱动程序.网络 ...
- mvc与三层结构
http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在问三层架构和MVC的关系,感觉这种问题有点教条化了.因为它们都在逻辑 ...
- mvc与三层结构终极区别
http://blog.csdn.net/csh624366188/article/details/7183872 http://www.cnblogs.com/zhhh/archive/2011/0 ...
- java中从Spring、Hibernate和Struts框架的action、service和dao三层结构异常处理体系设计
Spring的事务实现采用基于AOP的拦截器来实现,如果没有在事务配置的时候注明回滚的checked exception,那么只有在发生了unchecked exception的时候,才会进行事务回滚 ...
- JavaWEB 常用开发模式MVC+三层结构
MVC开发模式: M: Model -- JavaBean C: Controler -- Servlet V: View --- JSP 不会在word里面画画,所以就直接截了 老 ...
- 传统三层结构和MVC之于贫血模式和充血模式以及领域建模
相信很多人跟我一样,一开始在使用贫血模式的三层结构:抽象出来一个贫血的实体封装,然后把对模型的所有操作,分离出来,分离到BLL层去,然后DALL层负责把这些操作和数据库产生映射,负责读写删改的操作 ...
随机推荐
- C++读写ini配置文件GetPrivateProfileString()&WritePrivateProfileString()
转载: 1.https://blog.csdn.net/fengbingchun/article/details/6075716 2. 转自:http://hi.baidu.com/andywangc ...
- nginx的脚本引擎(二)rewrite
其实rewrite指令和上一篇说的if/set/return/break之类的没多大差别,但是rewrite用起来相对复杂,我就把他单独放到了这里.想要弄懂nginx的脚本引擎需要先明白处理reque ...
- c# 误区系列(一)
前言 整理很早以前认为的一些误区,准备整理一个系列.新手可以看下,然后大佬指点一下是否哪些地方错了. 正文 值类型存在栈上,引用类型存在堆上 很多人认为用这句话来解释值类型和栈类型的区别,甚至有些文章 ...
- jmeter_02_目录文档说明
jmeter目录文档说明 bin目录是可执行文件 jmeter.bat 是启动文件 可以启动jmeter. 使用notpad++ 等文本编辑器打开 bat文件 可以配置jvm的参数 比如堆内存[Hea ...
- go创建http服务
Go语言这种从零开始使用到解决问题的速度,在其他语言中是完全不可想象的.学过 C++ 的朋友都知道,一到两年大强度的理论学习和实战操练也只能学到这门语言的皮毛,以及知道一些基本的避免错误的方法. 那么 ...
- from lxml import etree报错
使用的是python3.7的环境,解析数据要用xpath,系统是mac pip install lxml一分钟后...下载成功 开始写代码, from lxml import etree挂了-,lxm ...
- mac 解决安卓模拟器链接不上网络
方法1.临时方法,每次启动都要加114.114.114.114 1.进入到下面的目录 /Users/anxiaodong/Library/Android/sdk/emulator 2.执行以下命令 e ...
- 第十章 nginx常用配置介绍
一.虚拟主机 1.配置方式 #虚拟主机配置方式:1.基于多IP的方式2.基于多端口的方式3.基于多域名的方式 2.方式一:基于多IP的方式 1.第一个配置文件[root@web02 /etc/ngin ...
- 探索ParNew和CMS垃圾回收器
前言 上篇文章我们一起分析了JVM的垃圾回收机制,了解了新生代的内存模型,老年代的空间分配担保原则,并简单的介绍了几种垃圾回收器.详细内容小伙伴们可以去看一下我的上篇文章:秒懂JVM的垃圾回收机制. ...
- Topsis优劣解距离法 mlx代码
请参考https://blog.csdn.net/qq_36384657/article/details/98188769 mlx代码 topsis 优劣解距离法 参数说明: 分数.获奖次数.价值等 ...