分享
 
 
 

面向对象,服务器架构,设计模式探讨

王朝other·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

面向对象,服务器架构,设计模式探讨

鹦其鸣声,求其友矣

原著:吕跃强 版权申明:完全属于吕跃强,任何转摘和引用必须指明出处

主 要 内 容

n 1 服务器本身的架构

n 2 设计模式,面向对象在服务器开发中的应用

参考:

网络的基础架构: ACE

高效的并发服务器结构: apache(session独立性较高)

特殊应用服务器 : darwin 流媒体服务器,

1 服务器架构的探讨

1.1迭代vs并发vs混合

迭代:那些对每个事件的处理时间短暂、简单。Session处理不复杂,并且可以分解为多个短暂步骤 ,并且分开处理

并发:session复杂。Session中的阻塞不确定,session上下文复杂。如:对某个中转的session处理,收到read请求,然后与数据库交互,然后与加密机交互,然后向服务器提交请求,读取服务器应答,再加密机交互,数据库,然后向客户端回应。像这种建议用多线程。

混合:平时迭代处理,对消耗大的请求并发处理

1.2 多线程VS多进程

n 多线程:效率高,占用资源小。共享地址空间,线程间影响大

n 多进程:效率低,占用资源大。但是安全,稳定性高。

n Apache 是多进程下面的多线程,整合了效率和安全。

1.3 并发分类

n 1.3.1 每个连接pthread_create一次

就是针对每个事件发生时开一个线程处理,处理完了线程退出。这种模式其实效率在有的系统中还是相当可观的,也就是采用原生线程的平台中。

这种模式在一些压力不大的系统中应用还是挺广泛的。而且编成简单。

1.3.2 预创建线程池模式

n 1.3.2.1预创建半同步/半异步(生产者/消费者)模式

由主线程(生产者线程)倾听事件,然后把事件和参数完一个队列里丢。消费者线程读出队列数据进行处理

一般说来主线程处理i/o事件并解析然后再往队列丢数据,然后消费者读出数据进行应用逻辑处理。当然,主线程也可以不处理i/o事件,而把句柄等直接往队列里丢,让消费者来处理i/o和应用逻辑。

优点:简化编程将低层的异步I/O和高层同步应用服务分离,且没有降低低层服务性能。集中层间通信。另外,适合相互交互的session

缺点 :需要线程间传输数据,因此而带来的动态内存分配,数据拷贝,语境切换带来开销。高层服务不可能从底层异步服务效率中 获益。

n 线程池的调度:可以用操作系统信号量或者条件变量的来,也可以自己管理线程对象,然后由程序具体激活某个线程。

这种模式在很多系统中应用非常广泛

半同步半异步框图

1.3.2.2 预创建领跑者/跟随者模式

n 每次允许一个线程leader等待在事件源集合上。同时其他线程follower 排队等候成为领导者的机会。Leader检测到事件后,马上转入follower并提升一个follower为leader,然后直接处理事件这时处于processer角色,处理完成后成为follower

缺点: 实现复杂性和缺乏灵活性

优点:增强了CPU高速缓存相似性,消除了动态内存分配和线程间的数据交换

需要注意的问题

n 确定句柄类型。UDP并发句柄,TCP socket 为迭代句柄。

n 确定句柄集类型。WaitForMultipleObjects() 是并发的,而select是迭代的

n 事件分离和处理,角色转换。底层操作系统可以将事件在内部排队,直到有leader

n 在OLAP系统中应用非常广。

1.4 内存池的管理

n 重载new/delete

譬如在我的CTcpWrRdSocket中,重载了new实现静态内存池

n 参考STL 配置器allocator 建立动态CMemory类。这个工作还没有做

1.5 服务器几个部分

n 配置文件处理

Apache的配置文件处理系统非常值得深究。 在我的框架中就一个简单类。建议自己继承一个以支持XML格式的配置

n 日志处理

(目前我的日志系统是由C库函数实现的。如果你习惯用<<的话也可以重载<<操作符。需要注意的是endl, hex, showbase等流操作子其实函数。没试过带参数的操作子)

n 边界处理socket (类图在包装器模式一节)

n 事件分离 select epoll_wait (类图在包装器模式一节)

n 线程池 (类图在最后)

n 应用逻辑处理

n 另外服务器的某些子系统可进行动态加载 (ace 和apache)

2 面向对象

2.1 设计方法:面向对象 vs 面向过程

一个程序最重要的要求就是能满足需求并且健壮的跑。对于此无论是面向对象和过程都能很好的满足。

误区:面向对象方法设计出来的软件一定比面向过程的具有更高质量。

误区: 只要学好vc++ 就能精通面向对象的设计方法

当然以后面对类似的需求,我们希望快速的高质量的搭建新系统。这样对软件的扩张性和维护性就提出了相当的要求,这时面向对象的设计方法就大行其道了。而面向过程就显得吃力。

误区:只要用了类(有的仅仅是类,就连继承都没有,更不用说多态了),就是面向对象了。

其实用了类只是基于对象编程

n 面向过程一般按照功能进行分解,最后分解成函数。这样在非常大的软件系统中存在极大的耦合(外部变量,函数耦合),并且难于管理,且扩张性和维护性不高。就是变量名和函数名管理就很头痛。而现实世界中的物体往往是属性和行为的复合体。所以面向过程适合那些以功能操作为主,对扩张性要求不高的系统。

n Rational统一过程(RUP):起始,细化,构建,移交的不断重复过程。敏捷开发(XP):其实也就是跌代。这里对象技术至关重要,否则原来的代码无法跌代,得打掉重写。上一个周期的跌代仅是验证了可行性。

n Rup和XP不是培训几周就可以实现的。

2.2 面向对象的原则

