B站教程的笔记
https://www.bilibili.com/video/BV1Zt411K7Gg?p=1
- 基础
《Linux系统编程》
《Linux网络编程》
《跟我一起学C++》 - 服务器设计目标
高性能 (对于大量的并发请求能够及时快速的做出响应)
高可用 (不间断服务、故障转移)
伸缩性 (TCP能跨机器的通信) - 分布式
负载均衡
分布式存储
分布式计算
任何网络系统都可以抽象为C/S结构
一个典型的服务器结构
一个典型的服务器结构.png网络I/O + 服务器高性能编程 + 数据库
网络I/O epoll
数据库往往是瓶颈发生的地方
- 超出数据库连接数
数据库并发连接数10个,应用服务器这边有1000个并发请求,将会有990个请求失败 - 超出时间限制
数据库并发连接数10个,数据库1秒钟之内最多能处理1000个请求,应用服务器这边有10000个并发请求,会出现0-10秒的等待。
1. 超出连接数
如果前端有大量的请求过来都需要访问数据库,数据库连接资源有限,就可能导致请求失败,这时候可以增加一个中间层(数据访问层DAL),让这些请求过来时排队。
DAL既可以跟APP部署在同一台机器上面,也可以作为一台单独的机器来部署。
DAL层.png
DAL 队列服务 + 连接池 DAL与数据库连接可以生成一些连接放到连接池,下一次请求的时候就不需要重新创建与数据库连接,只需要从连接池中取出一个连接进行处理,这样就可以提高响应速度。
2. 超出时限
减轻数据库压力
- 将业务逻辑挪到应用服务器这边,数据库上仅做一些辅助处理(仅可能简单)。因为数据库上进行计算会占用CPU。
- 缓存,下次请求就直接从缓存里取降低数据库的压力
使用缓存会出现问题:
缓存的更新(缓存同步) 缓存time out
-
如果缓存失效,重新去数据库里面查询,再更新缓存,使得缓存与数据库中的数据同步。这种方法实时性比较差。
-
一旦数据库中数据更新,立即通知前端的缓存更新,实时性比较高。
某个业务请求,要改写数据库中的数据,缓冲更新。这里的缓存将查询到的数据存至缓存,将热点数据存至缓存。
如果要改变数据库中的数据,可能直接对数据库进行update操作,DAL再让cache相应数据进行更新。
如果缓存了很大的数据,就可能内存不足。就可能将缓存中不活跃的数据换出内存缓存换页。 换出的算法:FIFO、LRU(最近最少使用)、LFU(最近最不频繁使用)。
实际上缓存的同步,缓存的换页都有开源的产品,比如一些流行的nosql都具有这些功能
nosql,存放非关系数据,一致性要求不那么高。可以把nosql当作缓存来使用
比如redis、memcached都可以当分布式缓存来用。
cache既可以和App(应用服务器)部署在同一台机器上面,也可以部署在不同。 如果部署在同一台机器上面,这个缓存就不是全局的缓存只是局部的缓存。
如果分布式缓存(缓存是全局的各个应用服务器都可以访问):
分布式缓存.png
如果APP足够多,要处理大量的并发。数据库仍然可能会有瓶颈。
比如,对数据库的写操作把数据库就锁住了,使得其它读请求也被阻塞了。
可以将数据库读写分离(一般读操作数量>写操作),主从模式
数据库进行负载均衡,现在主流的数据 库都有replication机制
如果数据容量太大
数据分区:对数据库进行分库分表
- 分库: 数据库可以按照一定的逻辑,把表分散到不同的数据库。(垂直分区)
用户表、业务表、基础相关的表,分为三个这样的主从库。从而每个数据库的容量减小,并发能力增大。
缺点:DAL层会受到影响
- 水平分区:
水平分区:每个数据库都有这些表,只不过将表里的数据进行切分
DAL需要到哪个数据库去找数据也需要一定算法
很容易横向扩展数据库
应用服务器的负载均衡
一个应用服务器可能有多种业务,可以将业务进行分割
添加一个任务服务器,实现负载均衡
任务服务器
①应用服务器被动接收任务
任务服务器能够监视,应用服务器的状态(负载,CPU高、IO高、并发高、内存换页高)。实现应用服务器的时候最好暴露一个接口如HTTP。
查询到这些信息后,选取负载最低(可能有一些算法来确定负载最低)的服务器
分配任务。
②应用服务器主动去任务服务器接收任务进行处理
好处:一个服务器处理完任务后,说明自己是空闲的。然后取任务。这样其实是最科学的。(任务可能有一些特征,任务服务器分配任务不一定公平)
缺点:如果应用服务器只能处理某些应用,就会增加任务 服务器的复杂度。如果所有应用服务器都处理相同任务,就应该让应用服务器主动去领任务。
任务服务器应该能够故障转移(任务服务器应该有两台甚至多台),两个服务器之间通过心跳连接。从而保证服务器的高可用(HA机制)。
哪个层面出现瓶颈就在哪一个层次增加服务器。
服务器的高性能编程:
服务器性能的四大杀手:
- 数据拷贝(服务器内部应该有缓存机制)
- 环境切换(理性创建线程针对线程切换,该不该用多线程,单线程好还是多线程好,单核服务器多线程未必能够提高性能,采用状态机编程反而效率最高。多核服务器,多线程能够充分发挥服务器的性能(但是也应该尽可能的避免线程之间的环境切换)。
- 内存分配 内存池(减少对内存的分配,减少向操作系统申请内存)
- 锁竞争 (有时候应该通过逻辑减低锁的使用,降低锁的竞争)
单核服务器不能并行处理任务,大量任务提交到服务器。不能并行处理,又使用了多线程,就会增加线程之间的切换。
状态机使用单线程切换状态
网友评论