Windows平台下高性能并发服务引擎设计(一)
来源:互联网 发布:小精灵字幕软件下载 编辑:程序博客网 时间:2024/05/16 09:25
一、系统内核设计框架图
图示为一个简单的引擎设计草图,最顶层为用户应用开发层,是整个服务引擎的唯一对外接口(直接开放给用户层,由用户层自定义开发),整套服务引擎的设计理念是采用事件驱动模式,本篇主要从该框架图入手简要介绍我所设计的后台服务引擎,后续篇章中我会对每个环节进行详细介绍。
该套引擎在我的程序中被称为IApplication,它包括系统日志接口,定时器接口,session管理器,虚拟服务器列表管理,当前虚拟虚拟目录等。
系统的设计约定如下:
底层系统只关心底层的设计和开发,系统底层的安全由底层自己负责,但是用户层在开发自定义应用的时候,必须接受底层给出的约定,这些技术约定会在后期的开放接口中给与说明,用户层自己的安全由用户层自己负责,底层不做考虑。
事件驱动模型设计:
内核层系统驱动采用iocp(windows平台下完成端口)来实现,由事件驱动概念引申出的io驱动以及定时器驱动都是基于该机制上实现。
Io模型设计:
Io的读写事件有io驱动层来完成,图中将io句柄单独拎出来考虑,主要是因为考虑到以下几点:
Io多样性(TCP、udp、文件io、管道等)。
扩展性。
灵活性,支持多样性io,内核以及用户层不用关心io的实现,仅仅需要关心io能实现的功能,并且能够根据实际需求选择不用io模型。
会话机制:
会话是服务器端用来标识客户端根服务器之间的联系,每一个客户端可以跟服务器之间同时进行多个通话如果有必要。
定时器:
每个虚拟器都有自己的一套定时器驱动,由内核实现,用户层可见,并可按照约定使用定时器
二、用户层开发接口
class IGooInterface
{
public:
virtual ~IGooInterface(){};
/*
* 函数名称: Init
* 函数功能: 初始化
* 参数: application
* 初始化成功返回true,否则返回false
*/
virtual bool Init(IApplication& application) = 0;
/*
* 函数名称: Uninit
* 函数功能: 销毁
* 参数: application
* 初始化成功返回true,否则返回false
* 注意销毁时主程序忽略该函数返回,返回值留待扩展测试使用
*/
virtual bool Uninit(IApplication& application) = 0;
public:
/*
* 函数名称: OnTimer
* 函数功能: 定时器回调函数
* 参数: application
* 参数[handle]: 当前定时器句柄,注意定时器触发时,已经从定时器队列中移出了,用户无需使用该句柄从定时器中再次移出
* 参数[eventid]: 定时器id
* 参数[wparam]: 定时器回调参数
* 参数[lparam]: 定时器回调参数
* 初始化成功返回0,否则返回-1
*/
virtual int OnTimer(IApplication& application, const GooTmHandle& handle, unsigned long eventid, void* wparam = NULL, void* lparam = NULL) = 0;
/*
* 函数名称: GetPkgLen
* 函数功能: 获取接受数据包包长
* 参数: application
* 参数[buffer]: 接受缓存
* 参数[dat_len]: 数据报长度
* 参数[isclient]: 是否客户端传来数据报
* 初始化成功返回>=0,否则返回-1
*/
virtual size_t GetPkgLen(IApplication& application, const unsigned char* buffer, const size_t& dat_len, bool isclient) = 0;
/*
* 函数名称: OnReceive
* 函数功能: 每当引擎成功接收一个数据报后,调用该函数.
* 参数: application
* 参数[session]: 用户会话
* 参数[buffer]: 数据报
* 参数[isclient]: 是否客户端传来数据报
* 初始化成功返回=0,否则返回-1
*/
virtual int OnReceive(IApplication& application, IGooSession* session, const IGooBuffer& buffer, bool isclient) = 0;
/*
* 函数名称: OnFinish
* 函数功能: 每当引擎成功发送一个数据报后,调用该函数.
* 参数: application
* 参数[session]: 用户会话
* 参数[buffer]: 数据报
* 初始化成功返回=0,否则返回-1
*/
virtual int OnFinish(IApplication& application, IGooSession* session, const IGooBuffer& buffer) = 0;
/*
* 函数名称: OnClose
* 函数功能: 用户会话断开,可能是因为超时
* 参数: application
* 参数[session]: 用户会话
* 参数[isclient]: 是否客户端传来数据报
* 初始化成功返回=0,否则返回-1
*/
virtual int OnClose(IApplication& application, IGooSession* session, bool isclient) = 0;
};
三、虚拟服务器设计
class IApplication
{
public:
virtual ~IApplication(){}
public:
/*!
* 函数名称: GetWorkPath
* 函数功能: 服务器工作路径
* 注 意: 该接口非线程安全
*/
virtual const TCHAR* GetWorkPath() const = 0;
/*!
* 函数名称: GetCurrentServerId
* 函数功能: 返回服务器唯一标志符
* 注 意: 该接口非线程安全
*/
virtual unsigned short GetCurrentServerId() const = 0;
/*!
* 函数名称: GetSessionManager
* 函数功能: session容器
* 注 意: 该接口非线程安全
*/
virtual IGooSessionManager& GetSessionManager() = 0;
/*!
* 函数名称: GetConfig
* 函数功能: 系统配置读取接口
* 注 意: 该接口非线程安全
*/
virtual IGooConfig& GetConfig() = 0;
/*!
* 函数名称: GetServerManager
* 函数功能: 服务器信息管理
* 注 意: 该接口线程安全
*/
virtual IGooServerManager& GetServerManager() = 0;
/*!
* 函数名称: GetLog
* 函数功能: 系统日志接口
* 注 意: 该接口非线程安全
*/
virtual IGooLog& GetLog() = 0;
/*!
* 函数名称: GetTimer
* 函数功能: 用户层定时器接口
* 注 意: 该接口非线程安全,该接口为用户定时器,用户层可以回调
*/
virtual IGooTimer& GetTimer() = 0;
/*!
* 函数名称: Release
* 函数功能: 释放资源
* 注 意: 该接口非线程安全
*/
virtual void Release() = 0;
};
Window平台下服务引擎设计我采用的是多线程设计模式,关于线程池的管理非常的简单,这里就不多费笔墨,我们仅讨论虚拟服务器的设计。
通过开放给用户层接口,我们可以发现,系统内核层每次回调用户接口的时候都回传入一个IApplication对象,该对象是虚拟服务器的全局信息,其中包括的主要功能我们可以通过上面代码注释了解。
四、定时器驱动设计
class IGooTimer
{
public:
virtual ~IGooTimer(){}
public:
/*!
* 函数名称: Register
* 函数功能: 注册定时器
* 参数[eventid]: 定时器id
* 参数[tm_split]: 每个几秒钟触发一次,注意我们系统的定时器只能精确到秒
* 参数[wparam]: 定时器触发回调参数
* 参数[lparam]: 定时器触发回调参数
* 函数返回: 注册失败返回INVALID_TM_HANDLE, 否则返回值大于0,注意 0 为系统保留
*/
virtual GooTmHandle Register(unsigned long eventid, const time_t& tm_split, void* wparam = NULL, void* lparam = NULL) = 0;
/*!
* 函数名称: UnRegister
* 函数功能: 注销指定定时器
* 参数[handle]: 定时器句柄
*/
virtual void UnRegister(const GooTmHandle& handle) = 0;
/*!
* 函数名称: LoopTimer
* 函数功能: 定时器主体函数
* 参数[usr_interface]: 用户层钩子函数,当有定时器触发时调用该接口中的OnTimer接口
* 注 意: 该函数由系统内核层调用,用户层无需调用该接口
*/
virtual time_t LoopTimer(IGooInterface* callback) = 0;
/*!
* 函数名称: Clear
* 函数功能: 清除所有定时器
*/
virtual void Clear() = 0;
};
我想各位开代码就该了解了定时器的所有功能,有windows编码习惯的人,可以将Register理解为SetTimer,UnRegister理解为KillTimer。
每次注册返回一个定时器句柄,本来想根据windows的设计习惯,返回值直接采用参数eventid,作为返回,但是考虑到一个因素就是,一个虚拟服务器下,可能存在多个会话有注册了eventid定时器服务器,这是考虑到每个事件必须具有唯一性的原理,我们采用内核层自动生成一个句柄来标志定时器事件的唯一性,而不是用过参数eventid来标识事件的唯一性,这样做的好处就是用户层在做编码设计时具有足够的灵活性。
这里需要注意的是LoopTimer接口,正常情况下由内核层调用,用户层无需关心,每当事件驱动促发时,就调用一下该接口,同时回调用户层接口,并返回下一个定时器促发需要等待时间,所以用户层在调用该接口是须慎用。后期会考虑在IGooTimer上再做一层继承把LoopTimer给隐藏到内核层,这样用户层即便存在无用的可能,也看不到该接口。
五、io模型设计
class IGooIOHandle
{
public:
virtual ~IGooIOHandle(){}
public:
virtual int Read(IGooBuffer& buffer, int offset, int len) = 0;
virtual int Write(const IGooBuffer& buffer, int offset, int len) = 0;
virtual int RegisterCompletionFunction(LPWSAOVERLAPPED_COMPLETION_ROUTINE fun) = 0;
virtual OVERLAPPED* GetOverLappedHandle() = 0;
virtual int Close();
};
上面的代码没有注释,但是我想熟悉window编码的人,都该了解大致意思了,这套作接口有一个优化方案,目前在做灵活性测试,到时候会给出一个最终版本的iohandle模型接口。
六、会话(session)模型设计
class IGooSession
{
public:
virtual ~IGooSession(){}
public:
virtual bool IsValid() const = 0;
virtual SOCKET GetHandle() const = 0;
virtual unsigned __int64 GetUniqueID() const = 0;
virtual bool IsTimeout() const = 0;
virtual size_t GetRestSlip() const = 0;
virtual void Refresh() = 0;
virtual IGooBufferQueue* GetRecvBufferList() = 0;
virtual IGooBufferQueue* GetSendBufferList() = 0;
virtual int PostRecv() = 0;
virtual int PostSend() = 0;
virtual void Close() = 0;
};
class IGooSysSession : public IGooSession
{
public:
virtual ~IGooSysSession(){}
public:
virtual GOO_OVERLAPPED* GetWriteLapped() = 0;
virtual GOO_OVERLAPPED* GetReadLapped() = 0;
virtual GOO_OVERLAPPED* GetListenLapped() = 0;
virtual int OnReadOK(IApplication&, IGooInterface* services, unsigned long trans_len) = 0;
virtual int OnWriteOK(IApplication&, IGooInterface* services, unsigned long trans_len) = 0;
virtual bool IsWaitForConnect() const = 0;
virtual void SetRealConnect() = 0;
virtual bool IsClientSocket() const = 0;
};
IGooSysSession 内核层调用,IGooSession用户层调用,如果设计主要是考虑到把某些实现隐藏掉,因为这些功能对用户层来说他不用关心。
由于时间问题,先到此,后续。。。。
- Windows平台下高性能并发服务引擎设计(一)
- 设计高并发下的读服务?
- 高性能mysql笔记(一)并发 事务 引擎
- 互联网公司高并发图片存储服务架构设计一
- 互联网公司高并发图片存储服务架构设计一
- 高并发服务架构设计
- 网站设计高性能高并发
- Apache + tomcat实现高并发负载均衡方案(一)----无Session的平台接口服务
- [Project]Restful高性能服务平台
- 直播平台的高并发架构设计
- 直播平台的高并发架构设计
- 电商抢购服务高并发设计
- 高并发服务设计——缓存
- 高并发服务设计——缓存
- 高并发服务设计—缓存
- 高并发服务设计——缓存
- 高性能高并发服务的瓶颈及突破思路
- 《高性能MySQL》 第一章(并发控制、事务、存储引擎)
- 怎么处理长时间仿真的可观测性问题?(农历10月初六是父亲生日,祝愿老人身体健康,天天开心!)
- Android平台开发-Android keypad map-Android按键事件
- Web应用程序的会话(Cookie)介绍
- BCD以及回车换行
- 查看表空间使用率的一个SQL
- Windows平台下高性能并发服务引擎设计(一)
- View相关属性分析与处理按键事件
- 触动人心——设计优秀的iPhone应用
- 多字节的数用十进制字符串表示
- Ubuntu搭建Python编译环境(Eclipse+PyDev)
- Select For update语句浅析
- PostgreSQL Linux 下的配置
- 我写的一个求2个数之间的质数,结果打印出了非质数和共有几个质数
- 微博系统架构