• 生产问题笔记


    1.Thread pool is EXHAUSTED! (原因: 并发状态下,线程池不够用)
    可以查这个网址: https://www.pianshen.com/search
    解决:增加dubbo的线程数
    <dubbo:protocol name="dubbo" port="-1" dispatcher="message" threadpool="cached" threads="${cdc_mbhk_loyalty_member_threads:800}"/>

    2. 分库分表的时候,用mybatis拦截器改写sql问题,insert和update都可以在Interceptor拦截器拦截改写成功,但是select 查询还是会用拦截前的sql执行?
    原因如下:
    mybatis拦截器Interceptor其实是责任链模式,由于项目使用过程中使用了PageHelper,
    导致向SqlSessionFactory中加入拦截器时不生效,解决办法是在springboot的启动类上排除掉PageHelperAutoConfiguration:
    @EnableAutoConfiguration(exclude={PageHelperAutoConfiguration.class})

    3.Thread pool is EXHAUSTED! (由于线上切换菲律宾的数据源,导致线程池一直hold保持连接,引发超过dubbo的最大线程数,导致服务雪崩)

    解决方法:
    第一:预警
    第二:熔断
    第三:分流

    4.线上发现oom:java.lang.OutOfMemoryError
    原因:
    mybatisPlus框架: 有selectOne,getOne方法,但是底层都是会获取list,也就是说 会从mysql查出所有满足条件的数据。
    selectOne方法: 期望查一条,如果超过一条数据就会抛异常。 Expected on but found ???
    getOne方法: 只取第一条数据,如果查出多条,会抛出warn警告,不抛异常。 Warn: exectue method there are %* results
    SqlHelper.getObject(this.baseMapper.selectList(queryWrapper));

    原本以为getOne只查了一条数据,结果发现其实底层是去查了符合条件所有的list,这个list数据量又很大,有30多万条。导致内存不够,gc释放不过来。最终oom。
    过程:
    1.服务挂了之后,通过dump文件发现,内存有很多list,和HashMap占用了很大内存没有释放,并且数据量很大50多万笔。
    2.并且发现了部分Mapper的sql查了大量的数据,但是不能确定是不是所有的sql查了大数据的都打出来了。
    3.在服务加上拦截器,拦截执行的sql,并且打印出查出大量数据的sql,并且打出堆栈信息。
    4.根据堆栈信息,定位到处问题的代码位置,并且根据getOne查看底层mybatis源码,发现以上问题。 修复之后,不再报oom。

    extends BaseMapper<CustomerLoyMember> : 会有selectOne方法。
    extends IService<CustomerLoyMember> : 会有getOne方法。

    事故: 有一条sql通过mybatis来查询,原本需求只查一条符合的数据,但底层实际上通过条件查出了几十万笔数据导致oom:
    //getOne
    QueryWrapper<CustomerLoyCard> customerLoyCardQueryWrapper = new QueryWrapper<>();
    customerLoyCardQueryWrapper.eq("MEMBER_ID", target.getMemberId());
    CustomerLoyCard loyCard = customerLoyCardService.getOne(customerLoyCardQueryWrapper);

    //selectOne
    CustomerLoyContactSplit contactSplit1 = customerLoyContactSplit1Mapper.selectOne(customerLoyMemberQueryWrapper);

     打印堆栈信息:用common-lang3 包中提供了 ExceptionUtils 类来帮助读取堆栈信息。

    String stackTrace = ExceptionUtils.getStackTrace(new Exception("to print stack info."));
    log.info("The stack info {}", stackTrace);

    路在脚下
  • 相关阅读:
    什么是HTTP?
    什么是OSI的第7层
    OSI7层模型
    什么是WAF?
    什么是Mirai僵尸网络
    什么是僵尸网络?
    洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk
    如何给数组的结构体排序 关于sort用法
    洛谷 P1803 凌乱的yyy / 线段覆盖
    洛谷 P1007 独木桥
  • 原文地址:https://www.cnblogs.com/lgg20/p/15477027.html
Copyright © 2020-2023  润新知