观极客时间之高并发系统设计40问 后感

与世无争的帅哥 提交于 2019-12-14 07:25:58

文章目录

个人感受

  个人感受很深刻的一点是对大牛的定义,知识深度和广度都很足,而不是说自己有多少年工作经验,除非能力跟工作年龄匹配得上哦~
  其次是一篇好的文章,应该可以让读者有所反思,有所延伸的收获。而不是像里面消息队列篇的用户故事里面将所有东西再总结一次,一个小学生都会从文章总结中心主旨,读过幼儿园的当然要总结先自己的思考,延伸出来的东西才真正的让文章的作用发挥到更大。

个人解毒(du)

  个人将对章节进行总结,并进行相关思考,归纳,balabala…

基础篇 (6讲)

01高并发系统:它的通用设计方法是什么?

总结
应对高并发:Scale-out(横向扩展),缓存,异步

解读

  1. 作者以架构师的角度给我们讲了这3个方法,为啥是架构角度?横向扩展,当你服务器抗不住最习惯做法就是加服务器,加满!那么其次另一个概念:纵向扩展,就是服务器的配置,高配,买~
  2. 缓存:惯用手段,一个redis可以抗10w多并发,针对读多写少场景
  3. 异步:就是解耦的过程。

  这些是从架构师角度出发,那么从开发者角度出发呢?开涛大神说过,高并发三板斧:缓存,熔断,限流

理解
  后面两个大家都很熟悉,淘宝的前方拥堵。都是为了保护服务器做出的措施。

02 | 架构分层:我们为什么一定要这么做?

  分层:大家各自忙自己的东西,像java的低耦合概念。考虑到系统的可扩展性也会相对提高。

03 | 系统设计目标(一):如何提升系统性能?

高性能、高可用、可扩展

  针对高可用谈一下,很多人会想出很完美很流弊的方案。但是你要注意一点,当你引入越多的第三方组件,系统的复杂性越高,高可用性的要求越高。

  举个栗子:如果你用了redis,然后redis崩了,那你主程序跑不了了。高可用性真滴很重要。

04 | 系统设计目标(二):系统怎样做到高可用?

总结

  这里就跟各个组件的部署方式有关系了,mysql主从,redis哨兵,zk选举,so on…做到崩了有人顶替~

05 | 系统设计目标(三):如何让系统易于扩展?

  这里跟分层概念有点像,当你分层之后,就可以针对性进行扩展

07 | 池化技术:如何减少频繁创建数据库连接的性能损耗?

  讲解的是数据库连接池带来的好处。

解读

为啥有池化这东西?因为创建链接是最耗时间的,所以提前讲连接创建好。对资源的控制也有很大的好处。

线程池

  如果你没有十足的把握,不要用线程池。
  阿里的规范:不要使用无界线程池,为啥?这个你要了解一下线程池的工作原理,有个coreThreadCount还有个maxThreadCount,当线程数不满足核心线程数的时候,线程池将创建线程。当线程数大于核心线程数coreThreadCount,将放到队列。当核心线程数+队列数量>maxThreadCount的时候,将使用线程池拒绝策略。线程池拒绝策略有哪些呢?自己百度~
  问题就出在这里,无界队列之后,maxThreadCount也就作废了,这样当你任务很多的时候,空间就被你撑爆,同时cpu也炸了。

  另一个点,线程池的核心线程数如何设置?针对IO密集型,可以使用较多的数量。因为当你执行IO操作的时候,cpu就空闲了。如果是CPU密集型的,将核心线程数设置为cpu数量,效率最高。

  最后一个问题:为啥不能用ExecuteService而要用ThreadPoolExecute?可以去看下源码也是因为无界队列的问题。

08 | 数据库优化方案(一):查询请求增加时,如何做主从分离?

  主从分离,读写分离。这里就扯到性能这一块,不多讲,还有mysql主从同步的方式:binlog。

