公开/公告号CN103513990A
专利类型发明专利
公开/公告日2014-01-15
原文格式PDF
申请/专利权人 安徽科大讯飞信息科技股份有限公司;
申请/专利号CN201310474365.3
申请日2013-10-11
分类号G06F9/44(20060101);
代理机构11251 北京科迪生专利代理有限责任公司;
代理人杨学明;李新华
地址 230088 安徽省合肥市高新开发区望江西路666号
入库时间 2024-02-19 21:48:50
法律状态公告日
法律状态信息
法律状态
2019-03-15
专利权的转移 IPC(主分类):G06F9/44 登记生效日:20190225 变更前: 变更后: 申请日:20131011
专利申请权、专利权的转移
2018-03-13
著录事项变更 IPC(主分类):G06F9/44 变更前: 变更后: 申请日:20131011
著录事项变更
2017-01-25
授权
授权
2016-12-14
著录事项变更 IPC(主分类):G06F9/44 变更前: 变更后: 申请日:20131011
著录事项变更
2014-04-23
实质审查的生效 IPC(主分类):G06F9/44 申请日:20131011
实质审查的生效
2014-01-15
公开
公开
查看全部
技术领域
本发明属于网络通讯领域,尤其涉及一种用于分布式处理的高性能通用网络框 架,其为一个提升网络性能、缩短软件开发周期的网络框架。
背景技术
随着互联网/移动互联网的飞速发展,业界对高性能的分布式处理服务器需求越来越高, 传统的服务器网络框架已经无法满足需求。另一方面,在面对纷繁复杂的业务需求时,更短 的软件开发周期意味着更丰厚的回报。
传统的网络框架基于阻塞式网络编程,程序流程通常阻塞在读取数据过程上。TCP是个 全双工的协议,同时支持读写操作,当一个线程/进程阻塞在读取数据上时,给这个连接发送 数据就必须等待读取数据完成,这就导致了程序效率低下。
近些年来,IO多路复用技术应用十分广泛,也就是通过select/poll/epoll等多路选择器, 让可一个线程可以处理多个连接,从而提高数据收发效率。同时,通过Reactor的思想,将 网络部分的通用代码提取为公用的框架或库,用户只需要编写业务逻辑代码,并通过事件回 调注册到框架中,就可以实现完整的网络服务。
通常情况下,网络库设计事件回调的方式是定义一个接口,包含网络事件对应的处理函 数。用户的代码去继承这个接口并加以实现,然后把对象注册到网络库中,事件触发时就回 调对应的函数,这是传统的C++网络库的做法。这种做法在C++中面临的一个直接问题是 对象的生命周期管理,因为C++的动态绑定只能通过指针和引用来实现,你必须把基类指针 传给框架,才能获得事件的回调。那么这个派生类对象何时销毁就成为了难点,它的所有权 到底归谁?
其次,传统的网络库对资源的管理容易导致一系列的问题。如TCP的连接是一个短生 命周期对象,但是当连接被动断开的时候,网络库不能立刻销毁对象,因为用户可能还持有 它的引用准备用来收发消息,如果直接delete,有可能造成空悬指针,导致程序挂死。
最后,对于CS结构,服务端添加新功能后,不一定所有的客户端都可以马上升级并使 用新功能,因此新的服务端在上线之后要保证和现有的客户端的功能和协议保持兼容,这样 才能平稳升级。传统的网络库在消息格式设计中放入版本号,服务端每次收到消息都需要根 据版本号做分发,如此很容易在服务端留下一堆冗余代码且容易导致混乱。另一种错误是采 用C struct的格式设计消息,这样的缺点也显而易见:首先不易升级,其次是不跨语言,需 要时刻维护其他语言的打包、解包代码,同样容易导致混乱。
发明内容
本发明利用C++语言的高效、稳定和灵活性,创建了一个通用的网络框架,极大的减少 了网络应用开发,让企业可以更专注于业务的开发而不必考虑数据传输、通讯和管理等方面 的技术细节。
本发明采用的技术方案为:一种用于分布式处理的高性能通用网络框架的设计方 法,该方法包括如下步骤:
1.网络服务设计:
网络设计方案采用了“多Reactor+线程池”的策略,主Reactor负责accept 客户端的连接,收到连接请求后,将连接分配给某个子Reactor,这样该连接的 收发操作都在这个子Reactor中完成,多个连接就被分发至多个子线程中,同 时,具体的运算任务也分配给了运算线程池来处理,从而充分的利用了CPU;
2.接口设计:
事件回调采用了boost::function+boost::bind的做法,这种做法不必担心对 象的生命周期,对用户代码的class类型、成员函数名没有限制,只对函数的参 数和返回值类型有部分限制,传给网络库的都是值语义的boost::function对象, 没有指针和引用的概念,从而解决了对象生命周期和空悬指针的问题;
3.资源管理:
采用了智能指针来管理资源,智能指针使用RAII的方法来对资源进行管 理,RAII的基本原理是利用对象封装资源,采用对象引用计数记录对象的引用 次数:对象初始创建的时候引用次数为1,在对象被使用时引用计数加1,对象 释放时引用计数减1,直至引用次数为0时对资源进行释放。故而能够自动管 理内存的释放,避免了空悬指针等bug的产生,同时降低了资源的维护成本, 缩短了程序的开发周期;
4.消息格式设计:
采用Google Protobuf(即第三方中间语言)来描述消息格式,Protobuf是用于结构化数 据串行化的方法,能够定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数 据结构,每个Protobuf信息是一小段逻辑记录,包含一系列的键值对,每个消息类型拥有一 个或多个特定的数字字段,每个字段拥有一个名字和一个值类型,值类型可以是数字、布尔 型、字符串、原始字节或者其他Protobuf类型,还允许数据结构的分级;可以运行Protobuf 编译器,将定义的.proto文件编译成特定语言的类;可以在不影响向后兼容的情况下随意给 数据结构增加字段,旧有的数据会忽略新的字段,所以使用Protobuf作为通信协议,可以无 须担心破坏现有代码的情况下扩展协议。至此完成用于分布式处理的高性能通用网络框架的 设计。
本发明主要实现了以下功能:
A.采用“多Reactor+线程池”机制有效处理密集型IO和计算的问题;
B.良好的接口设计不会给使用者带来不要的限制(耦合),用boost::function、boost::bind 机制取代了继承这种强的耦合设计,从而更易于开发;
C.采用智能指针以及相关的一些多线程安全措施,对资源进行合理有效的 管理,从而避免了开发过程中可能会导致的一些bug,增加了程序的鲁棒性;
D.采用Google Protobuf(第三方中间语言)来描述消息格式,然后生成不 同语言的解析与打包代码,从而解决了升级与跨语言的问题。
本发明与现有技术相比的优点在于:
(1)、本发明同时适合计算和IO密集型应用;
(2)、本发明良好的接口设计易于开发人员开发,简化TCP网络编程;
(3)、本发明有效的资源管理保证程序的稳定性;
(4)、本发明采用第三方中间语言描述消息格式解决程序升级和跨语言 的问题。
附图说明
图1是传统单Reactor的网络框架设计方案;
图2是本发明所采用的网络框架设计方案;
图3是本发明所采用的消息格式设计方法;
图4是本发明应用在音频质量检测系统上的部署示意图;
图5是性能、稳定性测试中音频质量检测系统的部署示意图;
图6是QCClient的处理速度随分布节点数目变化趋势图;
图7是QCServer的网络带宽随分布节点数目的变化趋势图;
图8是QCClient的CPU占用在3*24小时的监视情况的示意图;
图9是QCClient的系统句柄占用在3*24小时的监视情况示意图;
图10是QCClient的虚拟内存在3*24小时的监视情况。
具体实施方式
下面结合附图以及具体实施例进一步说明本发明。
1.网络服务设计
传统的阻塞式编程方案显然已经不能满足如今的IO需求了,附图1显示的 是目前使用较多的单Reactor设计方案,在没有事件触发时,IO线程等待在 poll/epoll上,事件到达后由网络库处理IO,完成后将结果发送(回调)给客户 端代码。
这种方案的优点前面已经提到,数据收发由网络库来完成,程序只用关心 具体的业务逻辑;缺点则是:适合IO密集型的应用,不适合CPU密集型的应 用,难以发挥多核多线程的威力。
附图2显示的是本发明采用的网络设计方案,采用了“多Reactor+线程池” 的策略,主Reactor负责accept客户端的连接,收到连接请求后,将连接分配 给某个子Reactor,这样该连接的收发操作都在这个子Reactor中完成,多个连 接就被分发至多个子线程中。同时,具体的运算任务也分配给了运算线程池来 处理,从而充分的利用了CPU。可以看出,这种方案适合处理密集型IO和运 算的应用,在现如今多核发展迅速的时代,可以极大的提升程序的性能。
2.接口设计
传统C++网络库设计中,网络库会定义一些抽象基类,使用者需要继承这 些基类以获取事件的回调通知。由于C++动态绑定只能通过指针和引用来实现, 使用者必须将子类对象的指针或者引用注册给网络库。在这些子类的生命周期 结束后到底由谁来释放,如何保证一个地方在释放对象时其他地方没有继续引 用这个对象,这些都是难点。
本发明中,事件回调采用了boost::function+boost::bind的做法,这种方式 不必担心对象的生命周期,对用户代码的class类型、成员函数名没有限制,只 对函数的参数和返回值类型有部分限制,传给网络库的都是值语义的 boost::function对象,没有指针和引用的概念,从而解决了对象生命周期和空悬 指针的问题。
网络编程最本质的是处理以下问题:
1)连接建立。包括服务端接受(accept)新连接和客户端发起(connect)连 接。
2)连接断开。包括主动断开(close或shutdown)和被动断开。
3)消息收发。包括如何处理消息分包和解包,如何设计消息缓冲等。
本发明的使用非常简单,不需要继承,只需要采用boost::function+ boost::bind机制注册回调去处理前面提到的连接建立断开、消息收发问题:
服务端注册连接建立、断开回调:
server_.setConnectionCallback(boost::bind(&Server::onConnection,this, _1));
服务端注册消息收发回调:
server_.setMessageCallback(boost::bind(&Server::onMessage,this,_1,_2));
3.资源管理
传统的资源管理方式会导致一些不可预估的错误。如在TCP连接中,当连 接被动断开的时候,网络库不能立刻销毁对象,因为用户可能还持有它的引用, 准备用来收发消息,如果直接delete,有可能造成空悬指针,导致程序挂死。
本发明采用了智能指针来管理资源,智能指针使用RAII的方法来对资源进 行管理,RAII的基本原理是利用对象封装资源,采用对象引用计数记录对象的 引用次数:对象初始创建的时候引用次数为1,在对象被使用时引用计数加1, 对象释放时引用计数减1,直至引用次数为0时对资源进行释放。故而能够自 动管理内存的释放,避免了空悬指针等bug的产生,同时降低了资源的维护成 本,缩短了程序的开发周期。
例如,对TCP传输中的消息采用智能指针(boost::shaed_ptr)管理,消息 定义如下:boost::shared_ptr<google::protobuf::Message>message。程序运行中 就无需考虑消息在何时释放,当消息使用完毕后会自动析构释放资源。
4.消息格式设计
本发明采用Google Protobuf(第三方中间语言)来描述消息格式。Protobuf 是用于结构化数据串行化的灵活、高效、自动的方法,有如XML,不过它更小、 更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代 码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结 构。只需要在一个.proto文件中定义你需要做串行化的数据结构信息。每个 Protobuf信息是一小段逻辑记录,包含一系列的键值对。
这里有个非常简单的.proto文件定义了个人信息:
可以看出,消息格式很简单,每个消息类型拥有一个或多个特定的数字字 段,每个字段拥有一个名字和一个值类型。值类型可以是数字(整数或浮点)、 布尔型、字符串、原始字节或者其他Protobuf类型,还允许数据结构的分级。 你可以指定可选字段,必选字段和重复字段。
一旦定义了自己的报文格式(message),你就可以运行Protobuf编译器,将 你的.proto文件编译成特定语言的类。
例如选择C++语言,运行编译如上的协议文件生成类叫做Person。随后就 可以在应用中使用这个类来串行化的读取报文信息。代码如下:
然后就可以读取报文中的数据,代码如下:
可以在不影响向后兼容的情况下随意给数据结构增加字段,旧有的数据会 忽略新的字段。所以使用Protobuf作为通信协议,可以无须担心破坏现有代码 的情况下扩展协议。
综上所述,本发明采用了附图3所示的消息格式设计。注意,消息中添加了校验和字段, 对于一些关键的网络应用,进一步保证了可靠性。
1.性能、稳定性评估
目前,本发明已经应用在音频质量检测系统上,该系统旨在使用自动化的 方法对音频的内容质量进行检测,代替传统的人工检测的方法,提升检测的效 率和效果。附图4是该系统的部署图。系统采用一台中心节点(QCServer)和 多个分布节点(QCClient)。中心节点负责管理分布式节点,分发请求任务, 整合处理结果。分布节点负责完成音频质量检测,并向中心节点返回处理结果, 其中对音质的检测较为消耗CPU。整个系统属于典型的CPU和IO密集型系统。 本发明负责QCServer和QCClient之间的IO通信管理以及QCClient的密集型 CPU任务处理。
1)性能测试。
采用3个服务器(4核2G、4核4G、4核8G),部署方式如附图5所示。
下面是引擎性能数据与分布节点数目的关系表:
表1引擎性能数据与分布节点数目的关系表
上面表格显示QCClient的性能良好,处理速度会随着分布式节点数目的增 加而增加,基本随着节点数线性增长,图6可直观显示。
同时QCServer所在服务器上的网络带宽也随着分布式节点数目的增加而 增加,基本随着节点数线性增长,图7可直观显示。
2)稳定性测试
附图8是QCClient的CPU占用在3*24小时的监视情况,附图9是句柄占 用在3*24小时的监视情况,附图10是虚拟内存在3*24小时的监视情况。可以 看出,系统的CPU占用平稳,无内存、句柄泄漏,整个系统在3*24小时内稳 定运行。
综上所述,本发明适合CPU和IO密集型应用开发,性能、稳定性良好。
本发明未详细公开的部分属于本领域的公知技术。
尽管上面对本发明说明性的具体实施方式进行了描述,以便于本技术领的技术人员理解 本发明,但应该清楚,本发明不限于具体实施方式的范围,对本技术领域的普通技术人员来 讲,只要各种变化在所附的权利要求限定和确定的本发明的精神和范围内,这些变化是显而 易见的,一切利用本发明构思的发明创造均在保护之列。
机译: 用于内啮合齿轮泵的高性能高性能转子转子外形的设计方法及采用该方法的转子
机译: 一种用于对技术实现所需的网络框架的组件进行优先级排序的系统,方法和制造品
机译: 通用变速涡轮发电机的一种新颖的设计方法