RmiProtocol
WebServiceProtocol
Export
Consumer消费服务的过程 把远端服务转为Invoker
ReferenceConfig
Protocol:refer()
DubboProtocol
HessianProtocol
InjvmProtocol
RmiProtocol
WebServiceProtocol
把Invoker转为客户端需要的接口
Invoker
DubboInvoker
HessianInvoker
InjvmInvoker
RmiInvoker
WebServiceInvoker
ProxyFactory:getProxy()
JavassistProxyFactory
JdkProxyFactory
ref
过程:首先ReferenceConfig类的init方法调用Protocol的refer方法生成Invoker实例(如上图中的红色部分),这是服务消费的关键。接下来把Invoker转换为客户端需要的接口
无处不在的Invoker 由于Invoker是Dubbo领域模型中非常重要的一个概念,很多设计思路都是向它靠拢服务消费者Invoker
用户代码通过这个proxy调用其对应的Invoker(DubboInvoker、 HessianRpcInvoker、 InjvmInvoker、 RmiInvoker、 WebServiceInvoker中的任何一个),而该Invoker实现了真正的远程服务调用
服务提供者Invoker
被封装成为一个AbstractProxyInvoker实例,并新生成一个Exporter实例。这样当网络通讯层收到一个请求后,会找到对应的Exporter实例,并调用它所对应的AbstractProxyInvoker实例,从而真正调用了服务提供者的代码
线程模型 过程
Proxy
Client
Transporter
Header -> Codec
Body -> Serialization
Server
Dispatcher
ThreadPool
Implementation
Dispatcher
all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等
direct 所有消息都不派发到线程池,全部在IO线程上直接执行
message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在IO线程上执行
execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在IO线程上执行
connection 在IO线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池
ThreadPool
fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)
cached 缓存线程池,空闲一分钟自动删除,需要时重建
limited 可伸缩线程池,但池中的线程数只会增长不会收缩。(为避免收缩时突然来了大流量引起的性能问题)
4,增强功能
并发控制
连接控制: 连接数控制
分组聚合: 分组聚合返回值,用于菜单聚合等服务
泛化引用: 泛化调用,无需业务接口类进行远程调用,用于测试平台,开放网关桥接等
异步调用
延迟暴露: 延迟暴露服务,用于等待应用加载warmup数据,或等待spring加载完成
延迟连接: 延迟建立连接,调用时建立
隐私传参: 附加参数
5,Dubbo扩展
方法
OSGI
Equinox
Eclipse, HSF
META-INF/MANIFEST.MF
IoC
Spring
META-INF/spring/beans.xml
SPI
java.util.ServiceProvider
JDBC, MessageDigest, ScriptEngine
META-INF/services/com.xx.Xxx
Dubbo SPI Microkernel & SPIProtocol & ProxyFactory & FilterCluster & Directory & Router & LoadBalanceTransporter & Serialization & ThreadPoolTelnetHandler & StatusChecker
6,Dubbo设计原则
模块分包原则
复用度
包中的类应该有同样的重用可能性
紧密协作的类应该放在一个包
对于变化因子,包中的类应全改或全不改
变化应在包内终止,而不传播到其它包
发布的粒度和复用度相同
稳定度
被依赖的包应该总是比依赖者更稳定
不要让一个稳定的包依赖于不稳定包
单向依赖,无环依赖
抽象度
越稳定的包应该越抽象
稳定的包不抽象将导致扩展性极差
抽象的包不稳定将导致其依赖包跟随变化
框架扩展原则 微核 +插件体系
OSGI
IoC
SPI
平等对待第三方
Dogfooding
框架自己的功能也要扩展点实现
甚至微核的加载方式也可以扩展
Autowire
装配逻辑由扩展点之间互助完成
杜绝硬编码的桥接和中间代码
Cascading
层叠扩展粒度,逐级细分
由大的扩展点加载小的扩展点
Law of Demeter
只与×××的扩展点交互,间接转发
保持行为单一,输入输出明确
外置生命周期
API传入参数,SPI扩展点实例
尽量引用外部对象的实例,而不类元
正确:userInstance.xxx()
错误:Class.forName(userClass).newInstance().xxx()
尽量使用IoC注入,减少静态工厂方法调用
正确:setXxx(xxx)
错误:XxxFactory.getXxx(); applicationContext.getBean(“xxx”)
最少化概念模型一致性数据模型
Dubbo统一URL模型
所有配置信息都转换成URL的参数
所有的元信息传输都采用URL
所有接口都可以获取到URL
领域划分原则 服务域
指产品主要功能入口,同时负责实体域和会话域的生命周期管理。
Velocity的Engine
Spring的BeanFactory
实体域
表示你要操作的对象模型,不管什么产品,总有一个核心概念,大家都绕围它转。
Velocity的Template
Spring的Bean
会话域
表示每次操作瞬时状态,操作前创建,操作后销毁。
Velocity的Context
Spring的Invocation
领域模型划分优势
结构清晰,可直接套用
充血模型,实体域带行为
可变与不可变状态分离,可变状态集中
所有领域线程安全,不需要加锁
领域模型线程安全性
服务域
通常服务域是无状态,或者只有启动时初始化不变状态,所以天生线程安全,只需单一实例运行
实体域
通常设计为不变类,所有属性只读,或整个类引用替换,所以是线程安全的
会话域
保持所有可变状态,且会话域只在线程栈内使用,即每次调用都在线程栈内创建实例,调用完即销毁,没有竞争,所以线程安全
接口分离原则 API & SPI
声明式API(Dubbo API):描述需要什么
ServiceConfig
ReferenceConfig
RpcContext
过程式SPI(Dubbo SPI):描述怎么实现
Protocol
Transporter
LoadBalance
API可配置,一定可编程
配置用于简化常规使用
编程接口用于框架集成
API区分命令与查询
命令:无返回值表示命令,有副作用
查询:有返回值表示查询,保持幂等,无副作用
组件协作原则 管道 v.s. 派发
管道
组合行为
主功能以截面实现
比如:Servlet
派发
策略行为
主功能以事件实现
比如: Swing
分布 v.s. 共享
分布
在行为交互为主的系统是适用
状态通过行为传递
共享
在以管理状态为主的系统中适用
状态通过仓库共享
主过程拦截
Web框架的请求响应流
ORM框架的SQL执行
Service框架的调用过程
反例:IBatis2在SQL执行过程中没有设拦截点,导致添加安全或日志拦截,执行前修改分页SQL等,不得不hack源代码
事件派发
过程
执行前后
触发附带非关键行为
状态
值的变化
触发状态观察者行为
关键路径
关键路径
采用拦截链分离职责
保持截面功能单一,不易出问题
非关键路径
采用后置事件派发
确保派发失败,不影响主过程运行
协作防御
可靠性分离
可靠操作
不可靠操作 (尽量缩小)
状态分离
无状态
有状态 (尽量缩小)
不可变类 (尽量final)
状态验证
尽早失败
前置断言 + 后置断言 + 不变式
异常防御,但不忽略异常
异常信息给出解决方案
日志信息包含环境信息
降低修改时的误解性,不埋雷
避免基于异常类型的分支流程
保持null和empty语义一致
功能演进原则 开闭原则
对扩展开放
对修改关闭
软件质量的下降,来源于修改
替换整个实现类,而不是修改其中的某行
增量式 v.s.扩充式
Dubbo增量式扩展
Remoting
Transport:
单向消息发送,抽象Mina/Netty
Exchange:
封装Request-Respose语义
调用两次单向消息发送完成
RPC
Portocol:
协议实现,不透明,点对点
Cluster:
将集群中多个提供者伪装成一个
Proxy:
透明化接口,桥接动态代理
在高阶附加功能
尽可能少的依赖低阶契约,用最少的抽象概念实现功能
当低阶切换实现时,高阶功能可以继续复用
7,Dubbo编码约定
异常和日志:
尽可能携带完整的上下文信息,比如出错原因,出错的机器地址,调用对方的地址,连的注册中心地址,使用Dubbo的版本等。
尽量将直接原因写在最前面,所有上下文信息,在原因后用键值对显示。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
如何快速更新自己的技术积累?
- 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
- 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
- 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
- 学习以后不知道有没有学成,则可以通过面试去检验。
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
知道该从何学起的朋友,同时减轻大家的负担。**[外链图片转存中…(img-kbia88tL-1712188576654)]
[外链图片转存中…(img-EpL1K4bj-1712188576654)]
[外链图片转存中…(img-SqRplDPV-1712188576655)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
如何快速更新自己的技术积累?
- 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
- 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
- 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
- 学习以后不知道有没有学成,则可以通过面试去检验。
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目
[外链图片转存中…(img-P8hp4obI-1712188576655)]
[外链图片转存中…(img-dn1JHYav-1712188576655)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!