高并发之扩容思路
每个线程都有自己的工作内存,占用内存大小取决于工作内存中变量的多少与大小,随着并发的线程不断增加,占用的内存会越来越多,我们就需要考虑给系统扩容。
方法:
- 垂直扩容:提高系统部件能力,比如增加内存
- 水平扩容:增加更多的服务器
数据库扩容
数显判断你的网站是写操作多还是读操作多的网站,例如博客网站就属于读操作多;相反的,大型网站的订单交易系统,这个系统的主要负载在于处理交易记录,属于写操作多。
多操作扩展:加redis缓存
写操作扩展:加Hbase来实现水平扩展
高并发之缓存思路
如何利用有效的资源来提高吞吐量呢?一个有效的办法就是引入缓存,请求可以从缓存中直接获取目标数据并返回,从而提高响应速度。
缓存的特征:
- 命中率:命中数/(命中数+没有命中数)
- 最大空间:代表缓存中可以存放的最大元素的数量,一旦缓存中元素数量超过这个值,就会触发缓存清空策略,根据特定情况来设置最大空间往往可以提高缓存命中率
- 清空策略:关于redis的数据清空策略见redis知识点
缓存命中率的影响因素
- 业务场景和业务需求:缓存常常适合读多写少的场景
- 缓存的设计(粒度和策略):通常情况下,缓存的粒度越小,命中率越高;另外策略也是一个影响因素,当数据发生变化时,更新缓存比直接移除缓存命中率更高
- 缓存容量和基础设施:缓存容量有限,容易引起缓存失效;采用应用内置的本地缓存容易出现单机瓶颈,采用分布式缓存更容易扩展
高并发下缓存常见问题
具体可以看这篇文章:缓存世界中的三大问题及解决方案
高并发之消息队列思路
现在假设这样一个场景,用户下单成功需要给用户发短信,如果没有消息队列,我们会选择同步调用发短信的接口并等待短信发送成功。现在假设短信接口实现出现了问题或者短信发送短时间内达到了上限,这个时候是选择重试几次还是放弃发送呢?这里的设计会很复杂
如果使用了消息队列,我们选择将发短信的操作封装成一条消息发送到消息队列,消息队列通知一个服务去发送一条短信,即使出现了上述的问题,可以选择把消息重新放到消息队列里等待处理
消息队列的好处:通过上述了例子,我们看到消息队列完成了一个异步解耦的过程,短信发送时我们只要保证短信发到消息队列成功就可以了,接下来就可以去做别的事情;其次,设计变得更简单,在下单的场景下,我们不用过多考虑发送短信的问题,交给消息队列管理就行了,可能短信发送会有延迟,但是保证了最终的一致性
消息队列特性
- 业务无关,只做消息分发
- FIFO,先投递先到达
- 容灾:节点动态增删和消息持久化
- 性能:吞吐量提升,系统内部通信效率提高
消息队列好处
- 业务解耦
- 最终一致性:主要是用记录和补偿的方式来处理;在做所有的不确定事情之前,先把事情记录下来,然后去做不确定的事,它的结果通常分为三种:成功,失败或者不确定;如果成功,我们就可以把记录的东西清理掉,对于失败和不确定,我们可以采用定时任务的方式把所有失败的事情重新做一遍直到成功为止
- 广播:如果没有消息队列,每当一个新的业务接入时,我们都需要连接一个新接口;有了消息队列,我们只需要关系消息是否送到到消息队列,新接入的接口订阅相关的消息,自己去做处理就行了
- 错峰与流控:利用消息队列,转储两个系统的通信内容,并在下游系统有能力处理这些消息的时候再处理这些消息
高并发之应用拆分思路
现在假设有一个股票系统如下:它的功能如图所示,通常在开市期间,股票行情数据量特别大,交易和开户等就稍微差一些,压力很小;如果此时股票行情功能出现了问题,可能会带来整个系统无法使用,此时应用拆分就显得很有必要,可以拆分成类似于交易中心,账户中心,行情中心,通知中心这样的服务;对于行情中心就可以采用扩容思路增加几台服务器来缓解压力。
应用拆分原则
- 业务优先原则
- 循序渐进:拆分和测试二者缺一不可,边拆分边测试
- 可靠测试
微服务
- 分布式服务组成的系统
- 按照业务划分
- 强服务个体,弱通信
- 自动化运维
- 具有高度的容错性
如何使用微服务
- 客户端如何访问这些服务:API Gateway
- 每个服务之间是如何通信的:消息队列
- 如此多的服务如何实现:多个服务节点来做负载均衡
- 服务挂了该如何解决:重试+限流+熔断+负载均衡+系统降级
高并发之应用限流思路
限制一段时间内允许通过的流量
常用的限流方法:
- 限制总并发数
- 限制瞬时的并发数
- 限制时间窗口内的平均速率
限流的算法
- 计数器法
- 滑动窗口
- 漏桶算法
- 令牌桶算法
具体可以看这篇文章:限流算法
高并发之服务降级与熔断思路
服务降级:当服务器压力剧增的时候,根据当前业务情况,对一些服务有策略的降级,以此缓解服务器的压力并保证大部分用户能得到正确的响应(给出一个默认的响应)。
服务熔断:指软件系统里由于某些原因,某些服务出现了过载的现象,为了防止造成整个系统故障,从而采用的一种保护措施
服务降级分类
- 自动降级:1. 超时降级:配置好超时时间和超时重试次数,当超过这些值时降级 2. 失败次数:是一些不稳定的API,当失败调用次数达到一定的值之后自动降级 3.故障降级:比如要调用的远程服务挂掉了,可能是网络故障,http抛出异常的状态码等,这时可以直接降级,返回默认响应 4. 限流降级:当网络流量太大时利用限流来实现降级
- 人工降级:当在某些秒杀业务中,我们可以将非核心服务降级,来保证核心服务的正常运行
服务降级需要考虑的问题
- 哪些服务时核心服务,哪些服务是非核心服务
- 哪些服务支持降级,哪些服务不支持降级
- 降级策略是什么
高并发之数据库分库分表思路
关于数据库的分库分表可以看这篇文章:微服务架构下的数据库分库分表