高性能服务器程序框架——《Linux高性能服务器编程》第8章——读书笔记

1、概述

本章的每个小节都在讲提升服务器程序性能的利器。
在这里插入图片描述

2、服务器模型

2.1 C/S模型

客户端 / 服务器模型。服务器监听客户的服务请求,并利用 I / O复用技术处理请求。

C/S模型非常适合资源相对集中的场合,并且它的实现简单,但其缺点也很明显:服务器是通信的中心,当访问量过大时,可能所有客户都将得到很慢的响应。下面讨论的P2P模型解决了这个问题。

2.2 P2P模型

点对点模型。网络上的每个主机,既是服务的享受者,又是服务的提供者。云计算机群可以看作P2P模型的一个典范。

P2P也有缺点:当用户之间传输的请求过多时,网络的负载加重。而且,主机之间很难发现
所以,实际使用的P2P模型通常带有一个专门的发现服务器,发现服务器通常还提供查找服务(甚至可以提供内容服务),使每个客户端都能尽快地找到自己需要的资源。
在这里插入图片描述
从编程角度来讲,P2P模型可看作C/S模型的扩展:每台主机既是客户端,又是服务器。因此,仍然采用C/S模型讨论网络编程。

3、服务器编程框架

服务器框架,骨架:
Linux服务器程序有很多,他们都有个大致的框架结构,这个骨架由下面4个模块组成:

  • IO处理单元: 接受连接,收发数据(也可能是逻辑单元来干)
  • 逻辑单元: 处理业务逻辑,客户端请求的具体是什么东西
  • 网络存储单元: 存大量数据,可有可无
  • 请求队列: 模块间交互

哎,有了这四个模块,服务器总算是能实现和客户端交互的功能啦!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • I/O处理单元是等待并接受客户端连接的模块,收发数据由后面的逻辑单元完成,但I/O处理单元也能完成该工作。I/O处理单元主要实现负载均衡,他从所有逻辑服务器中选负荷最小的为客户端服务。
  • 逻辑单元通常是个进程或线程。他分析并处理客户数据,向I/O处理单元或直接向客户端发送结果。服务器通常有多个逻辑单元。
  • 网络存储单元不是必须的。他可以是数据库、缓存和文件,甚至可以是台独立的服务器。
  • 请求队列是各个单元通信方式的抽象。

4、I/O模型

????啥玩意?干啥的?为啥存在?
IO,就是输入输出,服务器骨架里有个叫IO处理单元的模块,专门处理服务器数据的输入输出,
IO模型就是 数据输入输出的特定方式,这是前人总结好的,我们只要接受他,学习他就好了。

既然是模型,那就是已经有了大致的框架了,所以书中列出几种各具特色的IO模型。

在这里插入图片描述
五种I/O模型通俗理解
socket阻塞和非阻塞对connect、accept、recv、read、close等函数的影响
socket阻塞与非阻塞,同步与异步I/O模型详解

5、两种高效的【事件处理模式】

????啥玩意?干啥的?为啥存在?
既然是服务器,那肯定要和客户端交互,过程中会发生一些事情,那我们要处理这些事情,保证交互正常进行。
“事件处理模式”指的就是处理这些事情的一系列方法,这些方法都是前人总结好的,咱只要接受,学习就行。

服务器程序通常需要处理三类事件:I/O事件、信号、定时事件。后面章节会详细讨论。下面介绍两种高效的事件处理模式:ReactorProactor

同步I/O模型通常用于实现Reactor模式异步I/O模型则用于实现Proactor模式。不过也可以使用同步I/O方式模拟出Proactor模式。

5.1 Reactor模式

在这里插入图片描述

5.2 Proactor模式

在这里插入图片描述
理解两种事件处理模式
两种高效的事件处理模式(reactor模式、proactor模式),C/C++编码实现

6、两种高效的并发模式

服务器这么大个程序,肯定不能同时只干一件事,所以需要实现并发。
如何并发??前人也帮我们搞好了,我们直接学习就行。

并发编程的目的是让程序 “同时” 执行多个任务。

  • 如果程序是计算密集型的,并发编程没有优势,任务切换使效率降低。
  • 如果程序是I/O密集型的,则程序执行效率显著提升。

从实现的角度说,并发编程主要有多进程和多线程两种方式,后面会详细讨论。

下面主要讨论并发模式。并发模式是指:I/O处理单元多个逻辑单元之间协调完成任务的方法。
服务器主要有两种并发编程模式:

  • 半同步 / 半异步(half-sync / half-async)模式
  • 领导者 / 追随者(Leader / Followers)模式

6.1 半同步 / 半异步模式

半同步 / 半异步模式中的“同步” 和 “异步”与前面的I/O模型中的“同步” 和 “异步”完全不同的概念。

  • 在I/O模型中,“同步” 和 “异步”区分的是内核向应用程序通知的是何种I/O事件(就绪事件还是完成事件),以及 该由谁完成I/O读写(应用程序还是内核)。
  • 在并发模式中
    ——同步:程序完全按照代码顺序执行
    ——异步:程序的执行要由系统事件来驱动。常见的系统事件包括中断,信号等。在这里插入图片描述
    半同步/半异步模式中,同步线程用于处理客户逻辑异步线程用于处理I/O事件

6.2 领导者/追随者模式

领导者/追随者模式是多个工作线程轮流获得事件源集合,轮流监听、处理事件的一种模式。在任意时间点,程序都仅有一个领导者线程,它负责监听IO事件。而其他线程都是追随者,它们休眠在线程池中等待成为新的领导者。当前的领导者如果检测到IO事件,首先要从线程池中推选出新的领导者线程然后处理IO事件。此时,新的领导者等待新的IO事件,而原来的领导者则处理IO事件,二者实现了并发

领导者/追随者模式包含如下几个组件:

  • 句柄集(HandleSet)
  • 线程集(ThreadSet)
  • 事件处理器(EventHandler)
  • 具体的事件处理器(ConcreteEventHandler)在这里插入图片描述

7、有限状态机

8、池

池,就是一组资源的集合。
池提升效率的原理是:以 “空间” 换时间。我们事先预分配好足够的资源,那么程序在使用资源时就可以直接拿,不需要再分配了。

预分配资源的策略有两种:

  • 开始就分配足够多,可以满足任何要求
  • 开始分配一定资源,如果不够用,就再动态分配一点并加入池中

池有很多种

  • 内存池:通常用于socket的接收缓存和发送缓存。对于某些长度有限的客户请求,比如HTTP请求,预先分配一个大小足够(比如5000字节)的接收缓存区是很合理的。当客户请求的长度超过接收缓冲区的大小时,我们可以选择丢弃请求或者动态扩大接收缓冲区。
  • 进程池和线程池:多用于并发编程。当我们需要一个工作进程或工作线程来处理新到来的客户请求时,我们可以直接从进程池或线程池中取得一个执行实体,而无须动态地调用forkpthread_create等函数来创建进程和线程。
  • 连接池:是服务器预先和数据库程序建立的一组连接的集合。当某个逻辑单元需要访问数据库时,它可以直接从连接池中取得一个连接的实体并使用之。待完成数据库的访问之后,逻辑单元再将该连接返还给连接池。

9、避免不必要的数据复制

在这里插入图片描述

10、上下文切换 和 锁

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值