高并发常用解决方案汇总

1、扩容

扩容思路:

u 垂直扩容(纵向扩展):提高系统部件能力

u 水平扩容(横向扩展):增加更多系统成员来实现

数据库扩容:

读操作扩展:memcache、redis、CDN等缓存

写操作扩展:Cassandra、Hbase

2、缓存

(1) 浏览器:页面静态化

(2) 网络转发:nginx反向代理

(3) 应用服务:集群

(4) 数据库:读写分离、分表分库

小李飞刀_解决方案

缓存特性:

命中率:命中数/(命中数+没有命中数)

最大元素(空间)

清空策略:FIFO(先进先出)、LFU(淘汰一定时期内被访问次数最少的)、LRU(淘汰最长时间未被使用的)、过期时间、随机等

一般来说:项目中开发,使用缓存的时候,都是读多写少;

可以使用复制特性扩展读性能

可以使用客户端分片扩展写性能

缓存分类和应用场景

本地缓存:编程实现(成员变量、局部变量、静态变量)、Guava Cache

分布式缓存:Memcache、Redis

Guava Cache相当于利用hashmap实现了本地缓存的管理

小李飞刀_解决方案

高并发场景下缓存常见问题

u 缓存一致性

u 缓存并发问题

u 缓存穿透问题

u 缓存的雪崩现象

缓存一致性

小李飞刀_解决方案

雪崩:

执行了增删改操作,此时缓存中并没有key所对应的数据(缓存被清除了),那么可能某一时间点,多个请求同时访问,越过缓存服务器直接访问数据库服务器,造成服务雪崩现象;

解决方案:使用锁机制解决该问题

第一个请求去访问数据库拿数据到缓存,然后加锁不让其它的请求向下执行,直到第一个请求将最新的数据库中的数据同步到缓存,再释放锁让其它请求向下执行;

小李飞刀_解决方案

穿透:

因为某些原因,缓存中的数据key对应的值为null,此时请求会穿过缓存服务器直接访问数据库,当然这样最终也会造成雪崩啦;

解决方案:

缓存空对象或者数字

比如key对应的是new HashMap()而不是null;

再比如key对应的是-99,替代了null;

小李飞刀_解决方案

3、消息队列思路

u 业务无关:只做消息分发

u FIFO:先投递先到达

u 容灾:节点的动态增删和消息的持久化

u 性能:吞吐量提升,系统内部通信效率提高

为什么需要消息队列?

【生产】和【消费】的速度或稳定性等因素不一致

消息队列的好处

业务解耦

最终一致性

广播

错峰和流控

事务一致性分两种:

强一致性:分布式事务就是其中一种体现

最终一致性:

总结:

消息队列:处理对别人重要,对自己不用要的事情

4、应用拆分

小李飞刀_解决方案

跑定时任务耗内存,需要单独的定时任务服务器

弊端:管理成本变高,硬件成本变高

应用拆分原则

u 业务优先

u 循序渐进(边拆分边测试)

u 兼顾技术:重构、分层

u 可靠测试

应用拆分注意点

u 应用之间通信:RPC(dubbo等)、消息队列

u 应用之间数据库设计:每个应用都有独立的数据库

u 避免事务操作跨应用

应用拆分涉及到的技术点:Dubbo、SpringCloud

Dubbo相比于SpringCloud的优势:RPC调用远程方法,配置好就像调用本地方法一样无感知,

Dubbo相比于SpringCloud的劣势,不是所有语言都支持tcp协议,而SpringCloud应用之间访问遵循http协议,多数语言都支持http协议;那么SpringCloud微服务架构就更灵活,方便应用的扩展;

RPC与REST架构的区别参考地址:

https://baijiahao.baidu.com/s?id=1617168792520937104&wfr=spider&for=pc

Dubbo架构图

小李飞刀_解决方案

SpringCloud架构图

小李飞刀_解决方案

微服务标准

u 1、分布式服务组成的系统

u 2、按照业务去划分的服务,而不是按技术划分组织

u 3、强服务个体,弱通信

u 4、自动化运维DevOps https://blog.csdn.net/weixin_44221613/article/details/88651494

u 5、高度容错性

u 6、可以快速演化和迭代

使用微服务需要解决的问题

u 1、客户端如何访问服务端

网关:提供统一的服务入口,领各服务对前台透明;

提供安全、过滤、流控的API管理功能

u 2、每个服务之间的通信方式

异步:使用消息队列

同步:使用REST、RPC

u 3、如此之多的服务如何实现

主要解决服务上线下线,服务感知服务发现相关问题,

用到注册中心即可解决这一问题

u 4、服务挂了如何解决

重试、限流、熔断、负载均衡、系统降级

5、应用限流

计算器法

滑动窗口

漏桶算法

令牌桶算法

小李飞刀_解决方案

计数器法

小李飞刀_解决方案

小李飞刀_解决方案

滑动窗口算法

小李飞刀_解决方案

漏桶算法

小李飞刀_解决方案

令牌桶算法

小李飞刀_解决方案

应用限流算法对比

u 计数器法 VS 滑动窗口

相比于计算器算法,滑动窗口算法,每个格子都有一个计数器,所以需要更多的内存空间;精度越高,内存要求就更高;

u 漏桶算法 VS 令牌桶算法

漏桶算法保证了消费端均匀消费;

令牌桶算法限制了请求入口,等桶里的请求被消费完了,才能存放其它的请求

6、服务熔断服务降级

u 自动降级:超时、失败次数、故障、限流

u 人工降级:双杀、双11大促等

触发原因:

u 熔断:下游服务故障

u 降级:从整体负荷考虑

服务降级要考虑的问题

u 核心服务、非核心服务

u 是否支持降级、降级策略

u 业务放通场景、策略

Hystrix

u 在通过第三方客户端访问(通常是通过网络)依赖服务出现高延迟或者失败,为系统提供保护和控制

u 在分布式系统中防止级联失败

u 快速失败(Fail fast)同时能快速恢复

7、数据库切库、分库、分表

数据库瓶颈

u 单个库数据量太大(1T~2T):多个库

u 单个数据库服务器压力过大、读写瓶颈:多个库

u 单个表数据量过大:分表

主库:实时数据查询,及数据更新

从库:非实时数据查询,实际应用读多写少

读库占用资源过多,所有采用读库需要拆分,让不同的从库分担查询压力;

数据库切库

u 切库的基础及实际应用:读写分离

u 自定义注解完成数据库切库 - 代码实现

数据库支持多个数据源与分库

u 支持多数据源、分库

u 数据库支持多个数据源 ~ 代码实现

数据库分表

u 什么时候考虑分表

u 横向(水平)分表 与 纵向(垂直)分表

u 数据库分表:mybatis分表插件 shardbatis2.0

横向:按时间

纵向:按活跃度

冷数据:博客标题、博客内容、作者、时间…

热数据:点击量、评论数…

8、高可用手段

u 任务调度系统分布式:elastic-job + zookeeper

u 主备切换:Apache curator + zookeeper 分布式锁实现

u 监控报警机制

未完待续:以上只是提供了解决思路,后续本人会针对每一种解决方案有相关的代码论证;

当然,因为工作的原因,这个过程可能会耗时比较久!!!

谢谢大家,多多指教!!!
高并发常用解决方案汇总_第1张图片

你可能感兴趣的:(高并发常用解决方案汇总)