如何获得高并发的经验?(完结)
如何获得高并发的经验?(完结)
先说结论。
1、首先得在自己电脑上鼓捣出 Redis,kafka,dubbo,mycat 等高并发分布式组件的环
境,通过这些环境了解分布式组件的基本 api。
2、为这些分布式组件找个项目场景,证明自己用过,并且解决过实际问题。这里需要指
出的是,单纯背高并发的面试题没用。
3、修改简历,找到高并发面试的机会,然后通过多场面试,不断调整自己讲述高并发项
目经验的水平。这时,如果能直接用高并发的说辞进大厂,那是最好的,如果不能,找个
过渡性的能提供高并发实践的岗位。
4 如果有高并发项目的实践经验,那么后面就不用说了,只要多解决实际问题,高并发技
能一定能很快掌握。这时掌握的高并发技能,就不是单纯的理论说辞和简单的 API 技能
了,而是正宗的高并发项目实践技能。
可以这样说,能否找到高并发项目的实践经验,决定着程序员能否升级到架构师,不过这
不容易。下面讲一下我的一个朋友的经历,二哥经常和他聊天,互相在知乎上点赞,哈哈
哈。
a3297344-f4cf-494c-9231-ae2f84cd8fcb.png
1、17 年年初的时候,朋友在项目组里只用简单的 Spring + JDBC/ORM 做业务,开发是在
windows 上的,接触到的高并发组件,也就是 nginx 和 mysql 集群,加上一些 linux 上部
署和调试组件的经验,并没有高并发组件的使用经验。
相信当下不少球友和我这位朋友一样,只会做 windows 系统上的增删改查,没有任何分
布式组件和高并发经验。
那如果就这样下去,只会基本的增删改查,再干个几年,等年纪上来了,估计连跳槽的机
会都没。
2、后来,这位朋友就去背题,什么 redis 数据结构,dubbo 协议,kafka 流程等等,高并
发情况下防幂等,netty 堆外内存的使用要点,jvm 调优等。凡是和高并发有关的,他基
本都背了一下。然后就开始修改简历,就写,在 xx 项目里,并发量是每秒 xx,用到了
Redis,kafka, dubbo(省略其它分布式组件)等等,然后投简历。
3、由于朋友当时的公司不错,所以投出去的简历很快得到回应,也得到了不少大厂的面
试机会。刚开始面试时,Java、数据库等方面,朋友都是秒通过。但是如果问到分布式组
件,朋友基本就说不上来。
因为朋友背的都是脱离项目的理论,比如 mysql 集群的搭建方法和 redis 数据结构等,面
试官是结合项目问的,比如问,你项目里 Redis 如何确保高可用,用 nginx 部署 spring
boot 项目时,配置文件中注意的要点是什么。由于朋友是单纯背理论,所以就回答不上
来。
4、尝试了几次,朋友意识到单纯背题一定不行,他就在他的电脑上,搭建了诸多高并发
组件的开发环境。虽然组件在项目里都运行在 linux 上,但大多高并发组件都有
windows 版。
当时朋友搭建了 mysql 主从集群,redis 主从集群,rabbitmq, dubbo+zookeeper,nginx,
mycat 等开发环境,了解各组件的基本用法,然后为每个组件找了个项目背景。比如说
redis,朋友就说,我们项目需要缓存员工信息,所以用到了 Redis 里的 xxx API,对应的
Java 代码是什么,类似的,为每个组件都找个了应用背景。
5、这个时候朋友再去面试,在分布式组件方面,就能和面试官有来有去了,甚至还面试
成功了几家小公司。但如果面试官问些实践要点,比如 redis 如何防穿透,redis cluster
的失效转移等,朋友就答不上来。所以朋友当时给面试官的印象是,有分布式组件的使用
经验,也会用分布式组件开发基本的高并发技能,但缺乏系统的用分布式组件实现高并发
的能力。
6、这个时候,朋友就回想起刚开始背题的一些内容,比如 netty 防堆外内存溢出,netty
如何解决半包粘包,redis 如何防穿透,mycat 如何实现读写分离,还有限流和熔断等机
制等。这时朋友才感到,原来这些题目是要等掌握一定高并发说辞后再用,不是一开始就
用的。
明白这些以后就好办多了,这些技能和开发无关,只需要结合项目背景讲下实现要点。
比如以限流为例,先准备一个限流场景,比如公司查询系统每秒只能放 1000 个请求,然
后说下实践要点,无非是 redis+lua,再说下异常情况下怎么处理,无非就超量情况下抛
异常。其它熔断防穿透都要点都按这样准备。
7、请注意,到了这个时间点,朋友的分布式高并发经验,也仅仅是停留在理论层面,但
这个时候我去面试,就能通过用法+实践要点的说辞,成功把自己包装成有高并发项目经
验的人了,后面的面试成功率就高很多了。
不过在这个阶段,为了挑战大厂的岗位,朋友还准备了“项目中解决过的实际问题”。
套路说辞基本一样,首先遇到什么问题,比如 redis 穿透,或 oom 异常,或 kafka 私信堆
积过多,然后说表现,表现无非是系统宕机,卡死,或功能异常,再说如何排查,无非是
通过看日志,日志中遇到什么异常,发现什么问题,最后再说怎么解决的。
网上这种问题一搜一大堆,但网上的说辞大多是纯理论的,得为这些问题找个项目背景。
比如 xx 支付系统遇到 oom 异常,xx 优惠券分发系统遇到死信过多,xx 支付系统遇到
redis 穿透等等。
8、也就是说,通过不断面试,朋友整理了高并发方面的基本用法+实践要点+解决过问题
等说辞。这样虽然还是没高并发项目经验,但已经能确保进大厂了。事实上朋友就这样进
大厂的。
9、进大厂以后,其实朋友的日子很难过,一方面项目组通过面试,认定他有高并发项目
经验,其实他没有,但朋友不这样说,他就只能在原来的公司做基本的增删改查。
这时,朋友除了自己到处查以外,只能一方面厚着脸皮到处问人,另一方面多加班。由于
朋友的项目用到高并发,所以日常工作中有大量的开发,部署,调试机会,平时也经常解
决高并发的问题。
所以朋友的苦日子也就过了 3 个月,后面他不仅能解决高并发的问题,还能参加压力测
试,通过压力测试提升高并发的性能,做到这个程度,朋友才算真正获得了高并发的项目
经验。
10、 掌握高并发经验的红利是相当大的。当朋友掌握高并发经验后,后面找工作,基本
上大多数的技术面试都能过。
二哥就认识一个大佬,叫李智慧,由于有高并发架构的能力,目前在极客 xx 上出了一门
高并发架构课,不知道有球友听说过吗?
1b95839f-68b6-48a8-8005-8e6502824e64.png
如果你也有高并发的经验,也可以进个外企养老,或者是找个小公司做技术总监,不至于
在 35 岁被淘汰。
其实我发现,不少人掌握高并发技能的经历和二哥的朋友很相似。
1、在公司项目没有提供高并发实践机会的前提下,通过背题等,哪怕根据一些所谓的思
维导图,把相关全学了一遍。
2、然后进入到提供高并发实践机会的项目里,得到相关经验。
3、得到高并发的实践机会,通过项目真正掌握高并发的技能。
最后做个总结,高并发能力包括哪些,如何该怎么掌握?这无法通过短短的文章来说明。
但是,你就照着我在上文里给出的步骤,先搭建环境,再掌握分布式组件的基本用法,再
了解高并发的实践要点和解决问题的说辞,你至少能通过面试得到高并发项目的实践机
会。
掌握高并发经验的难点在于得到实践机会,进了项目组,有了实践机会,高并发技巧就不
用我说了,你自己就能知道如何掌握。
前文已经说了,要得到高并发经验,一般得分两步走,第一通过面试得到实践机会,第二
在项目中提升,其实难点在第一点,在零基础前提下,准备高并发方面的面试,确实难。
而通过面试找到项目实践机会后,可能会被人鄙视,也会被领导认为很水,但好歹得到了
能进一步提升的机会。
这里特别提一句,大厂技术面试官一般眼睛都很毒,高并发项目经验,或者高并发方面只
有理论经验的候选人,通过寥寥几个问题就能问出。这点大家不要有侥幸心理。
那在零基础前提下,准备高并发方面的面试的难点在哪里呢?
1、高并发的组件大多是运行在 linux 上,windows 很难搭建环境,没有环境其它就不用
说了。
2、零基础的球友,不知道高并发场景下的分布式组件怎么用,或者只知道如何用简单的
api。由于缺乏项目经验,所以也不知道分布式组件在项目里是怎么用的。
3、在学分布式组件解决高并发问题方面,往往只会孤立地使用某个组件,比如孤立使用
redis 做缓存,孤立使用 rabbitmq 做消息中间件,但现实场景下,往往是综合使用多个分
布式组件,协同解决高并发问题。
4、由于只会理论,没有在项目里接触过高并发开发,所以普遍缺乏分析排查解决高并发
方面问题的经验。
在高并发场景下,往往会用到集群,熔断,限流等。在使用高并发组件的时候,往往也会
踩到不少坑,比如 mycat 方言不对,netty 半包,消息中间件重发等。
大厂面试官往往是会通过这些经常遇到的问题,来确认求职者的高并发方面的经验,而一
些没有高并发项目经验的求职者,在这方面往往是不堪一击的。
下面就以我考核高并发技能的方式,让大家体验一下零项目经验高并发求职者的难度。
1、不问概念,比如 redis 数据结构,netty 重要组件。因为零项目经验的高并发求职者一
定背过。
2、第一层难度,这块问题不固定,我先问,你项目里用到哪些分布式组件,然后指着用
过的分布式组件,问下 Java 环境下的基本 api 和配置。比如用过 Redis 我就问 Jedis 的语
法,用过 Netty 就问 java 层面如何做通讯协议,用过 RabbitMQ 就问 Spring Boot 要做哪
些配置。
我就问你用过的组件,java 里是怎么用的。我发现不少只会背理论的求职者,单纯讲组件
(比如 Redis 或 netty 等)很熟悉,但不知道怎么和 Java 整合,这就说不过去了。
3、第二层难度,有些求职者自己搭建过环境,知道分布式组件的 api。对这些求职者,
我进一步提问,和我说下你用(Redis,Kafka,Netty,nginx 等的)分布式组件的项目场
景,比如你说你用 Redis,你们项目的数据量是多少?你们项目是用单机版 Redis 还是
Redis 集群,如果是单机版 Redis,你们怎么确保高可用?
这样当我结合项目背景问的时候,会发现不少高并发方面的求职者露馅。用他们的话说,
nginx 都是部署在 windows 上的,redis 只用单机版,而且数据量不高。这也能说明不少
求职者没有高并发分布式组件的使用经验。
4、其实如果求职者能结合项目背景说分布式组件的用法,至少能说明有高并发的经验,
在一些高并发要求比较低的岗位,这样的表现,至少在分布式组件这块,就可以过关了。
但如果要面试资深开发或架构,那么还需要问 第三层难度,即在高并发分布式组件方面
解决过哪些问题?这样能证明求职者有一定的高并发项目实践经验。
这方面网上有现成的问题,比如 Dubbo 超时问题,多注册中心问题,Redis 内存溢出问题
等。
不过话说回来,零高并发项目经验的求职者,如果准备方法得当,其实也能通过项目背景
和实际解决过的问题,证明自己有高并发项目经验。
也就是说,哪怕你高并发方面缺乏项目经验,只要好好准备,一样能通过面试得到实践机
会,大家应当有信心。
我在文章里经常用到小二这个角色,那么接下来就以小二为例。
1、小二具备 Spring Boot+JPA 开发经验,这其实也是高并发经验的基础。
2、小二掌握了如何在 windows 环境下搭建 Redis,MyCAT,RabbitMQ,nginx,
dubbo+zookeeper,MongoDB 等组件运行环境的步骤,请注意是 windows 环境,而不是
linux 环境。虽然生产环境中,这些组件都在 linux 环境下,因为大家平时都用
windows,而且这些组件在 windows 和 linux 环境下的开发差异不大。
3、小二环境搭建好以后,首先运行一通 spring boot 整合诸多分布式组件的项目,这样他
就知道怎么用,而不会仅仅知道怎么说。然后我就让他为每个组件,找个业务背景。。
4、会用+结合业务背景使用高并发分布式组件以后,我再让小二背些分布式组件方面的
常用坑,以及常规的使用经验,无非是 dubbo 调用超时,redis 超时,redis 内存溢出,
dubbo 整合 zookeeper 的要点等。这方面不要太深,不用涉及到算法,也不用涉及到底层
技能。而且这方面内容我书里大多也提到。最后我让小二通过秒杀案例,串起来讲多个分
布式组件的使用要点。
5、这个是要点,我让小二准备了不少解决高并发问题的说辞。高并发问题其实也很普
遍,无非是 redis 超时,kakfa 由于重发而导致的不幂等,dubbo 注册中西中心失效等。
这些方面,我让我小弟准备哪些点呢?问题是如何发现(无非是通过日志告警或系统卡顿
发现),如何排查(到 linux 看日志,日志中看到哪些具体的关键字),如何解决(改文
件或改配置)
如果球友想要从事高并发系统的开发岗位,要学习的相关技术其实是很多的,这些技术核
心就是解决高并发情况下如何保持系统的高可用和低延迟。
参考链接:https://www.zhihu.com/question/40609661/answer/2245612049
以 Java 工程师为例,面试中经常会考察的内容包括:
(1) 架构设计:
高可用与稳定性、事务一致性、多副本一致性、CAP 理论。
(2) 相关技术:
多线程(JUC/AQS/线程池)、RPC 调用及框架(如 Thrift)、NIO 及 NIO 框架(如
Netty)、高并发框架(如 Disruptor) 、微服务框架(SpringBoot)、微服务治理
(Spring Cloud)、数据库相关技术(如:索引优化、分库分表、读写分离)、分布式缓
存(如 redis)、消息中间件系统(如 RabbitMQ)、容器技术(如 docker)。
(3) 工具:
系统性能查看(top、uptime、vmstat、iostat)、压测工具(如 ab、locust、Jmeter、
go)、线程分析(如 jps、jstack)等。
当然,我们不可能逐一把这些技能全部掌握,我们可以从一个实际项目入手,不断的把这
些技术用上去,发现哪些知识不足,再去补充相关的知识。
可以从设计一个秒杀系统开始实践,秒杀系统的特点:
(1)瞬时并发量大
秒杀时会有大量用户在同一时间进行抢购,瞬时并发访问量突增 10 倍,甚至 100 倍以上
都有。
(2)库存量少
一般秒杀活动商品量很少,这就导致了只有极少量用户能成功购买到。
(3)业务简单
流程比较简单,一般都是下订单、扣库存、支付订单。
设计秒杀系统的关键点:
(1)限流
由于活动库存量一般都是很少,对应的只有少部分用户才能秒杀成功。所以我们需要限制
大部分用户流量,只准少量用户流量进入后端服务器。
(2)削峰
秒杀开始的那一瞬间,会有大量用户冲击进来,所以在开始时候会有一个瞬间流量峰值。
如何把瞬间的流量峰值变得更平缓,是能否成功设计好秒杀系统的关键因素。实现流量削
峰填谷,一般的采用缓存和 MQ 中间件来解决。
(3)异步
秒杀其实可以当做高并发系统来处理,在这个时候,可以考虑从业务上做兼容,将同步的
业务,设计成异步处理的任务,提高网站的整体可用性。
(4)缓存
秒杀系统的瓶颈主要体现在下订单、扣减库存流程中。在这些流程中主要用到 OLTP 的数
据库,类似 MySQL、Oracle。由于数据库底层采用 B+ 树的储存结构,对应我们随机写入
与读取的效率,相对较低。如果我们把部分业务逻辑迁移到内存的缓存或者 Redis 中,会
极大的提高并发效率。
从 0 到 1 搭建一个秒杀系统,也并不容易,涉及到很多前端、后端、中间件的技术。这个
跟其实是所有公司的工作常态,大部分时间也是在搭架子,真正做技术优化的时间并不
多,经常是在业务量突增或者大促活动来临时,集中搞一波性能优化。
这里推荐一个 GitHub 上的秒杀项目:https://github.com/qiurunze123/miaosha
2bddb273-0630-494b-b866-96b58cd46cca.png
0ac7e532-b08a-467a-922f-47bd3fe7e1ec.png
如果没有实际的高并发项目可做,自己弄个秒杀系统自娱自乐也是不错的。
搭建系统 -> 压测 -> 发现问题 -> 学习知识 -> 优化系统,通过这样的循环,相信你一定既
能体验到学习的乐趣,同时实力也大幅提升。
高并发其实没有那么神秘,讲来讲去就是解决“有限资源与无限用户”的矛盾。你会发现目
前主流的解决方案来来去去无非那几种,你如果有心,即使没做过,但是私底下练习过
了,面试说出来也是可以过的。