目录
dubbo面试题(上)
Dubbo面试专题
1. 什么是dubbo
2. Dubbo使用的什么协议?
3. 为什么要用Dubbo进行数据传输?
4. Dubbo的负载均衡策略怎么配置?(官网介绍)
5. Dubbo注册中心怎么配置?
6. dubbo连接注册中心和直连的区别
7. Dubbo在安全机制方面是如何解决的
8. Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?
9. zookeeper是如何保证事务的顺序一致性的
dubbo面试题(下)
dubbo面试题(上)
Dubbo面试专题
1. 什么是dubbo
Dubbo是阿里巴巴SOA服务化治理方案的核心框架,是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
2. Dubbo使用的什么协议?
主要使用协议有
(dubbo 、rmi、hessian、http、webservice、thrift、memcached、redis)
dubbo:
Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
缺省协议,使用基于 mina 1.1.7 和 hessian 3.2.1 的 tbremoting 交互。
l 连接个数:单连接
l 连接方式:长连接
l 传输协议:TCP
l 传输方式:NIO 异步传输
l 序列化:Hessian 二进制序列化
l 适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo协议传输大文件或超大字符串。
l 适用场景:常规远程服务方法调用
rmi:
l 连接个数:多连接
l 连接方式:短连接
l 传输协议:TCP
l 传输方式:同步传输
l 序列化:Java 标准二进制序列化
l 适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件。
l 适用场景:常规远程服务方法调用,与原生RMI服务互操作
Hessian:
l 连接个数:多连接
l 连接方式:短连接
l 传输协议:HTTP
l 传输方式:同步传输
l 序列化:Hessian二进制序列化
l 适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
l 适用场景:页面传输,文件传输,或与原生hessian服务互操作
Http:
l 连接个数:多连接
l 连接方式:短连接
l 传输协议:HTTP
l 传输方式:同步传输
l 序列化:表单序列化
l 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。
l 适用场景:需同时给应用程序和浏览器 JS 使用的服务。
Webservice:
l 连接个数:多连接
l 连接方式:短连接
l 传输协议:HTTP
l 传输方式:同步传输
l 序列化:SOAP 文本序列化
l 适用场景:系统集成,跨语言调用
Thrift
Memcached
Redis
(官网介绍)
3. 为什么要用Dubbo进行数据传输?
一般服务端服务器比较少,消费端有可能会有很多项目或者工程会调用dubbo的接口,而且数据量传输较小且并发量比较高的情况下用dubbo效率会很高。
4. Dubbo的负载均衡策略怎么配置?(官网介绍)
在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。
可以自行扩展负载均衡策略,参见:负载均衡扩展
负载均衡策略有( 随机、轮循、最少活跃调用数、一致性Hash)
Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
一致性 Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
算法参见:/wiki/Consistent_hashing
缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="" value="0,1" />
缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key="" value="320" />
配置
服务端服务级别
<dubbo:service interface="..." loadbalance="roundrobin" />
客户端服务级别
<dubbo:reference interface="..." loadbalance="roundrobin" />
服务端方法级别
<dubbo:service interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>
客户端方法级别
<dubbo:reference interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>
5. Dubbo注册中心怎么配置?
(官网地址)dubbo注册中心配置主要通过<dubbo:registry> 标签进行配置,主要使用Zookeeper做注册中心。 <dubbo:registry address="zookeeper://10.20.153.10:2181" /> 或 <dubbo:registry protocol="zookeeper" address="10.20.153.10:2181" /> 。(详情官网)
多注册中心: Dubbo 支持同一服务向多注册中心同时注册,或者不同服务分别注册到不同的注册中心上去,甚至可以同时引用注册在不同注册中心上的同名服务。(详情官网)
6. dubbo连接注册中心和直连的区别
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,
点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表,
服务注册中心,动态的注册和发现服务,使服务的位置透明,并通过在消费方获取服务提供方地址列表,实现软负载均衡和Failover, 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外,注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
注册中心和监控中心都是可选的,服务消费者可以直连服务提供者
7. Dubbo在安全机制方面是如何解决的
Dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo还提供服务黑白名单,来控制服务所允许的调用方。
8. Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?
可以的,启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用 。 (推荐用法--配置Dubbo缓存文件)
9. zookeeper是如何保证事务的顺序一致性的
zookeeper采用了递增的事务Id来标识,所有的proposal都在被提出的时候加上了zxid,zxid实际上是一个64位的数字,高32位是epoch用来标识leader是否发生改变,如果有新的leader产生出来,epoch会自增,低32位用来递增计数。当新产生proposal的时候,会依据数据库的两阶段过程,首先会向其他的server发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行
其他深入课题:
《超时原理以及应用场景》
《Dubbo开发问题汇总》
《分布式事务TCC》
《基于Dubbo的分布式事务框架 LCN》
《分布式系统互斥性与幂等性问题的分析与解决》
查看原文:http:///?p=129 视频地址(/lecturer/2226)。
dubbo面试题(下)
1. 如果服务注册不上怎么办?
(1) 检查dubbo的jar包有没有在classpath中,以及有没有重复的jar包
(2) 检查有没有重复的配置文件
(3) 检查暴露服务的spring配置有没有加载
(4) 检查beanId或beanName有没有重复
(5) 查看有没有错误日志:
cat ~/output/logs/
(6) 在服务提供者机器上测试与注册中心的网络是否通:
telnet 172.22.3.94 9090
(7) 检查与注册中心的连接是否存在:
netstat -anp | grep 172.22.3.94
(8) 如果是预发布机,检查hosts文件有没有正确绑定:
cat /etc/hosts
(9) 实在不行,开启远程调试:
– (a) 在服务器JVM参数中加入:-Xdebug -Xnoagent -=NONE -Xrunjdwp:transport=dt_socket,address=7001,server=y,suspend=y
注意线上只有7001和8080可以被线下访问,调试端口需用这两个之一,因注册是启动时行为,启动时必需挂起suspend=y
– (b) 在dubbo源码的DefaultRegistryService的registerService()方法中设置断点。
– (c) 在Eclipse的Debug按钮下拉菜单Debug Configurations中的Remote Java Applications中新增远程调试,并设置IP和端口,以及增加dubbo的源码,进行远程Debug调试。
2. 出现RpcException: No provider available for remote service异常怎么办?
表示没有可用的服务提供者,
1). 检查连接的注册中心是否正确
2). 到注册中心查看相应的服务提供者是否存在
3). 检查服务提供者是否正常运行
3. 出现调用超时异常怎么办?
通常是业务处理太慢,可在服务提供方执行:jstack PID > 分析线程都卡在哪个方法调用上,这里就是慢的原因。
如果不能调优性能,请将timeout设大。
4. 出现hessian序列化失败怎么办?
1). 检查服务方法的传入传出参数是否实现Serializable接口
2). 检查服务方法的传入传出参数是否继承了Number,Date,ArrayList,HashMap等hessian特殊化处理的类
5. 出现Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [/schema/dubbo]怎么办?
表示spring找不到<dubbo:...>配置的解析处理器。
通常是Dubbo的jar没有引入,请加入对Dubbo的依赖,或者是ClassLoader隔离,看是否有使用osgi或其它热加载机制。
6. 出现"消息发送失败"异常怎么办?
通常是接口方法的传入传出参数未实现Serializable接口。
7. 出现: cvc-elt.1: Cannot find the declaration of element 'beans'异常怎么办?
表示xsd加载失败,
1). 检查spring版本,如果是spring2.0版本,因为该版本不能读取jar包内xsd,会读取外网的xsd,而线上环境通常不允许访问外网,
可修改/etc/hosts加入:(已将spring的xsd放在公司内部的maven仓库中)
10.20.133.138
spring2.版本不存在此问题,可以考虑升级到2.版本。
2). 检查有没有使用osgi的xsd,如果用了,需要将及其依赖包加进来
8. 项目依赖的三方库与Dubbo所依赖的版本冲突怎么办。
比如,项目使用的spring和与dubbo冲突,
dubbo使用的是spring2.5和commons.pool1.4,
而项目中其它模块依赖的是spring2.0.1和commons.pool1.3。
1). 在Maven中,使用项目根中的dependencyManagement版本仲裁解决:
-
<dependencyManagement>
-
<dependencies>
-
<dependency>
-
<groupId></groupId>
-
<artifactId></artifactId>
-
<version>2.0.1</version>
-
</dependency>
-
<dependency>
-
<groupId></groupId>
-
<artifactId></artifactId>
-
<version>1.3</version>
-
</dependency>
-
</dependencies>
-
</dependencyManagement>
2). 在Antx中,使用项目根中版本仲裁解决:
-
<projects name="thirdpart">
-
<project version="2.0.1"/>
-
<project version="1.3"/>
-
</projects>
9. 出现或者Thread pool exhausted怎么办?
RejectedExecutionException表示线程池已经达到最大值,并且没有空闲连,拒绝执行了一些任务。
Thread pool exhausted通常是min和max不一样大时,表示当前已创建的连接用完,进行了一次扩充,创建了新线程,但不影响运行。
原因可能是连接池不够用,请调整中的:
-
// 设成一样大,减少线程池收缩开销
-
=200
-
=200
配置项说明请参见:配置参考手册
如果线程池已经有200,还不够,通常是业务处理占用线程时间过长,
需优化业务,可通过运行:
jstack 进程号 >
分析当前大多数线程都在干什么,从而分析出哪个地方是瓶颈,
比如,如果大部分线程都在处理SQL,可能是数据库连接不够,或数据源配置错误,或SQL没走索引等。
10. 出现怎么办?
1). 检查注册中心是否开启白名单功能,如果开启,当IP不在白名单列表中,注册中心将拒绝连接。
2). 检查端口是否正确,注册中心有两个端口,一个为控制台HTTP端口,用于管理员查看数据,一个为程序注册服务用的TCP端口。
11. 出现Remote server returns error: [6], Got invocation exception怎么办?
此异常表示Dubbo框架调用服务提供者的实现方法失败,并且不是方法本身的业务异常。
通常是服务消费者和服务提供者的API签名不一致引起,或者提供方比消费方少此函数。
一般是服务增加方法,或修改了方法签名,而双方用的服务API的jar包不一致。
12. 出现Error closing connection/tbr-client 怎么办?
如果服务提供者先关闭,当注册中心通知服务消费者后,服务消费者会再次关闭与服务提供者的连接,
而此时连接早已不存在,TBRemoting没有判断null,直接调用了close方法,所以会抛出空指针异常,
由于TBRemoting源码由taobao管理,暂时未解决此BUG,但不影响使用,可忽略。
Dubbo1.0.11-3以后版本已hack了taobao的代码,不存在此问题。
13. 出现: Error creating bean with name 'xxxService': Initialization of bean failed; nested exception is : Method must not be null怎么办?
通常是classpath下存在spring多个版本的jar包,排除掉不需要的spring包即可。
14. 出现Error setting property values; nested exception is : Invalid property 'applicationName' of bean class []: Bean property 'applicationName' is not writable or has an invalid setter method.怎么办?
出现类似的dubbo某个类的属性没有setter方法的异常,通常是classpath下有多个不同版本的dubbo的jar包,导致配置文件与类不匹配。
可以在程序中运行下面的代码发现重复的类或jar包:(代码中的类名视具体冲突而定)
-
Enumeration<URL> urls = ().getContextClassLoader().getResources("com/alibaba/dubbo/registry/internal/");
-
while (()) {
-
URL url = ();
-
(">>>>>>>>>>>>>>>>>>>>>>" + ());
-
}
15. 服务提供者没挂,但在注册中心里看不到怎么办?
首先,确认服务提供者是否连接了正确的注册中心,不只是检查配置中的注册中心地址,而且要检查实际的网络连接。
其次,看服务提供者是否非常繁忙,比如压力测试,以至于没有CPU片段向注册中心发送心跳,这种情况,减小压力,将自动恢复。
16. 出现ERROR -拒绝连接 :拒绝连接 怎么办?
监控中心不可用,发送统计信息失败,不影响调用,但将丢失统计信息。
17. 服务地址出现127.0.0.1怎么办?
Dubbo1.0.7以后版本不存在此问题,当发现本机IP为127.0.0.1时,将遍历所有网卡查找有效IP。
之前版本处理方式:
正确配置的IP映射,Linux下为/etc/hosts,Windows下为C:/WINDOWS/system32/drivers/etc/hosts
假设:ifconfig命令行结果为10.20.130.230,hostname命令行结果为test2,
则配置为:
-
127.0.0.1 localhost
-
10.20.130.230 test2
18. 通过netstat -anp看到连接的注册中心和配置的不一样怎么办?
检查classpath下是否存在两个文件:
-
Enumeration<URL> urls = ().getContextClassLoader().getResources("");
-
while (()) {
-
URL url = ();
-
(">>>>>>>>>>>>>>>>>>>>>>" + ());
-
}
19. 客户端的异常信息里的errorcode是什么意思?
如Remote server returns error: [6], Got invocation exception
1 — 收到消息的时候线程池拒绝处理
2 — 服务提供者端未能根据服务名找到相应服务
3 — 该服务调用时,服务提供者端不能加载参数类型对应的class
4 — 参数不能被正确的反序列化
5 — 不能正确从Class中create该调用所指示的方法
6 — 不能正确调用该方法
20. 出现expected string at 0×33 怎么办?
这是Hessian3.2.1的一个BUG,Dubbo内部使用Hessian3.2.1做序列化,升级到Dubbo1.0.14以上版本,已解决此问题。
具体原因参见:
/wp/experience_929/
21. 预发布环境,在本地的/etc/hosts文件作了对注册中心的绑定,为什么服务还是注册到生产环境的注册中心?
中配置的 =
而/etc/hosts里的绑定如下:
172.22.14.13
两边的不一致,导致该问题出现。
将绑定修改为:172.22.14.13 即可!
22. 注册中心上服务是存在的,为什么报找不到服务的错误?
报错信息: Caused by: : No invoker available for remote service :1.0.0, servers: []
注册中心上看到的服务提供者提供的服务地址是:dubbo://172.29.61.76:55372?version=1.0.0&group=ibank&dubbo=1.0.0&application=ibank
原因:服务提供者配置了group属性,默认的路由规则是 服务名= group/serviceName。
对这个服务,根据默认的路由规则,消费者消费的服务名应该是 ibank/:1.0.0
23. 获取版本号出现怎么办?
at
这个只有1.0.14和1.0.14-2存在的问题,在获取版本时静态字段初始化顺序不对,不影使用,可忽略,升级为1.0.15以上版本不再会有该问题。
24. 以及配置中如何使用占位符?
注:此为Spring的标准功能,仅在此提示使用方式,不属于Dubbo范畴。
使用Spring自带的PropertyPlaceholderConfigurer实现properties配置:
-
xxx=10.20.130.230:9090
-
yyy=morgan
-
<?xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="/schema/beans"
-
xmlns:xsi="http:///2001/XMLSchema-instance"
-
xmlns:dubbo="/schema/dubbo"
-
xsi:schemaLocation="/schema/beans /schema/beans/ /schema/dubbo /schema/dubbo/">
-
<!-- 使用Spring自带的占位符替换功能 -->
-
<bean class="">
-
<!-- 指定properties配置所在位置 -->
-
<property name="location" value="classpath:" />
-
</bean>
-
<!-- 使用${}引用配置项 -->
-
<dubbo:registry address="${xxx}" application="${yyy}" />
-
</beans>
25. 使用多个进程启动服务,端口冲突怎么办?
注:此为Spring的标准功能,仅在此提示使用方式,不属于Dubbo范畴。
使用Spring自带的PropertyPlaceholderConfigurer的SYSTEM_PROPERTIES_MODE_OVERRIDE实现通过-D参数设置端口:
java -=20881
-
<?xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="/schema/beans"
-
xmlns:xsi="http:///2001/XMLSchema-instance"
-
xmlns:dubbo="/schema/dubbo"
-
xsi:schemaLocation="/schema/beanshttp:///schema/beans/:///schema/dubbohttp:///schema/dubbo/">
-
<!-- 使用Spring自带的占位符替换功能 -->
-
<bean class="">
-
<!-- 系统-D参数覆盖 -->
-
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
-
<!-- 指定properties配置所在位置 -->
-
<property name="location" value="classpath:" />
-
</bean>
-
<!-- 使用${}引用配置项 -->
-
<dubbo:provider port="${}" />
-
</beans>
26. 如何加载Spring?
注:此为Spring的标准功能,仅在此提示使用方式,不属于Dubbo范畴。
1). 基于ClassPath加载:
-
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[}{"http://10.20.160.198/wiki/display/dubbo/"});
-
();
2). 基于文件系统加载:
-
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(new String[}{"http://10.20.160.198/home/xxx/"});
-
();
3). 基于Web容器加载:(WEB-INF/)
-
<?xml version="1.0" encoding="UTF-8"?>
-
<web-app xmlns:xsi="http:///2001/XMLSchema-instance"
-
xmlns="/xml/ns/javaee" xmlns:web="/xml/ns/javaee/web-app_2_4.xsd"
-
xsi:schemaLocation="/xml/ns/javaee /xml/ns/javaee/web-app_2_4.xsd"
-
version="2.4">
-
<context-param>
-
<param-name>contextConfigLocation</param-name>
-
<param-value>classpath:</param-value>
-
</context-param>
-
<listener>
-
<listener-class></listener-class>
-
</listener>
-
</web-app>
27. 出现: cvc-complex-type.2.: The matching wildcard is strict, but no declaration can be found for element怎么办?
通常是在用Dubbo1.0的jar包,却用了Dubbo2.0才支持的<dubbo:registry> <dubbo:application> <dubbo:provider> <dubbo:consumer>或2.0才支持的属性。
28. 出现Could not deserialize parameter instance, error is: readObject: unexpected end of file怎么办?
通常是消费方或提供方的内存不足,导致buffer不能分配,使发送到一半的请求被中断了。
也可能是网络抖动,导致传输流被中断。
29. 出现: Invalid argument: 怎么办?
通常是Windows Vista和Windows7的JDK1.6的部分版本存在BUG:
/jira/browse/DIRMINA-379
可以换换JDK版本试试。