介绍:为什么SOFARPC调用30s还不超时?一、背景最近帮一个客户处理了一个奇怪的RPC调用问题,分享给大家。SOFARPC请参考官网[1]。2.问题现象客户使用REST接口触发RPC调用,发现每次RPC调用需要30秒,最终RPC调用结果是成功的。从业务日志来看,从业务开始到业务结束,确实需要30秒。3、问题分析RPC调用用了30秒才成功,这本身就是一件奇怪的事情。因为默认的SOFARPC的frameRPCtimeout是3秒。以下代码显式设置超时,该超时设置为默认值。我们首先确定SOFARPC框架的默认超时时间在代码中没有改变。因此,理论上,如果RPC调用超过3秒,RPC客户端应该会报错。那么,让我们看看这30秒内发生了什么!3.1直入框架核心我们知道SOFARPC调用的超时时间是3秒。我们首先需要确认SOFARPC框架需要多少时间。根据业务日志的时间点(2020-01-2110:41:34),查看RPC摘要日志:/home/admin/logs/tracelog/rpc-client-digest.log。我们发现RPC执行时间仅为54ms。这证明RPC调用其实是很快的!那么时间都去哪儿了?2020-01-2110:42:04.186,xxx_app,0a014046157957449410610155674,0,com.xxx.xxx.service.xxxService:1.0,$genericInvoke,bolt,sync,xxx.xxx.xxx.72:12222,xxx,,,,,00,2296B,889B,54ms,0ms,0ms,54ms,http-nio-8080-exec-10,REGISTRY,,,,xxx.xxx.xxx.72,12222,,,是否花时间获取RPC提供者地址?因此,我们检查RPC客户端的注册表寻址日志/home/admin/logs/rpc/rpc-registry.log。我们发现接口的地址是三秒前返回的。所以这也不是解决问题的问题。2020-01-2110:41:31,330INFOObserverNotifyThread-2-thread-5com.alipay.sofa.rpc.registry.dsr.DsrSubscribeCallback-RPC-00204:接收RPC服务地址:service[com.xxx.xxx.service.xxxService:1.0@DEFAULT]可用目标地址[3]3.2业务代码疑点根据以上证据,我们有理由怀疑问题出在业务代码本身。我们要求客户检查业务代码。客户在业务代码中加入了很多日志,明确打印了业务处理和RPC调用时间,结果发现RPC调用时时间还是消失了。下面是客户端SOFARPC调用的具体代码。GenericObject结果=(GenericObject)serviceName.$genericInvoke(methodName,argTypes,args);看到这个结果,我们很疑惑:RPC超时是3s,但实际上这个调用花了30s没有超时(因为RPC的实际执行时间只有54ms)。那么,时间都去哪儿了?3.3反向推导从结果到反向推导,genericInvoke应该包含很多处理方法,但是在调用真正的RPC方法之前,它必须调用其他处理方法来做其他事情,那么它到底做了什么?如果你阅读代码,你会发现你将淹没在代码的海洋中。我们需要其他更有效的方法来解决此类问题。这30秒给人一种被“卡”在某处的感觉。这时候我们就需要思考,在这种情况下,有什么日志或者工具可以帮助我们更接近真相呢?这时候jstack登场了。jstack可以帮助我们获取某个时刻某个进程中所有线程的调用栈。如果一个线程卡在了某个方法中,我们多抓几次jstack就可以清楚的看到卡住的方法。所以我们要求客户在复现问题时每5s收集一次jstack$PID>stack.log,至少收集4条日志。$PID需要替换成业务应用的java进程ID。天道酬勤。从这些jstack日志中,我们通过genericInvoke快速定位到对应线程,发现卡在了OS的方法getLocalHostName上(有几个jstack日志卡在了getLocalHostName上)。同时从调用栈来看,此时线程正在初始化RPCtracer,也就是RPC调用还没有开始,所以不会出现RPC调用超时。“http-nio-8080-exec-10”#28守护进程prio=5os_prio=0tid=0x00007f54604e5000nid=0x175c可运行[0x00007f53ef1f6000]java.lang.Thread.State:在java.net.Inet4AddressImpl.getLocalHostName(本机方法)在java.net.InetAddress.getLocalHost(InetAddress.java:1475)在sun.management.VMManagementImpl.getVmId(VMManagementImpl.java:140)在sun.management.RuntimeImpl.getName(RuntimeImpl.java:59)在com.alipay.common.tracer.core.utils.TracerUtils.getPID(TracerUtils.java:139)在com.alipay.common.tracer.core.generator.TraceIdGenerator.getTraceId(TraceIdGenerator.java:49)在com.alipay.common.tracer.core.generator.TraceIdGenerator.generate(TraceIdGenerator.java:54)在com.alipay.common.tracer.core.SofaTracer$SofaTracerSpanBuilder.createRootSpanContext(SofaTracer.java:296)在com.alipay.common.tracer.core.SofaTracer$SofaTracerSpanBuilder.start(SofaTracer.java:285)在com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer。com.alipay.sofa.rpc.tracer.Tracers.startRpc(RpcSofaTracer.java:143)在com.alipay.sofa.rpc.event.SofaTracerSubscriber.onEvent(SofaTracerSubscriber.java:35)处的startRpc(RpcSofaTracer.java:143)在com.alipay.sofa.rpc.event.EventBus.handleEvent(EventBus.java:153)在com.alipay.sofa.rpc.event.EventBus.post(EventBus.java:123)在com.alipay.sofa.rpc.client.ClientProxyInvoker.invoke(ClientProxyInvoker.java:80)在com.alipay.sofa.rpc.api.GenericService_proxy_0.$genericInvoke(GenericService_proxy_0.java)在com.xxx.xxx.xxx.util.SofaUtil.invokeService(SofaUtil.java:32)在com.xxx.xxx.xxx.controller.xxxxxxxxController.xxxxxxxxController002(xxxxxxxxController.java:425)在sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)在java.lang.reflect.Method.invoke(Method.java:498)那么这个getLocalHostName方法到底在做什么呢?通过网络搜索,发现这个函数其实就是找本机的HostName。IPCentOS搜索顺序如下:/etc/hosts文件、DNS、myhostname(只返回本机配置的公网IP地址)。由于client端的DNS配置错误,导致DNS超时一直卡在这个方法中,导致出现这个问题。同时经客户确认,这些机器不依赖DNS寻址。所以我们的解决方案很简单:将IP添加到/etc/hosts中的主机名映射。参考文档[1]SOFARPC:https://help.aliyun.com/document\_detail/149865.html?spm=a2c4g.11186623.6.560.178c5fb01GxG9Z我们是阿里云智能全球技术服务-SRE团队,我们是致力于成为一支以技术为基础、以服务为导向、为业务系统提供保障的高可用工程师团队;提供专业、系统的SRE服务,帮助客户更好地使用云,基于云构建更稳定可靠的业务系统,提高业务稳定性。我们期待分享更多的技术,帮助企业客户更好地接入和使用云,让企业在云上的业务运营更加稳定可靠。可以用钉钉扫描下方二维码加入阿里云SRE技术学院的钉钉圈,还有很多云高手交流云平台那些事。版权声明:本文内容由阿里云实名注册用户投稿,版权归原作者所有。阿里云开发者社区不拥有自己的版权,也不承担相应的法律责任。具体规则请参考《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如发现本社区涉嫌抄袭内容,请填写侵权投诉表进行举报,一经查实,本社区将立即删除涉嫌侵权内容。