本文共 1965 字,大约阅读时间需要 6 分钟。
SPI(Service Provider Interface)主要用于框架中,定义接口后允许不同实现通过特定位置加载实现类。具体实现通过META-INF/services目录下的文件查找,记录实现类全限定名,按需加载以减少资源浪费。
Java SPI在查找实现类时会实例化所有实现,可能导致资源浪费。Dubbo自行实现SPI,通过文件名查找具体实现类,按需加载,更加灵活高效。
Javassist通过生成字节码实现动态代理,效率高且成本低;ASM虽然速度更快,但需要手工生成字节码,成本较高。Javassist成为Dubbo默认选择。
服务暴露在Spring容器刷新后,组装URL,通过ProxyFactory获取Invoker,使用Javassist动态代理实现类,选择Dubbo协议暴露,使用NettyServer创建服务。
支持饿汉式和懒汉式引入,饿汉式在加载完成后引入,懒汉式在注入时引入。引入时通过配置参数组装URL,注册中心订阅提供者信息,使用NettyClient进行远程通信。
调用接口方法生成代理类,通过Cluster路由和负载均衡选择Invoker,远程调用返回结果。服务端通过Map获取Exporter调用实现类,组装响应并返回。消费端通过ID匹配响应,唤醒Future。
Dubbo默认异步通信,通过长连接和线程池复用机制实现异步转同步,减少C10K问题。
封装Invoker屏蔽调用细节,统一暴露接口,便于调用者使用,不管是本地还是远程实现。
本地暴露用于同一JVM内引用本地服务,避免网络通信,提升性能。
确定通信协议、提高网络效率、服务暴露、客户端发现、序列化反序列化。
高效网络通信框架(如Netty),高效序列化框架(如Protobuf),可靠寻址方式(如Zookeeper),支持会话的RPC。
动态代理(CGLib、Javassist)、高效序列化(Kryo、Protobuf)、NIO通信(Netty)、服务注册中心(Zookeeper)。
性能:RPC通过二进制传输效率更高;传输协议:可同时支持TCP和HTTP;负载均衡:RPC自带,HTTP需额外配置;通知:RPC自动通知,HTTP需配置。
Dubbo协议采用单一长连接,压满网卡需要20倍提供者,适合大规模消费者。
单一长连接限制传输能力,需根据网络带宽调整服务协议。
减少连接握手,复用线程池,适合高并发场景。
Dubbo协议默认使用Hessian2,其他协议如RMI和HTTP有不同序列化方式。
本地暴露在同一JVM内无需网络通信,远程暴露需传输IP和端口。
Dubbo、RMI、Hessian、Webservice,分别适用于小数据量、高数据量、文件传输等场景。
应用信息、注册中心、服务协议、缺省值配置、引用配置。
RPC适合内部服务调用,封装更简便;HTTP可读性高但效率较低。
RPC面向过程,REST面向资源,REST支持更多HTTP方法。
Dubbo使用本地缓存,健壮性表现包括监控中心、数据库、注册中心、提供者等多种情况。
通过配置文件或代码中注入指定IP和端口。
通过定期心跳检测或实现可销毁接口实现动态管理。
动态增加或减少服务提供者,负载均衡自动调整。
支持树型目录服务和变更推送,适合分布式服务发现。
Protobuf基于结构化数据,编码效率高,计算复杂度较低,适合高频率、低延迟场景。
通过.proto文件定义结构,生成对应语言的源代码实现序列化反序列化。
使用多个时间轮或分段时间轮,根据任务特性设计,支持海量定时任务。
转载地址:http://pmhfk.baihongyu.com/