- 5.1 通过看源码来解决百度不到的问题
- 5.2 SpringBoot框架关键点讲解
- 5.3 SpringBoot启动流程分析
- 5.4 Springboot 启动器和监听器的加载
- 5.5 SpringBoot的Env和profile
- 5.6 容器加载和webserver启动
- 5.7 SpringBoot启动流程总结
- 5.8 Dubbo RPC原理
- 5.9 Dobbo和SpringCloud的区别
- 5.10 dubbo微服务配置
- 5.11 聊一下服务暴露,发现以及调用的过程吧
- 5.12 高效的限流,灵活的熔断
- 5.13 单机限流方案
- 5.14 集群限流方案
- 5.15 如何灵活的熔断
- 5.16 360度微服务监控
- 5.17 二面雷点与坑
5.1 通过看源码来解决百度不到的问题
你有解决过哪些有挑战的问题,如何解决的
- 查问题
- 搜“百度“
- 自行源代码解决
Jedis TooManyClusterRedirectionsException
太多重定向?
由于槽位是cache信息,节点挂掉或者新增节点,如果数据被设置到错误的master上,则就会出现重定向,并且会跟上最新的节点信息,应该去请求redis-master2,这种就叫重定向。重定向超过阈值就会报这个错误。
节点发生迁移过程中,master1迁移到master2,会发送move让他去master2去找,如果在迁移过程中,当master1会判断是否存在,如果不存在,则会发ask指令,只会去重定向到master2,move是永久重定向,发送到master2,会拒绝,会发送一个asking,代表下一次执行操作,要接收,然后在发送set指令,让他破格去访问正在迁移中的槽位去做更新。
除非是分片极度不稳定,不然应该出现,在非常健康的情况下,也出现了,需要排查源代码来解决。

找到目标异常类,看看哪里使用了。

第一处
第二处,这里做了异常转换,看起来像是为了老版本兼容
在转换的异常类出现的地方也打个断点。和第一个出现的地方打断点。
具体内容

spring配置仅仅设置了1,如果attempts配置成1,直接不会重定向,这是尝试次数不是重定向次数,无论是asking还是remove都会报这个异常。
5.2 SpringBoot框架关键点讲解
读源码的前提
- 先会用框架
- 官方文档要吃透
如何看源代码
- 先看框架架构
- 再看启动流程
- 最后在看执行方法
5.3 SpringBoot启动流程分析
视频内容暂时看不了,网上查查资料补充吧。
5.4 Springboot 启动器和监听器的加载
5.5 SpringBoot的Env和profile
5.6 容器加载和webserver启动
5.7 SpringBoot启动流程总结
- 创建SpringApplication
- 初始化构造器Initializer和listener
- 调用run方法
- 开启定时器StopWatch
- 根据SpringApplicationRunl isteners以及参数来启动环境
- 准备环境配置,注意ConfigFileApplicationL istener是用来加载properties文件的
- 打印banner
- 创建容器上下文
- prepare准备容器上下文,执行之前的Initializer初始化, 并load主bean
- refresh容器.上下文, 里面onRresh可以启动web server
- afterRefresh 执行初始化完成后要做的操作
- listener启动完成
- 关闭计时器
- 打印启动时间
5.8 Dubbo RPC原理
Dubbo RPC调用基本原理
Dubbo的原理
- 注册中心
- 提供者
- 消费者
- 控制台admin
- 监控中心
Dubbo的线程模型
- IO线程池:主要用来出来io recv和send的请求,每个io线程池内所处理的连接,是不固定的,但是每个连接只能被io线程池中固定的一个io线程处理。
- 业务工作线程池:大部分写dubbo的service回调,以及service的实现,就是在业务工作线程池中去跑的
- Boss线程:用来监听所有的连接信息,并且将连接内容丢给io的线程池,同时可以用来accpet连接。

BOSS现成就是调用select讲socket分配给io线程去处理。发送rpc请求的时候,会被io线程做处理,io线程将请求丢给worker线程池,worker线程池是真正做请求的。
Dubbo的线程模型
- all:.一律进工作线程池 ,recv和send都转发给worker线程池,其实比较低效,对于一些简单操作, 这是默认模式。
- direct: 一律IO线程池
- message:除了请求和响应走工作线程池,其他都是IO线程池
- execution: 除了请求,其他都走IO线程池
- connection: 连接和断连进队列,其他都走工作线程池
对工作线程池的配置,Dubbo的线程模型
- fixed: 固定大小线程池
- cached: 缓存线程池,一分钟后释放
- limited: 可伸缩线程池,只会增长不会收缩
- eager: min到max, 超过后进队列,队列满后拒绝
5.9 Dobbo和SpringCloud的区别
Dubbo使用RPC二进制协议,SpringCloud使用HttpRestful

