前言
在面试中经常被问到高并发高可用的问题,所以想对这方面做下整理。事实上真正接触过高并发的程序员是不多的,我也没有,但虽然没接触,却是应该去了解的,因为这涉及到很多东西,能牵扯到技术栈的各个部分。
问题
常见的问题有:
- 一个查询很慢的接口你要如何去优化?
- 设计一个系统架构时你要考虑什么?
- 如何将一个系统改造成高并发高可用的架构? 等等........
高并发的参考指标
高并发不能只看数字,要看具体的业务场景。对于高并发而言,产品类型不同,会有不同的衡量指标。以电商系统为例,商品浏览看得是 QPS,订单模块则是看得 TPS。同时,还需要关注活跃的用户量等等
高并发优化实践
- 单机性能优化
- 编写复杂的压测脚本,自动实现不同模块的压测任务
- hashmap导致死循环,不带缓存的文件 IO 流去读取文件
- 优化数据库
- 缓存数据一致性
- 使用负载均衡去分担高并发的压力
- 根据业务需要对负载算法进行调整,比如访问需求更大则转发量更多
- 使用中间件
- 本地调用改成RPC远程调用
- 模块间调用使用MQ进行消息传递
- 放在关系数据库的频繁访问的数据存在NOSQL数据库(NoSQL无需事先为要存储的数据建立字段,更灵活)
高并发通用的设计方法有两种:横向扩展和纵向扩展
- 纵向扩展是为了提升单机的处理能力,硬件方面通过加内存、 CPU核数、存储容量、或者将磁盘 升级成SSD 等堆硬 件 的 方 式 来 提升,软件方面使用缓存减少IO次数,使用并发或者异步的方式增加吞吐量
- 横向扩展是通过集群部署以进一步提高并发处理能力
- 做好分层架构: 动静分离,反向代理,Web层API网关,业务服务层可以拆成微服务, 存储层可以是异构数据库(关系型与非关系型),主从库
- 各层进行水平扩展
具体的实践
- 高性能实践
- 集群部署
- 多级缓存
- 分库分表和索引优化,使用es解决复杂查询
- 考虑NoSQL的使用
- 异步化
- 限流(根据业务考虑)
- 流量削峰,使用MQ承接流量
- 并发处理,使用多线程将串行逻辑并行化
- 减少IO次数
- 使用池化技术,http请求池,数据库连接池,线程池
- JVM优化,新生代和老年代大小与GC算法选择
- 锁选择,读多写少使用乐观锁,考虑分段锁减少锁冲突
- 高可用实践
- 接口层面的超时设置、重试策略和幂等设计。
- 灾备演练
- 对等节点的故障转移
- 监控报警
- 日志系统
- MQ场景的消息可靠性保证
- 限流和降级:保证核心服务,牺牲非核心服务
- 高扩展实践
- 合理的分层架构:微服务
- 存储层拆分,分库分表
- 业务层拆分
参考链接
这篇文章写得很简单,只是看了文章,列了一些点,没有详细展开,也是因为我现在还是了解的不够清楚,日后随着经验的积累会慢慢完善,阐述清楚