博客信息

高并发常用解决方案汇总

发布时间:『 2019-11-25 22:48』  博客类别:解决方案  阅读(867)

1、扩容

扩容思路:

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

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

 

数据库扩容:

读操作扩展:memcacheredisCDN等缓存

写操作扩展:CassandraHbase


2、缓存

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

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

(3) 应用服务:集群

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


小李飞刀_解决方案

 

缓存特性:

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

最大元素(空间)

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

 

 

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

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

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

 

 

缓存分类和应用场景

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

分布式缓存:MemcacheRedis

 

 

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


小李飞刀_解决方案

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

缓存一致性

缓存并发问题

缓存穿透问题

缓存的雪崩现象

 

 

缓存一致性


小李飞刀_解决方案

雪崩:

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

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

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


小李飞刀_解决方案


穿透:

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

解决方案:

缓存空对象或者数字

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

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


小李飞刀_解决方案


3、消息队列思路

业务无关:只做消息分发

FIFO:先投递先到达

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

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

 

为什么需要消息队列?

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

 

 

消息队列的好处

业务解耦

最终一致性

广播

错峰和流控

 

事务一致性分两种:

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

最终一致性:

 

总结:

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


4、应用拆分

小李飞刀_解决方案

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

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

 

 

应用拆分原则

业务优先

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

兼顾技术:重构、分层

可靠测试

 

 

应用拆分注意点

应用之间通信:RPCdubbo等)、消息队列

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

避免事务操作跨应用

 

应用拆分涉及到的技术点:DubboSpringCloud

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

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

 

RPCREST架构的区别参考地址:

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

  

Dubbo架构图

小李飞刀_解决方案


SpringCloud架构图

小李飞刀_解决方案


微服务标准

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

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

3、强服务个体,弱通信

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

5、高度容错性

6、可以快速演化和迭代

 

 

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

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

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

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

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

异步:使用消息队列

同步:使用RESTRPC

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

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

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

4、服务挂了如何解决

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


5、应用限流

计算器法

滑动窗口

漏桶算法

令牌桶算法

小李飞刀_解决方案


计数器法

小李飞刀_解决方案


小李飞刀_解决方案


滑动窗口算法

小李飞刀_解决方案


漏桶算法

小李飞刀_解决方案


令牌桶算法

小李飞刀_解决方案


应用限流算法对比

计数器法 VS 滑动窗口

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

漏桶算法 VS 令牌桶算法

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

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


6服务熔断服务降级

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

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

 

触发原因:

熔断:下游服务故障

降级:从整体负荷考虑

 

 

服务降级要考虑的问题

核心服务、非核心服务

是否支持降级、降级策略

业务放通场景、策略

 

 

Hystrix

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

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

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


 

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

数据库瓶颈

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

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

单个表数据量过大:分表

 

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

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

 

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

 

 

数据库切库

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

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

 

 

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

支持多数据源、分库

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

 

 

数据库分表

什么时候考虑分表

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

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

 

横向:按时间

纵向:按活跃度

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

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


 

8、高可用手段

 

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

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

监控报警机制


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

当然,这个过程可能会耗时比较久!!!


关键字:     解决方案       高并发  

备案号:湘ICP备19000029号

Copyright © 2018-2019 javaxl晓码阁 版权所有