首页 国际新闻 正文

Dubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆

Dubbo[ |db| ,发音为打波] 稳如狗,哪有坑?


假如你用过Dubbo,可是没碰到过什么坑,那只能阐明你还没有深交Dubbo,看看笔者那些年运用Dubbo踩过的坑!

父子类有相同特点时值丢掉

假定Provider供给的服务中某个服务的参数是WordDTO,而且WordDTO承继自BaseDTO,两个类的界说如下:

@Datapublic class BaseDTO implements Serializable { private Long id;}@Datapublic class WordDTO extends BaseDTO { private Long id; private String uuid; private Long timestamp; private String word;}

问题描绘:在Consumer侧给WordDTO赋的值,其id特点的值无法在Pr爱拍才哥ovider侧获取到。假定Consumer传的值是:{"id":68,"timestamp":1570928394380,"uuid":"f774f99f-987c-4506-8ab8-366cd619bb15","word":"hello world"},在Provider拿到的却是:{"timestamp":1570928394380,"uuid":"f774f99f-987c-4506-8ab8-366cd619bb15","word":"hello world"}。

原因剖析:dubbo默许选用的是hessian序列化&反序列化办法,JavaDeserializer在获取fileds时,选用了Map去重。可是在读取值时,依据serializer的次序,关于同名字段,子类的该字段值会被赋值两次,总是被父类的值掩盖,导致子类的字段值丢掉。

处理方案

  1. 更改序列化办法(不主张);
  2. 删掉子类中与父类同名特点(主张);

自界说反常被包装成RuntimeExcep九阳剑圣tion

首要需求阐明的是,呈现这个问题有必定的条件。假如Provider中的api和自界说Exception界说都是普吉岛气候在一个api.jar中,那么是不会有任何集问题的。可是假如自界说Exception是在一个独自的比方common.jar包中就会呈现这个问题(此刻api和model在另一个api.jar中)。

下面是一段调用一个会抛出自界说反常的服务的代码:

try { String hello = demoService.saySomething(wordDTO); System.out.println(hello);}catch (WrongArgumentException e){ System.err.println("wrong argument 1: " + e.getMessage());}catch (RuntimeException e){ System.err.println("wrong argument 2: 付出" + e.getMessage());}

可是,调用的日志却是如下所示,经过日志咱们能够发现,在Consumer中并没有捕获到自界说的WrongArgumentException反常,只能捕获到RuntimeException中的反常,且这个反常信息是封装自界说的WrongArgumentException反常:

wrong argument 2: com.afei.dev.maven.exception.WrongArgumentException: word不允许为空com.afei.dev.maven.exception.WrongArgumentException: word不允许为空 at com.afei.test.dubbo.provider.facade.impl.DemoServiceImpl.saySomething三七粉的正确吃法(DemoServiceImpl.java:11) at com.alibaba.dubbo.common.bytecode.Wrapper1.invokeMethod(Wrapper1.java)

这是什么原因呢?这是因为dubbo Provider的ExceptionFilter.java对反常一致封装导致的,其封装的中心源码我就不贴出来了,你假如有爱好能够自己下载查看。我这儿只贴出它的处理逻辑,当碰到如下这些状况时,dubbo会直接抛出反常:

  1. 假如是checked反常(不是RuntimeException可是是Exception.java类型的反常),直接抛出;
  2. 在办法签名上有声明(例如String saySomething()throws MyException ),直接抛出;
  3. 反常类和接口类在同一jar包里,直接抛出我的绝色御姐老婆;
  4. 是JDK自带的反常(全类名以java或许javax最初,例如java.lang.IllegalStateException),直接抛出;
  5. 是Dubbo自身的反常RpcException,直接抛出;

不然,Dubbo经过如下代码将反常包装成Runt浦江气候imeException抛给客户端:

return new RpcResult(new RuntimeException(StringUtils.toString(exception)));

经过上面临ExceptionFilter的源码剖析可知,假如要让Provider抛出自界说反常,有如下几个处理办法:

  1. 将自界说反常和接口类放到一个包中即可(引荐);
  2. 办法签名上声明自界说反常;