n 开闭原则:一个模块对扩张开放,对修改关闭

n 完全替换原则:派生类可完全替换基类

n 非循环依赖原则:包与包直接切忌循环依赖

n 依赖倒置原则:依赖抽象,而不要依赖与具象

n 优先使用聚合,而不是继承

n 为人写代码:代码风格要统一,简洁

开闭原则和依赖倒置原则解释

2.3 面向对象设计

2.3.1 类的粒度:共性 VS 个性

n 日志:日志类的分类根据使用的要求,日志可以远程本地, 滚动 按条,有前缀 无前缀分。远程的还可以TCP UDP分。然后除UDP外所有的类都可以再继承实现一个线程安全的。其实还可以再分。就是这样从类图看就已经非常累赘了。

n 继承的粒度和减少使用者的分枝代码矛盾把握

n 使用聚合减少类的种类(较大不同时)

n 就使用(属性)开关量减少

共性 VS 个性 类粒度的把握

2.3.2 类职责分配

n 通用职责分配软件模式(GRASP):设计原则的总结和概括。

n 9种职责分配模式:专家 创建者 低耦合 高内聚 控制者 多态 纯虚构 中介者 不要和陌生人讲话

2.3.2.1 不要和陌生人讲话

Class CInerDataWkThread

{

private:

Creator * m_ptReactor;

public:

ThreadFunc(void)

{

if( false==m_bIsStatic )

n {

n if( !SetAynCancel() )

n { return -1; }

n }

n while(1)

n {

n Wait();

n //和陌生人CObserver说话了,错误

n m_ptReactor->GetObserver()->EventProcess(&m_tEventPara);

n // 只和m_ptReactor说话,由m_ptReactor负责和CObserver说话,正确

n m_ptReactor->EventNotify();

n }

n return 0;

n }

n }

2.3.2.2 专家:与封装特性一致

这里m_tQueueTData 暴露在两个类中,导致到处是 Lock UnLock代码

根据专家原则,应该对此单独做一个类使其专门完成此职责

2.4 设计模式:变化之道 vs 永恒之美

n 模式:每个模式描述了一个在我们的环境中不断发生的问题,并且描述了解决该问题的核心方案,这样你就可以多次使用这一解决方案,不必重新劳动。

n 模式的组成:包括名称,解决的问题,方案和使用模式的结果。

n 模式的精髓:1 适应变化 2 针对接口编程,而不是实现编程(其实就是virtual + 继承)3 优先使用聚合而不是继承

2.4.1 模式的分类

n 架构模式:1.1 分层模式 1.2 管道和过滤器 1.3 黑板 2.1 C/S p2p B/S 3. MVC

n 设计模式:

n 类模式:工厂方法,适配器,模版方法,解释器

n 对象模式: 抽象工厂,原型模式,单件,桥接 复合 装饰 外观 享元 代理 命令 跌代器 中介者 观察者 职责链 策略

2.4.2 包装器模式: 通一接口VS暴露细节

n 也叫适配器(adapter)

n 定义: 将一个类的接口或一组API转换成用户希望的另外一个接口。

n 标准的可以以继承或聚合的方式实现,推荐聚合

2.4.3 桥接模式

n 一个抽象有多个实现时,通常用继承协调。抽象类定义接口,具体子类则用不同的方式实现,此方法有时不够灵活。继承机制将抽象和实现部分固定在一起。

n 感觉把一一列举变成排列组合,一次一点修改相关全改(举个例子:9个十位数和10个个位数组成90个两位数,不用烈举90个了。我用了10 个数,原来是10-19,现在变为20-29 ,只需1变为2 就可以了)

n 意图:把抽象部分和实现部分分离,使他们可以独立的变化

2.5 观察者模式:间接依赖VS直接依赖

n 谁或何时触发更新,目标的删除,观察多个目标,参数推拉模型

n 观察者在服务器中的变体:显示的指定感兴趣的改变 反应器模式

直接依赖变成间接依赖

2.6单件模式:隐式全局VS显式全局

n 不用释放内存

n 模式介绍:

n 全局变量的头痛

n 自创的多件模式

Class A

{

Public:

Static A *Instance();

~A();

Protected:

A();

Private:

Static A* m_pThis;

}

A *A::m_pThis=NULL;

A *A::Instance()

{

If( NULL==m_pThis)

{ m_pThis = new A(); return m_pThis; }

Else { return m_pThis; }

}

自创的多件模式

class CAnonymSem

{

public:

CAnonymSem();

~CAnonymSem();

static CAnonymSem *GetFirstSingleton(void);

protected:

static CAnonymSem *m_pFirst;

sem_t m_tSem;

};

CAnonymSem *CAnonymSem::m_pFirst=NULL;

CAnonymSem *CAnonymSem::GetFirstSingleton(void)

{

if( NULL==m_pFirst )

{

m_pFirst=new CAnonymSem();

return m_pFirst;

}

else {return m_pFirst; }

}

2.7 模版方法:依赖倒置vs正向依赖

好莱坞原则

class CAppServer

{

public:

void Run(void)

{

Daemon();

SignalInit();

RealRun();

}

protected:

int Daemon();

int SignalInit();

virtual int RealRun()

{ cout<<"hello, in CAppServer::RealRun()"<<endl; }

}

class CMyServer:public CAppServer

{

protected:

int RealRun()

{ cout<<"hello, in CMyServer::RealRun()"<<endl; }

}

main()

{

CAppServer *pMyApp = new CMyServer;

pMyApp->Run();

}

3 我的服务器框架类图

谢 谢 大 家,如有建议请发email到以下信箱:

dellme99@163.com,dellme99@126.com

类图贴不上来,请问如何才能把类图贴上来。

另外,如何才能把源代码贴上来

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有