case-服务超时排查

一、问题描述

线上的一个服务A连续出现rpc调用服务B超时报错。

仔细看了一下报警发现超时的rpc服务B都是在集中在一台服务器h上,并且都是一个接口访问失败。初步排除网络抖动原因和受诉宿主机影响,因为异常还在出现,根据该接口平常qps情况应该是该接口所有请求都超时了。

二、原因分析

1. 查看系统各项监控指标:

CPU:

最上边的线就是该服务器,可以看出cpu使用率很高远超出其他机器。又看了一下这台机器刚刚发布过新版本代码。我的感觉可能是哪个小伙伴挖的坑。其他指标如网络、gc都正常。那么就顺着这条线查下去。

2. 登上服务器,使用top查看下cpu在忙活什么?

发现一个java线程用了90的cpu。

3. 然后通过jstack看一下这个线程在做什么。

看了一下jdk版本,嗯是1.7 ,应该就是著名的hashMap死循环了。

4. 接下来我们跟一下代码看看到底那里出了问题。

static {
            schemes.put(StandardScheme.class, new ThriftService.getName_result.getName_resultStandardSchemeFactory(null));
            schemes.put(TupleScheme.class, new ThriftService.getAllWmPoiRule_result.getName_result_resultTupleSchemeFactory(null));
            Map<ThriftService.getName_result._Fields, FieldMetaData> tmpMap = new EnumMap(ThriftService.getAllWmPoiRule_result._Fields.class);
            tmpMap.put(ThriftService.getName_result._Fields.SUCCESS, new FieldMetaData("success", (byte)3, new ListMetaData((byte)15, new StructMetaData((byte)12, WmPoiRule.class))));
            metaDataMap = Collections.unmodifiableMap(tmpMap);
            FieldMetaData.addStructMetaDataMap(ThriftService.getName_result.class, metaDataMap);
        }
public class FieldMetaData implements Serializable {
    private static Map<Class<? extends TBase>, Map<? extends TFieldIdEnum, FieldMetaData>> structMap = new HashMap();
    ...
    public FieldMetaData(String name, byte req, FieldValueMetaData vMetaData) {
        this.fieldName = name;
        this.requirementType = req;
        this.valueMetaData = vMetaData;
    }

    public static void addStructMetaDataMap(Class<? extends TBase> sClass, Map<? extends TFieldIdEnum, FieldMetaData> map) {
        structMap.put(sClass, map);
    }
    ...
}

熟悉thrift的同学应该知道以上的代码是thrift自动生成的代码。这段代码里在静态块中使用了HashMap,但是不同类的<clinit>又是多线程并发执行。同一个类的<clinit>又是同步执行的,那么在jdk1.7的情况下并发的put造成了HashMap的死循环的,而<clinit>的同步又block住了访问这一类的所有线程,导致了该接口的所有线程block住不能返回最终导致超时。

既然查到了问题就好解决了!重启万能大法!!!

三、后续TODO

这么明显的bug我想应该早就有人发现了吧,查了一下thrift的issues列表结果真的发现了

https://issues.apache.org/jira/browse/THRIFT-1618

emmmmm事实证明我们该升级了。。。重启服务搞定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值