那么Dubbo为什么这样规划?我信任没有谁比Dubbo的作者梁飞更有发言权了!这儿就引证Dubbo作者梁飞在Github上的原话(原话出处:https://github.com/apache/dubbo/issues/111):

这个是为了避免服务供给方抛出了消费方没有的反常,比方数据库反常类,导致消费方反序列化失利,使反常信息更古怪,主张在事务接口上RuntimeException也声明在throws中。


IP露出问题

在某些杂乱环境下,例如Docker、双网卡、虚拟机等环境下,Dubbo默许绑定的IP或许并不是咱们期望的正确IP,Dubbo绑定IP默许行为如下(中心源码在NetUtils.java中):

  1. 经过InetAddress.getLocalHost()获取本机地址,假如本机地址有用则回来(有用地址需求满意这几点:1. 不能为空,2. 不是loopback地址(相似127.x.x.x),3. 不能是0.0.0.0,也不能是127.0.0.1);
  2. 假如本机地址无效,那么再遍历网卡地址,然后经过isValidAddress校验ip是否正常并回来第一个有用的IP地址。这样的话,Dubbo就不能确保回来的是内网IP仍是外网IP。

事实上,杂乱环境下这个IP绑定问题不太好自动化处理,不过咱们能够运用dubbo的扩展才能处理这些问题。

  • Docker环境

假如你的dubbo布置在Docker上,那么需求留意了。咱们需求处理Dubbo几个特定参数来处理这个问题:

  1. DUBBO_IP_TO_REGISTRY --- Registering to the IP address of the registration center
  2. DUBBO_PORT_TO_REGISTRY --- Registering to the port of the registration center
  3. DUBBO_IP_TO_BIND --- Listening IP addresses
  4. DUBBO_PORT_TO_BIND --- Listening ports

假定主机IP地址为30.5.97.6,docker发动dubbo服务参阅指令,发动后,这个Provider服务注册的地址便是30.5.97.6:20881,咱们能够经过指令(telnet 30.5.97.6 20881,invoke org.apache.dubbo.test.docker.DemoService.hello("world"))查看并调用Provider供给的服务:

docker run -e DUBBO_IP_TO_REGISTRY=30.5.97.6 -e DUBBO_PORT_TO_REGISTRY=20881 -p 30.5.97.6:20881:20880 --link zkserver:zkserver -it --rm dubbo-docker-sample

参阅地址:https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-docker。

  • 露出外网IP

假如你服务的调用方和消费方不在同一个内网中,那么就奥特曼搏斗进化会期望Dubbo张希先服务经过外网IP露出。不过不好意思,dubbo默许的服务露出行为搞不定,因为dubbo默许露出的是内网IP地址。

这个时分,咱们就需求凭借两个参数:dubbo.protocol.host和du流氓大亨养精英bbo.protocol.port,经过这两个参数显现声明咱们露出服务的IP和Port,这两个参数即能够经过装备文件办法指Dubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆定,也能够经过JVM参数办法指定,具体怎样运用,UP TO YOU!!!

  • 双网卡问题

当服务器上有多个网卡时,Dubbo服务供给者发动时,会将过错的IP注册到注册中心,然后导致消费端衔接不上。这种状况的笔者供给两种处理办法:

  1. 装备dubbo.protocol.host=192.168.0.1
  2. 装备/etc/hosts,例如afeiserver01 = 192.168.0.1,其间afeiserver01是机器名;

Data length t眼线怎样画oo large

这个反常的具体仓库信息如下所示:

org.apache.dubbo.remoting.transport.ExceedPayloadLimitException:Data length too large: 10356612, max payload: 8388608,channel: NettyChannel [chann甜甜圈el=[id: 0xd36132c0, L:/192.168.1.6:55078 - R:/192.168.1.6:20880]]

日志中说到max payload为8388608,等价于8 * 1024 * 1024,即8k。所以这个问题的原因十分明晰了,便是恳求或许呼应的报文体长度超越了8k。

这个问题比较简单,笔者在这儿供给两个处理方案:

  1. 修正payload的值,将其调大,例如16777216,即16k,不引荐
  2. 削减恳求/呼应报文长度。例如Provider供给的服务,最大批量限制为1000,比方最多只能批量查询1000个用户ID的用户信息,引荐

阐明:

dubbo在小报文的场景下体现最佳,所以,除非的确无法饶过。不然激烈不主张调大payload的值;


线程耗尽

dubbo服务Provider侧假如线程耗尽,会跑出相似如下的反常信息:

19-10-17 00:00:00.033 [New I/O server worker #1-6] WARN com.alibaba.dubbo.common.threadpool.support.AbortPolicyWithReport - [DUBBO] Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-10.0.0.77:20703, Pool Size: 200 (active: 200, core: 200, max: 200, largest: 200), Task: 5897697 (completed: 5897197), Executor status:(isShutdown:false, isTerminated:false, isTDubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆erminating:false), in dubbo://10.0.0.77:20703!, dubbo version: 2.5.3, current host: 127.0.0.1

对dubbo有根本了解的都知道,Provider默许是fixed线程池,且线程数为200。那么什么时分会呈现这种反常呢:

  1. Provider侧接口处理太慢。假如是这种原因的话,咱们能够经过jstack指令,在线程栈中看到超越200个状况为RUNNING、且命名为"DubboServerHandler-"的线程,经过线程栈咱们大约知道是哪部分代码引起的,然后优化问题代码,提高处理才能然后处理这个问题;
  2. Provider处理才能的确不可。这个原因是指,Consumer或许会到达10000TPS,可是Provider单机处理才能或许只要1000TPS,假如没有10台以上的Provider服务实例,那么就的确需求扩容了。
  3. Provier因为某些原因堵塞。这个原因一般是Provider侧依靠的某些服务或许中间件出问题导致的;

依据下面这段日志可知,Dubbo线程都堵塞在发送ActiveMQ音讯的当地,咱们能够经过异步发送MQ音讯,或许查看是不是ActiveMQ服务吞吐量不可并萧靖彤优化它的吞吐量等手法来处理:

"DubboServerHandler-127.0.0.1:20880-threDubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆ad-128" daemon prio=10 tid=0x00007fd574193811 nid=0x16cf1 waiting for monitor entry [0x00007fd691887000..0x00007fd691888810] java.lang.Thread.State: BLOCKED (on object monitor) at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40) - waiting to lock <0x00007fd6c9fa4ba8> (a jDubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆ava.lang.Object) at org.apache.activemq.transport.ResponseCor甜心格格relator.oneway(ResponseCorrelator.java:60) at org.apache.activemq.ActiveMQConnection.doAsyncSendPacket(ActiveMQConnection.java:1265) at org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1259)

