RPC框架Dubbo深入分析

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开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

如何快速更新自己的技术积累?

  • 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
  • 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
知道该从何学起的朋友,同时减轻大家的负担。**[外链图片转存中…(img-kbia88tL-1712188576654)]

[外链图片转存中…(img-EpL1K4bj-1712188576654)]

[外链图片转存中…(img-SqRplDPV-1712188576655)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

如何快速更新自己的技术积累?

  • 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
  • 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

[外链图片转存中…(img-P8hp4obI-1712188576655)]

[外链图片转存中…(img-dn1JHYav-1712188576655)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

  • 19
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值