09 | 数据库优化方案(二):写入数据量增加时,如何实现分库分表?

  当数据表达到千万级别时需要分库分表。之前有位开发同事跟我说分库分表之后唯一索引失效了,所以单表的情况一般没有加。这是很离谱的一种说法。平时开发多大几率遇到分库分表呢?其次逻辑上的唯一你如何保证?代码吗,如果出现并发的情况呢?所以数据库单表的唯一索引是必要的!阿里的代码规范也提到了。

个人提问
  上面有点扯偏了,分库分表蛮多坑的。

  1. 分区键如何取值?它的取值依据是什么?那么它跟hbase的分片键有什么区别?
  2. 使用的框架是什么?是否成熟?中间件还是框架?
  3. 你是否对框架足够的了解熟悉,还是只会使用框架而已。

文章中作者也谈到,如果对框架的不熟悉会导致种种bug。

10 | 发号器:如何保证分库分表后ID的全局唯一性?

  大家很习惯的想到UUID,雪花算法,其实用redis来充当发号器也是obk的。
  其次说一下,大家开发中滥用的情况,单表也使用雪花算法,mysql的主键是聚集索引,物理和逻辑都是顺序的,使用雪花算法其实打破了物理顺序。虽然说影响不大,但是细节很重要,除非是分库分表,分布式环境才使用该算法。

异议
  文中说要引入zk来实现唯一,感觉不引入zk也可以实现唯一,不同机器工作机器id不同,即使同一台机器同个时间后面12位序列号也不同呢

  其次是时钟回摆的问题,我敢问一下谁敢去调服务器的时间呢?who else?所以不必太关注这个。美团唯一id Leaf可以去了解一下。

11 | NoSQL:在高并发场景下,数据库和NoSQL如何做到互补?

  里面提到了NoSQL,面向列,文档的存储。可以说写的性能很强滴,这个要看公司的架构,一般业务都是关系型的,so mysql会比较多,nosql作为性能提高点补充。

演进篇 · 缓存篇 (6讲)

  上一章基本是架构的知识,接下来会越来越多底层。

12 | 缓存:数据库成为瓶颈后,动态数据的查询要如何加速?

缓存
  这个大家都很熟悉,但是你真的会用吗?本人功底也很菜,就不献丑了。
本地缓存
  有分布式缓存redis,为啥还要本地缓存呢?
  原因:分布式缓存需要网络通讯,本地缓存直接返回。多快~

文章中提到guava cache,下面是我的学习笔记

Guava Cache学习笔记.

13 | 缓存的使用姿势(一):如何选择缓存的读写策略?

  上一节引申出了缓存的一致性。

解决方案

  1. Cache Aside(旁路缓存)
  2. Read/Write Through(读穿 / 写穿)策略

  由于习惯是使用第一种方法:读不存在回填redis,写删缓存。

写数据库和删缓存的顺序这里就不展开了,要收费的~

14 | 缓存的使用姿势(二):缓存如何做到高可用?

  涉及到数据的分布:hash分片,一致性hash分片

分布式之一致性hash.

收获

一致性hash存在脏数据的情况。

redis哨兵模式本人不熟悉,就不谈了。

15 | 缓存的使用姿势(三):缓存穿透了怎么办?

分很多情况的穿透

  1. 恶意攻击
  2. redis key集体过期

解决方案

  1. 回填空值
  2. 布隆过滤器,其实bitmap也可以使用

16 | CDN:静态资源如何加速?

就是根据dns就近访问资源,收获甚少,不展开了。

加餐 | 数据的迁移应该如何做?

最后一种方法,比较真实。
根据主从去同步,然后线上停服一段时间,进行同步。

像第一种方法,mysqldump你要更新到什么时候?第二种方法,阿里的canal,一般就代码去解析,解析到天荒地老啊~

演进篇 · 消息队列篇 (6讲)

这一节主要讲mq

17 | 消息队列:秒杀时如何处理每秒上万次的下单请求?

  实质就是使用mq去解耦,有点像微信的回调接口,先返回值,后续再call你结果。

18 | 消息投递:如何保证消息仅仅被消费一次?

这一节讲的是mq的重复消费的问题。

