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 监控报警机制
未完待续:以上只是提供了解决思路,后续本人会针对每一种解决方案有相关的代码论证;
当然,因为工作的原因,这个过程可能会耗时比较久!!!