服务调用失利

反常仓库信息如下所示:

Forbid 姐consumer 0 access service com.afei.dubbo.demo.api.QueryService from registry 127.0.0.1:2181 use dubbo version 2.5.3,Please check registry access list (whitelist/blacklist)

或许反常仓库信息如下所示:

org.apache.dubbo.rpc.RpcException:Failed to invoke the method saySomething in the service com.afei.test.dubbo.provider.facade.DemoService.No provider available for the service com.afei.Dubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆test.dubbo.prov灰洞ider.facade.DemoService:2.0.0from registry 224.5.6.7:1234

我信任,每一个运用过dubbo服务的同学,肯定会碰到上面这两个ERROR日志。这两个问题一般有如下几种原因:

  1. Provider服务悉数下线,即没有一个存活的ProvideDubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆r服务进程。
  2. 存在一个或多个Provider服务,可是version或许group不匹配。例如ConsumeDubbo用了这么久,居然有这么多洞?-万博亚洲_manbetx 2.0下载_万博体育manbetx登陆r侧声明version=1.0.0,而Provider侧声明version=2.0.0,或许group不匹配,都会呈现这个ERR山村小医生OR。
  3. 露出的IP有问题。例如露出的是内网IP,可是调用却是经过外网IP;

dubbo spring schema

在dubbo进入apache之前,dubbo的spring s艾唯莎chema声明如下:

http://code.alibabatech.com/schema/dubbo

当dubbo进入apache后,dubbo的spring schema能兼容两种办法:

http://dubbo.apache.org/schema/dubbohttp://code.alibabatech.com/schema/dubbo

这是由dubbo.jar中META-INF/spring.schemas文件决议的:

http\://dubbo.apache.org/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsdhttp\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/compat/dubbo.xsd

dubbo新版别是即能兼容http://dubbo.apache.org/schema/dubbo,也能兼容http://code.alibabatech.com/schema/dubbo。可是dubbo老版别只能兼容http://code.alibabatech.com/schema/dubbo。假如老版别也装备http://dubbo.apache.org/schema/dubbo,就会抛出如下日常:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException:Configuration problem: Unable to locate Spring NamespaceHandle

相关推荐

  • 暂无相关文章