方案

  1. 给消息唯一id处理完写入数据库
  2. 根据锁,乐观锁来控制

文中的伪代码

boolean isIDExisted = selectByID(ID); 
// 判断ID是否存在if(isIDExisted) { 
return; 
//存在则直接返回
}
 else { 
 process(message); 
 //不存在,则处理消息 saveID(ID); 
 //存储ID
 }

网上查看了下mq的重复消费问题:由于onMessage的内部异常或者超时导致的!

幂等性

  说到这一点我就想锤人。肥朝哥说:幂等性是对分布式环境最基本的尊敬。
  你知道为啥我们很多程序没有处理幂等性没有报错吗?因为架构师把组件的重试机制关闭了,因为前端使用按钮的转圈限制了用户的重复点击。一旦小程序端没有控制,或者代码出问题,gg。
  有人反驳我说使用分布式锁,百度都知道,难道我不知道吗?我的意思是一个公司如果没有一套规范,很粗糙也行,比如前端发出请求时要哪些注意,还是说让后端处理幂等性之类的规范。
  其次,如果你的服务做了幂等性,你的上游服务没有幂等,你的操作也白费了。因为源头就是脏数据,到你这来也是脏数据。在我工作半年里面,看过很多项目组在这上面踩过很多坑。

19 | 消息队列:如何降低消息队列系统中消息的延迟?

  讲的是mq的性能问题,监控消息队列堆积数量,增加客户端数量,不过不一定有用。

演进篇 · 分布式服务篇 (9讲)

21 | 系统架构:每秒1万次请求的系统要做服务化拆分吗?

  这里讲服务拆分的问题,可以采用DDD去拆分。
  其次是阿里的中台概念,讲公共的部分抽象出来,有些人说只是服务拆分过头,合并一下的玩笑,其实中台的意义还是存在的,关系到架构的合理性,不细说。

23 | RPC框架:10万QPS下如何实现毫秒级的服务调用?

  主要讲RPC的知识,将http封装,序列化和反序列化。
  其中涉及到代理的概念,我们公司用的最多的是Fegin

个人学习总结

手写rpc简单demo以及相关学习思考.

24 | 注册中心:分布式系统如何寻址?

  Eureka,Nacos等等
  Eureka其中涉及到读缓存和写缓存,加快注册,拉服务信息的速度。
  在Dubbo微服务中,会使用zk为注册中心,这里面使用zk的节点的原理以及节点变更时间来更新注册信息。

25 | 分布式Trace:横跨几十个分布式组件的慢请求要如何排查?

  这个也是我吐槽蛮多的,链路监控,也可以是APM,应用性能检测。
  比如A调B,调C,你怎么知道那个服务报错,哪个服务最慢。

方案

  1. 各种框架,skywalk,pinppoint等等
  2. 在网关给请求打印traceId,以及请求的顺序先后

26 | 负载均衡:怎样提升系统的横向扩展能力?

nginx,lvs

负载算法

  1. 轮训
  2. 权重
  3. so on

27 | API网关:系统的门面要如何做呢?

zuul,gateway等等

zuul
  由责任链构成,pre routing filter(路由前过滤器)、routing filter(路由过滤器)和 after routing filter(路由后过滤器)

针对不同的业务就行改造,一般开发不会碰到的,西西~

这里涉及到了动态路由,就是不需要重启去更新配置。

演进篇 · 维护篇 (4讲)

30 | 给系统加上眼睛:服务端监控要怎么做?

这里是日志上报的,ELK了解一下,不过一般都是日志很大的情况使用。

31 | 应用性能管理:用户的使用体验应该如何监控?

也就是APM的介绍

33 | 配置管理:成千上万的配置项要如何管理?

  最想吐槽的点,原生spring cloud config 很难用,默认集成mq去手动更新,还需要加@RefreshScope,但是大家好像都不加,然后全部重启应用来实现更新配置,西西~
  Apollo,Nacos了解一下

总结

  总的来说收获还是蛮多的,在方案上面以及看到了自己的不足,继续加油。本人才疏学浅,有所不足,多多指教~

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!