5.10 dubbo微服务配置
Dubbo的配置纬度有哪些
- Application 应用纬度
- Service服务纬度
- Method方法纬度
- Provider 提供者纬度
- Consumer消费者纬度
常见的调用属性有哪些
- Timeout超时消费者>提供者
- Retries失败重试,一般设置成0
- LoadBalance负载均衡策略, 轮询,随机,最少活跃调用,一致性hash
服务发布有依赖怎么办
默认check=”true”,可以通过check= “false”关闭检查
序列化方式
hessian, fastjson, jdk,protobuf, protostuf
如何做降级
mock null

5.11 聊一下服务暴露,发现以及调用的过程吧
- 每个ServiceBean作为一个Applicationlistener会在contextRefresh时做服务export,将自身的服务提供内容发送到注册中心上,并且在本地也暴露服务
- 每个ReferenceBean作为一个ApplicationContextAware会在contextRefresh时做bean的afterPropertiesSet,将从注册中心拉取远端服务,并且在本地生成服务存根
- 调用时通过代理的方式转移到ReferenceBean.上,做对应的服务调用
5.12 高效的限流,灵活的熔断
你是如何解决微服务的异常问题的
- 限流
- 熔断
限流的维度
- 接口限流
- 总限流
限流的单位
- 限并发
- 限QPS/TPS
限流的分类
限制tps/qps,使用令牌桶方案,执行结束之后不释放,异步线程去充令牌数
5.14 集群限流方案
setnx 判断是否有令牌key,这样比较伤性能,最好还是启动另一个java应用来进行令牌填充。
缺点,java每一秒1次,redis缓存ttl时间也是1s钟,没法完全做到时钟上的一致。无论晚了还是早了都会有问题。
简单解决,设置两秒钟,限流改成20
第二种解决方法,不需要java应用,在系统启动之初,往redis插入key值,10个限流,当前的时间戳比如这里是秒。count 和time是hash的两个属性。

具体操作
取一个当前时间和令牌桶里面的时间做一个差值,如果相差1秒可以往里面冲10个令牌,并且设置当前时间是1001秒,如果过了2s也只能发布10个。
如果多个线程都发现令牌不足,就会出现覆盖的情况,用redis乐观锁,开启事务,使用乐观锁去加令牌。
还可以有更优化的方案
Guava limter

效仿雪花算法
一次性拿出来十个令牌,在本地进行扣减令牌,用完再从分布式系统拿取令牌

5.15 如何灵活的熔断
- 失败率触发
- 失败总次数触发
工作线程池是有上限的,B系统等待C系统响应,线程池被占满了,无法出来新的请求,整个集群就会被拖死,基本的处理方式就是设置超时时间,超时就会返回失败结果。
如果还依赖D系统,因为线程池是共用的,导致B系统无法调用D系统,可以配置线程池隔离。B系统内部可以有两个线程池,一个用来调用C系统,一个用来调用D系统。
配置熔断策略,如果频繁触发,就关停调用。

熔断恢复
- 全恢复
- 半转全(放行百分之10,百分之十,有失败继续熔断,如果没有错误,则全开启或者再开启百分之10)
5.16 360度微服务监控
监控常用维度
- 接口
- DB
- Redis
- 硬件( CPU,IO Wait,Memory,,网卡)
监控指标
- 接口TPS/QPS,AVG耗时,95线,99线, 99.99线
- CPU load average
- Memory 占用
- IO Wait
- 网卡占用
监控工具
- 大众点评开源CAT
- Zabbix
只有这些就够了吗
- 客户端监控(埋点监控)
5.17 二面雷点与坑
基础知识纬度
- 知识点的前几个一定要准备充足,回答好
- 忌讳知识点盲区
- 忌讳扯
性能优化及设计
- 全面性的思考问题,先简单说面,然后深入说点,再扩展到面
- 避开不擅长的领域
微服务
- 从应用入手讲解原理
- 通过case挖掘你的价值

