Dubbo基本见解
1、dubbo主要角色
- Provider: 暴露服务的服务提供方。
- Consumer: 调用远程服务的服务消费方。a.订阅注册中心,注册中心广播服务变更,第一次会主动全量pull所有信息,后面增量会被动监听注册中心的消息b.本地会缓存注册信息,注册中心挂了之后会拉本地缓存,保证服务之间可用。
- Registry: 服务注册与发现的注册中心。1、根节点:dubbo2、一级子节点:提供服务的服务名(接口路径)3、二级子节点:固定的四个子节点:分别为:consumers、configurators、routers、providers4、三级内容注册信息存储的是临时节点,当服务变更会广播
- Monitor: 统计服务的调用次调和调用时间的监控中心。
- Container: 服务运行容器。
2、dubbo服务暴露(接口暴露)
a、provider服务暴露过程
- 1、链接zk
Initiating client connection, connectString=zookeeper-1.fcdc.com:2181,zookeeper-2.fcdc.com:2181,zookeeper-3.fcdc.com:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@19ad75e5 - 2、启动Netty服务(用于可以消费者通讯)
[DUBBO] Start NettyServer bind /0.0.0.0:20880, export /172.30.34.5:20880, dubbo version: 2.6.12, current host: 172.30.34.5 - 3、接口暴露在本地服务
[DUBBO] The service ready on spring started. service:【接口路径】
[DUBBO] Export dubbo service 【接口路径】 to local registry, dubbo version: 2.6.12, current host: 172.30.34.5
- 4、接口暴露在远程服务,把接口注册到zk上
[DUBBO] Export dubbo service 【接口路径】 to url dubbo://172.30.34.5:20880/【接口路径】?anyhost=true&application=cmp-biz&bean.name=ServiceBean:【接口路径】&bind.ip=172.30.34.5&bind.port=20880&default.register=false&dubbo=2.0.2&generic=false&interface=【接口路径】&methods=【方法】 [DUBBO] Register dubbo service 【接口路径】 url dubbo://172.30.34.5:20880/【接口路径】?anyhost=true&application=cmp-biz&bean.name=ServiceBean:【接口路径】&bind.ip=172.30.34.5&bind.port=20880&default.register=false&dubbo=2.0.2&generic=false&interface=c【接口路径】&methods=【方法】&pid=10&revision=2.7.2-SNAPSHOT&side=provider×tamp=1709207426440 to registry registry:// zookeeper-1.fcdc.com:2181/com.alibaba.dubbo.registry.RegistryService?application=cmp-biz&backup=zookeeper-2.fcdc.com:2181,zookeeper-3.fcdc.com:2181&dubbo=2.0.2&pid=10®istry=zookeeper×tamp=1709207426440, dubbo version: 2.6.12, current host: 172.30.34.5 - 5、订阅监听接口变更(订阅zk的[configurators]节点)
[DUBBO] Subscribe: provider://172.30.34.5:20880/【接口路径】?anyhost=true&application=cmp-biz&bean.name=ServiceBean:【接口路径】&category=configurators&check=false&default.register=false&dubbo=2.0.2&generic=false&interface=【接口路径】&methods=【方法】&pid=10&revision=2.7.2-SNAPSHOT&side=provider×tamp=1709207427050, dubbo version: 2.6.12, current host: 172.30.34.5 [DUBBO] Notify urls for subscribe url provider://172.30.34.5:20880/【接口路径】?anyhost=true&application=cmp-biz&bean.name=ServiceBean:【接口路径】&category=configurators&check=false&default.register=false&dubbo=2.0.2&generic=false&interface=【接口路径】&methods=【方法】&pid=10&revision=2.7.2-SNAPSHOT&side=provider×tamp=1709207427050, urls: [empty://172.30.34.5:20880/【接口路径】?anyhost=true&application=cmp-biz&bean.name=ServiceBean:【接口路径】&category=configurators&check=false&default.register=false&dubbo=2.0.2&generic=false&interface=【接口路径】&methods=【方法】&pid=10&revision=2.7.2-SNAPSHOT&side=provider×tamp=1709207427050], dubbo version: 2.6.12, current host: 172.30.34.5
b、consumer服务加载过程
- 1、链接zk
Initiating client connection, connectString=zookeeper-1.fcdc.com:2181,zookeeper-2.fcdc.com:2181,zookeeper-3.fcdc.com:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@19ad75e5 - 2、启动Netty服务(用于可以消费者通讯)
[DUBBO] Start NettyServer bind /0.0.0.0:20880, export /172.30.34.5:20880, dubbo version: 2.6.12, current host: 172.30.34.5 - 3、注册到zk上的consumers节点
[DUBBO] Register: consumer://172.30.17.23/com.api.cabinet.CleanTaskFacade?application=cmp-biz&category=consumers&check=false&default.check=false&default.timeout=5000&dubbo=2.0.2&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&side=consumer&timeout=5000×tamp=1709207412512, dubbo version: 2.6.12, current host: 172.30.17.23
- 4、订阅接口zk上providers,configurators,routers节点
[DUBBO] Subscribe: consumer://172.30.17.23/com.api.cabinet.CleanTaskFacade?application=cmp-biz&category=providers,configurators,routers&default.check=false&default.timeout=5000&dubbo=2.0.2&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&side=consumer&timeout=5000×tamp=1709207412512, dubbo version: 2.6.12, current host: 172.30.17.23
- 5、监听providers,configurators,routers(第一次拉取全量)
- 把服务的url信息缓存到本地文件到C: Uers/bobo/.dubbo/dubbo-registry-ipxxx.cache(线程来处理)
- 然后加载到invoker里面,刷新Map<String,Invoker<T>>urlInvokerMap 缓存对象
- 然后加入集群路由cluster.join(directory)
- ProxyFactory$Adpative.getProxy创建代理对象
- 用jdk字段带的InvocationHandler创建对象
[DUBBO] Notify urls for subscribe url consumer://172.30.17.23/com.api.cabinet.CleanTaskFacade?application=cmp-biz&category=providers,configurators,routers&default.check=false&default.timeout=5000&dubbo=2.0.2&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&side=consumer&timeout=5000×tamp=1709207412512, urls: [dubbo://172.30.16.14:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,confirmTaskUnlock,realCleanTaskApply&pid=27&retries=0&side=provider&threads=800×tamp=1705580588547, dubbo://172.30.47.23:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1705580595124, dubbo://172.30.35.8:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,confirmTaskUnlock,realCleanTaskApply&pid=10&retries=0&side=provider&threads=800×tamp=1709126627225, dubbo://172.30.48.23:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,confirmTaskUnlock,realCleanTaskApply&pid=10&retries=0&side=provider&threads=800×tamp=1708851066607, dubbo://172.30.51.32:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,confirmTaskUnlock,realCleanTaskApply&pid=10&retries=0&side=provider&threads=800×tamp=1705580582842, dubbo://172.30.56.29:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1705580583481, dubbo://172.30.37.14:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1709126632152, dubbo://172.30.60.17:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1709126643556, dubbo://172.30.54.22:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,confirmTaskUnlock,realCleanTaskApply&pid=10&retries=0&side=provider&threads=800×tamp=1709126635717, dubbo://172.30.15.20:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1705580586769, dubbo://172.30.25.32:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1705580587619, dubbo://172.30.58.7:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,confirmTaskUnlock,realCleanTaskApply&pid=10&retries=0&side=provider&threads=800×tamp=1709126631834, dubbo://172.30.49.22:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1709126638552, dubbo://172.30.59.13:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&retries=0&side=provider&threads=800×tamp=1709126628743, dubbo://172.30.53.17:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,confirmTaskUnlock,realCleanTaskApply&pid=10&retries=0&side=provider&threads=800×tamp=1705580599362, dubbo://172.30.31.16:20880/com.api.cabinet.CleanTaskFacade?anyhost=true&application=cabinet-state-server&bean.name=com.api.cabinet.CleanTaskFacade&default.register=false&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=11&retries=0&side=provider&threads=800×tamp=1709126631505, empty://172.30.17.23/com.api.cabinet.CleanTaskFacade?application=cmp-biz&category=configurators&default.check=false&default.timeout=5000&dubbo=2.0.2&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&side=consumer&timeout=5000×tamp=1709207412512, empty://172.30.17.23/com.api.cabinet.CleanTaskFacade?application=cmp-biz&category=routers&default.check=false&default.timeout=5000&dubbo=2.0.2&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10&side=consumer&timeout=5000×tamp=1709207412512], dubbo version: 2.6.12, current host: 172.30.17.2 - 6、代理到本地
[DUBBO] Refer dubbo service com.api.cabinet.CleanTaskFacade from url zookeeper://zookeeper-1.fcdc.com:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=cmp-biz&bean.name=com.api.cabinet.CleanTaskFacade&check=false&default.check=false&default.register=false&default.timeout=5000&dubbo=2.0.2&generic=false&interface=com.api.cabinet.CleanTaskFacade&methods=realCleanTaskCancel,realCleanTaskApply,confirmTaskUnlock&pid=10®ister.ip=172.30.17.23&remote.timestamp=1705580588547&retries=0&side=consumer&timeout=5000×tamp=1709207412512, dubbo version: 2.6.12, current host: 172.30.17.23
3、 dubbo的SPI机制
4、dubbo通讯
- dubbo默认是使用单一长连接即消费者与每个服务提供者建立一个单一长连接,即如果有消费者soa-user1,soa-user2,提供者soa-account三台,则每台消费者user都会与3台account建立一个连接,结果是每台消费者user有3个长连接到分别到3台提供者,每台提供者account维持到soa-user1和soa-user2的2个长连接。dubbo这么设计的原因是,一般情况下因为消费者是在请求链路的上游,消费者承担的连接数以及并发量都是最高的,他需要承担更多其他的连接请求,而对提供者来说,承担的连接只来于消费者,所以每台提供者只需要承接消费者数量的连接就可以了,dubbo面向的就是消费者数量远大于服务提供者的情况
- dubbo 缺省协议采用单一长连接,底层实现是 Netty 的 NIO 异步通讯机制
- Dubbo 实现了以下几种调用方式
- 同步调用(默认)
- 异步调用
- 参数回调
- 事件通知
- 同步调用(异步转同步)Dubbo 的底层 IO 操作都是异步的。基于NIO非阻塞实现的,Consumer 端发起调用后,得到一个 Future 对象。对于同步调用,业务线程通过
timeout则是 Consumer 端定义的超时时间。当结果返回后,会设置到此 Future,并唤醒阻塞的业务线程;当超时时间到结果还未返回时,业务线程将会异常返回。异步转同步原理:业务线程DefaultFuture.java里面定义一下重要变量,// 存储netty通讯管道,key=全量id
private static final Map<Long, Channel> CHANNELS = new ConcurrentHashMap<Long, Channel>(); // 存储通讯时的DefaultFuture,key=全量id
private static final Map<Long, DefaultFuture> FUTURES = new ConcurrentHashMap<Long, DefaultFuture>(); // 读写锁
private final Lock lock = new ReentrantLock();
// 信号量,done.await()使当前线程等待(异步转同步关键),done.signal()释放信号线程会重新获得锁
private final Condition done = lock.newCondition();
// 响应实体类,里面会有全局id,在请求和响应都带参
private volatile Response response;
public static void received(Channel channel, Response response) {
try {
// 根据id拿DefaultFuture
DefaultFuture future = FUTURES.remove(response.getId());
if (future != null) {
future.doReceived(response);
} else {
logger.warn("The timeout response finally returned at "
+ (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()))
+ ", response " + response
+ (channel == null ? "" : ", channel: " + channel.getLocalAddress()
+ " -> " + channel.getRemoteAddress()));
}
} finally {
CHANNELS.remove(response.getId());
}
}
- 异步调用NIO future主动获取结果,返回结果放在RpcContext中,判断是异步 后面是可以根据上下文获取到结果
- 响应超时针对请求响应超时,dubbo的实现机制是,在DefaultFuture启动一个守护线程循环监听是否超时,循环睡眠时间Thread.sleep(30),代码如下:
public class DefaultFuture implements ResponseFuture { // 每个DefaultFuture开启一个线程判断是否超时
static {
Thread th = new Thread(new RemotingInvocationTimeoutScan(), "DubboResponseTimeoutScanTimer");
th.setDaemon(true);
th.start();
}
}
5、dubbo的@Adaptive-自适应扩展机制
- dubbo为什么要设计adaptive?
- 注解在类上和注解在方法上的区别?
- a. 为什么AdaptiveCompiler这个类是固定已知的? 因为整个框架仅支持Javassist和JdkCompiler;
- b. 为什么AdaptiveExtensionFactory这个类是固定已知的? 因为整个框架仅支持2个objFactory,一个是spi,另一个是spring;
ExtensionLoader.getAdaptiveExtension方法会直接返回这个类的实例
注解在扩展点接口方法上
含有@Adaptive的方法中都可以根据方法参数动态获取各自需要真实的扩展点。它主要是用于SPI,因为spi的类是不固定、未知的扩展类,所以设计了动态$Adaptive类; ExtensionLoader.getAdaptiveExtension方法会返回动态编译生成的$AdaptiveExtensionLoader.getAdaptiveExtension会动态编译Protocol$Adaptive的类,再通过在动态累的方法中调用ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(spi类);来提取对象。
- Adaptive加载流程
ExtensionLoader.getAdaptiveExtension获取Adaptive扩展。这个方法会首先在扩展点接口的所有实现类中查找类上是否有含有@Adaptive注解,如果有这样的类直接返回该类的实例,如果没有则会查找扩展点接口的方法是否有@Adaptive注解并动态编译一个类实现该接口并扩展这些含有@Adaptive注解的方法。6、dubbo的编码解码
6.1、首先要了解什么是粘包?
发送方原因:
- 当发送方的缓冲区长度大于网卡的MTU(Maximum Transmission Unit,最大传输单元)时,TCP会按照MTU的大小将数据包分成多个数据包进行发送,这也可能导致粘包现象。(2)(4)
接收方原因:
- 接收方如果在短时间内无法完全处理并清空接收缓冲区中的数据,可能会导致后续的数据包被存储在缓冲区中,进而被错误地组合起来作为单个数据包进行处理。
- 应用层的处理速度可能低于TCP接收数据的速度,导致多个数据包被接收并保存在接收缓存中,当应用层尝试读取这些数据包时,它们可能会以粘包的形式呈现给上层应用。(3)
6.2、如何解决粘包问题?
- 消息的定长,例如定100个字节
- 就是在包尾增加回车或空格等特殊字符作为切割,典型的FTP协议
- 将消息分为消息头消息体。例如 dubbo
6.3、client的请求编码
-->NettyCodecAdapter.InternalEncoder.encode-->DubboCountCodec.encode-->ExchangeCodec.encode-->ExchangeCodec.encodeRequest-- >DubboCodec.encodeRequestData
- 第1-2个字节 :就是一个固定的数字,特殊标记
- 第3个字节 :是通讯序列化的标识(默认是Hessian2Serialization序列化)
- 第4个字节 :响应结果码 (request 没有第四个字节)
- 第5-12个字节 :请求id:long型8个字节。异步变同步的全局唯ID,用来做consumer和provider的来回通信标记
- 第13-16个字节 :消息体的长度,也就是消息头+请求数据的长度。
6.4、server的响应编码
- 第1-2个字节 :就是一个固定的数字,特殊标记
- 第3个字节 :是通讯序列化的标识(默认是Hessian2Serialization序列化)
- 第4个字节 :响应结果码 (request 没有第四个字节)
- 第5-12个字节 :请求id:long型8个字节。异步变同步的全局唯ID,用来做consumer和provider的来回通信标记
- 第13-16个字节 :消息体的长度,也就是消息头+请求数据的长度。
6.5、dubbo处理粘包
7、dubbo核心模型Invoker
- 为什么说Invoker是Dubbo核心模型呢?
Invoker是Dubbo中的实体域,也就是真实存在的。其他模型都向它靠拢或转换成它,它也就代表一个可执行体,可向它发起invoke调用。在服务提供方,Invoker用于调用服务提供类。在服务消费方,Invoker用于执行远程调用。
- 服务提供方的Invoker
在服务提供方中的Invoker是由ProxyFactory创建而来的,Dubbo默认的ProxyFactory实现类为JavassistProxyFactory。JavassistProxyFactory创建了一个继承自AbstractProxyInvoker类的匿名对象,并覆写了抽象方法doInvoke。覆写后的doInvoke 逻辑比较简单,仅是将调用请求转发给了Wrapper类的invokeMethod 方法。以及生成 invokeMethod 方法代码和其他一些方法代码。代码生成完毕后,通过 Javassist 生成 Class 对象,最后再通过反射创建 Wrapper 实例。
- 服务消费方的Invoker
在服务消费方,Invoker用于执行远程调用。Invoker是由 Protocol实现类构建而来。Protocol实现类有很多但是最常用的两个,分别是RegistryProtocol和DubboProtocol。当前的Invoker底层依然是NettyClient,但是此时注册中心是集群搭建模式。所以需要将多个Invoker合并为一个,这里是逻辑合并的。实际上Invoker底层还是会有多个,只是通过一个集群模式来管理。所以暴露出来的就是一个集群模式的Invoker。于是进入Cluster.join方法。Cluster是一个通用代理类,会根据URL中的cluster参数值定位到实际的Cluster实现类也就是FailoverCluster。这里用到了@SPI注解,也就是需要ExtensionLoader扩展点加载机制,而该机制在实例化对象是,会在实例化后自动套上Wapper但是是集群模式所以需要Dubbo中另外一个核心机制——Mock。Mock可以在测试中模拟服务调用的各种异常情况,还可以实现服务降级。在MockerClusterInvoker中,Dubbo先检查URL中是否存在mock参数。(这个参数可以通过服务治理后台Consumer端的屏蔽和容错进行设置或者直接动态设置mock参数值)如果存在force开头,这不发起远程调用直接执行降级逻辑。如果存在fail开头,则在远程调用异常时才会执行降级逻辑。可以说注册中心为集群模式时,Invoker就会外面多包裹一层mock逻辑。是通过Wapper机制实现的。最终可以在调用或者重试时,每次都通过Dubbo内部的负载均衡机制选出多个Invoker中的一个进行调用
相关面试资料
1、Dubbo是什么?
Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目。
面试官问你如果这个都不清楚,那下面的就没必要问了。
官网:http://dubbo.apache.org
2、为什么要用Dubbo?
因为是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。内部使用了 Netty、Zookeeper,保证了高性能高可用性。
使用 Dubbo 可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求。
下面这张图可以很清楚的诠释,最重要的一点是,分布式架构可以承受更大规模的并发流量。
下面是 Dubbo 的服务治理图。
3、Dubbo 和 Spring Cloud 有什么区别?
两个没关联,如果硬要说区别,有以下几点。
1)通信方式不同
Dubbo 使用的是 RPC 通信,而 Spring Cloud 使用的是 HTTP RESTFul 方式。
2)组成部分不同
4、dubbo都支持什么协议,推荐用哪种?
dubbo://(推荐)
rmi://
hessian://
http://
webservice://
thrift://
memcached://
redis://
rest://
5、Dubbo需要 Web 容器吗?
不需要,如果硬要用 Web 容器,只会增加复杂性,也浪费资源。
6、Dubbo内置了哪几种服务容器?
Spring Container
Jetty Container
Log4j Container
Dubbo 的服务容器只是一个简单的 Main 方法,并加载一个简单的 Spring 容器,用于暴露服务。
7、Dubbo里面有哪几种节点角色?
8、画一画服务注册与发现的流程图
该图来自 Dubbo 官网,供你参考,如果你说你熟悉 Dubbo, 面试官经常会让你画这个图,记好了。
9、Dubbo默认使用什么注册中心,还有别的选择吗?
推荐使用 Zookeeper 作为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。
10、Dubbo有哪几种配置方式?
1)Spring 配置方式
2)Java API 配置方式
11、Dubbo 核心的配置有哪些?
我曾经面试就遇到过面试官让你写这些配置,我也是蒙逼。。
配置之间的关系见下图。
12、在 Provider 上可以配置的 Consumer 端的属性有哪些?
1)timeout:方法调用超时
2)retries:失败重试次数,默认重试 2 次
3)loadbalance:负载均衡算法,默认随机
4)actives 消费者端,最大并发调用限制
13、Dubbo启动时如果依赖的服务不可用会怎样?
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,默认 check="true",可以通过 check="false" 关闭检查。
14、Dubbo推荐使用什么序列化框架,你知道的还有哪些?
推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。
15、Dubbo默认使用的是什么通信框架,还有别的选择吗?
Dubbo 默认使用 Netty 框架,也是推荐的选择,另外内容还集成有Mina、Grizzly。
16、Dubbo有哪几种集群容错方案,默认是哪种?
17、Dubbo有哪几种负载均衡策略,默认是哪种?
18、注册了多个同一样的服务,如果测试指定的某一个服务呢?
可以配置环境点对点直连,绕过注册中心,将以服务接口为单位,忽略注册中心的提供者列表。
19、Dubbo支持服务多协议吗?
Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。
20、当一个服务接口有多种实现时怎么做?
当一个接口有多种实现时,可以用 group 属性来分组,服务提供方和消费方都指定同一个 group 即可。
21、服务上线怎么兼容旧版本?
可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。
22、Dubbo可以对结果进行缓存吗?
可以,Dubbo 提供了声明式缓存,用于加速热门数据的访问速度,以减少用户加缓存的工作量。
23、Dubbo服务之间的调用是阻塞的吗?
默认是同步等待结果阻塞的,支持异步调用。
Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。
异步调用流程图如下。
24、Dubbo支持分布式事务吗?
目前暂时不支持,后续可能采用基于 JTA/XA 规范实现,如以图所示。
25、Dubbo telnet 命令能做什么?
dubbo 通过 telnet 命令来进行服务治理,具体使用看这篇文章《dubbo服务调试管理实用命令。
telnet localhost 8090
26、Dubbo支持服务降级吗?
Dubbo 2.2.0 以上版本支持。
27、Dubbo如何优雅停机?
Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果使用 kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才会执行。
28、服务提供者能实现失效踢出是什么原理?
服务失效踢出基于 Zookeeper 的临时节点原理。
29、如何解决服务调用链过长的问题?
Dubbo 可以使用 Pinpoint 和 Apache Skywalking(Incubator) 实现分布式服务追踪,当然还有其他很多方案。
30、服务读写推荐的容错策略是怎样的?
读操作建议使用 Failover 失败自动切换,默认重试两次其他服务器。
写操作建议使用 Failfast 快速失败,发一次调用失败就立即报错。
31、Dubbo必须依赖的包有哪些?
Dubbo 必须依赖 JDK,其他为可选。
32、Dubbo的管理控制台能做什么?
管理控制台主要包含:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡,等管理功能。
33、说说 Dubbo 服务暴露的过程。
Dubbo 会在 Spring 实例化完 bean 之后,在刷新容器最后一步发布 ContextRefreshEvent 事件的时候,通知实现了 ApplicationListener 的 ServiceBean 类进行回调 onApplicationEvent 事件方法,Dubbo 会在这个方法中调用 ServiceBean 父类 ServiceConfig 的 export 方法,而该方法真正实现了服务的(异步或者非异步)发布。
34、Dubbo 停止维护了吗?
2014 年开始停止维护过几年,17 年开始重新维护,并进入了 Apache 项目。
35、Dubbo 和 Dubbox 有什么区别?
Dubbox 是继 Dubbo 停止维护后,当当网基于 Dubbo 做的一个扩展项目,如加了服务可 Restful 调用,更新了开源组件等。
36、你还了解别的分布式框架吗?
别的还有 Spring cloud、Facebook 的 Thrift、Twitter 的 Finagle 等。
37、Dubbo 能集成 Spring Boot 吗?
可以的,项目地址如下。
https://github.com/apache/incubator-dubbo-spring-boot-project
38、在使用过程中都遇到了些什么问题?
Dubbo 的设计目的是为了满足高并发小数据量的 rpc 调用,在大数据量下的性能表现并不好,建议使用 rmi 或 http 协议。
39、你读过 Dubbo 的源码吗?
要了解 Dubbo 就必须看其源码,了解其原理,花点时间看下吧,网上也有很多教程,后续有时间我也会在公众号上分享 Dubbo 的源码。
40、你觉得用 Dubbo 好还是 Spring Cloud 好?
扩展性的问题,没有好坏,只有适合不适合
Dubbo基本见解的更多相关文章
- dubbo见解
调用关系说明 服务容器负责启动,加载,运行服务提供者. 服务提供者在启动时,向注册中心注册自己提供的服务. 服务消费者在启动时,向注册中心订阅自己所需的服务. 注册中心返回服务提供者地址列表给消费者, ...
- dubbo学习小结
dubbo学习小结 参考: https://blog.csdn.net/paul_wei2008/article/details/19355681 https://blog.csdn.net/liwe ...
- Dubbo2.7的Dubbo SPI实现原理细节
总结/朱季谦 本文主要记录我对Dubbo SPI实现原理的理解,至于什么是SPI,我这里就不像其他博文一样详细地从概念再到Java SPI细细分析了,直接开门见山来分享我对Dubbo SPI的见解. ...
- 用dubbo时遇到的一个序列化的坑
首先,这是标题党,问题并不是出现在序列化上,这是报错的一部分: Caused by: com.alibaba.dubbo.remoting.RemotingException: Failed to s ...
- dubbo服务提供与消费
一.前言 项目中用到了Dubbo,临时抱大腿,学习了dubbo的简单实用方法.现在就来总结一下dubbo如何提供服务,如何消费服务,并做了一个简单的demo作为参考. 二.Dubbo是什么 Dubbo ...
- 分布式学习系列【dubbo入门实践】
分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...
- Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题
现互联网公司后端架构常用到Spring+SpringMVC+MyBatis,通过Maven来构建.通过学习,我已经掌握了基本的搭建过程,写下基础文章为而后的深入学习奠定基础. 首先说一下这篇文章的主要 ...
- Dubbo 备注
Dubbo是阿里开源的一款服务治理中间件,主要包含如下节点: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. ...
- Dubbo学习小记
前言 周一入职的新公司,到了公司第一件事自然是要熟悉新公司使用的各种技术,搭建本地的环境. 熟悉新公司技术的过程中,首先就是Maven,这个前面已经写过文章了,然后就是Dubbo----公司的服务都是 ...
- Running Dubbo On Spring Boot
Dubbo(http://dubbo.io/) 是阿里的开源的一款分布式服务框架.而Spring Boot则是Spring社区这两年致力于打造的简化Java配置的微服务框架. 利用他们各自优势,配置到 ...
随机推荐
- 【scikit-learn基础】--『回归模型评估』之准确率分析
分类模型的评估和回归模型的评估侧重点不一样,回归模型一般针对连续型的数据,而分类模型一般针对的是离散的数据. 所以,评估分类模型时,评估指标与回归模型也很不一样,比如,分类模型的评估指标通常包括准确率 ...
- 强大的AWS lambda
AWS强大的lambda 自从几年前换工作后,我所参与的项目一直都是基于AWS云服务的架构,我慢慢对serverless的相关基础建设有了一定了解和实践经验.其中lambda是我心中最强大的serve ...
- JVM底层原理
目录 1.类加载器与ClassFileFormate 2.JVM内存模型 3.对象在JVM中的创建与内存分配 4.对象引用与垃圾回收算法 5.JVM垃圾回收 6.G1垃圾回收器 7.ZGC垃圾回收器
- 【二】tensorflow调试报错、TF深度学习强化学习教学
相关文章: [一]tensorflow安装.常用python镜像源.tensorflow 深度学习强化学习教学 [二]tensorflow调试报错.tensorflow 深度学习强化学习教学 [三]t ...
- 操作系统开发:BIOS/MBR基础与调试
这里在实验之前需要下载 Bochs-win32-2.6.11 作者使用的是Linux版本的,在Linux写代码不太舒服,所以最好在Windows上做实验,下载好虚拟机以后还需要下载Nasm汇编器,以及 ...
- Linux 系统Apache配置SSL证书
在Centos7系列系统下,配置Apache服务器,给服务器增加SSL证书功能,让页面访问是不再提示不安全,具体操作流程如下. 1.第一步首先需要安装mod_ssl模块,执行yum install - ...
- workman在线五子棋
一.下载安装workman,地址:https://github.com/walkor/workerman composer require workerman/workerman 二.cd到worke ...
- PHP使用cookie做浏览历史记录
/** * @param $article文章详情 * @param int $count记录数 * tp须引入cookie类 */ function addHistory($article,$cou ...
- 应用--WebApplication
应用--Program中的WebApplication 在6.0,微软团队对于NetCore做了很大的改变,其中有一个改变就是推出了新的托管模型--最小托管模型,使用该模型可以创建最小的web应用.( ...
- WDMyCloud的ssh登陆密码错误
是一个困扰很久的小问题,以至于无法ssh登陆到NAS服务器进行操作. 之前配置是可以直接使用root用户ssh登陆到服务器的,可是后来突然就不行了,无论输入啥密码都是报错: Permission de ...