K
  • 一次redis bigkey导致的超时故障

    2021年遇到的第一个有意思的线上技术故障,是由redis的big key引起的,虽然不是我负责的系统,但是又还是我去排查,花了不少时间和DBA一起刨根究底位到问题根本,记录下这个过程。

    Read More »

  • 一次经典的FGC排查

    背景

    前几天搞一次上线,在负责的核心系统搞出了一次FGC,表现是系统一直在FGC,老年代一直是居高不下,经过一顿猛操作,快速定位到是由死循环引起FGC,虽然排查过程不复杂,但是非常经典,是拿来给组内新人入门的最好案例。

    Read More »

  • 慢SQL优化总结

    背景

    616大促前夕压测检查出有几个供应链的系统有SQL慢查询,于是DBA来了一场大部分系统mysql慢查询全扫描,揪出我们组负责的几个系统用大于有100条慢SQL(查询速度>300ms),下面就是我这次100条慢SQL排查的总结。

    Read More »

  • 老系统full GC排查

    背景

    组内有个文件系统是以前北京的同事离开的时候交接给我们,主要是用于vis内部文件上传,包括图片、pdf等,我们接手过来之后,经常隔一个星期或者几天就出现一次Full GC,每次这个系统的负责的同事操作都是,先涨堆内存,或者直接来一波重启,后面有事,就再重复一次操作。终于有一次,组长在群里发出这个系统告警的时候,我才发现这又是一个很有意思的问题,虽然它跟KPI半毛钱关系都没。

    排查

    准备dump文件

    在收到告警的时候,应用已经触发了Full GC, 但是依旧我还是常规性做了heapdump,拿到了大小为2G 左右的dump文件,我在这里记录为afterGC.dump,用处后面再说。
    然后悄悄观察几天,一直等到old去一直涨到接近75% 阈值时,手动做了heap dump,拿到了一个接近7.2G左右的dump文件,称之为beforeGC.dump,注意不要 dump:live ~~

    分析dump文件

    打开MAT,注意一般dump文件有个 7 8G,用mat打开的时候可能会出现堆内存不足导致失败,所以需要配置下mat的堆内存大小,在mat的安装目录 的 MemoryAnalyzer.ini 文件里面,配置下Xmx,就拿我本次来说,配了2GB就可以了。 打开之后,发现分析的饼图跟7.2GB的dump文件大小完全对不上,一查才发现MAT默认把不可达的对象(unreachable objects)解析,详细见官方文档https://wiki.eclipse.org/MemoryAnalyzer/FAQ#How_to_analyse_unreachable_objects ,需要修改mat的默认配置,

    Read More »

  • 一次Full GC排查

    背景

    我们有个spark应用正常跑了一个星期之后,在4月8号中午突然间spark SQL写hive暂停了,打开log一看,满屏的 Full GC,基本每隔1S左右FUll GC一次,每次费时 3-4S,偶尔有几次出现10几秒,看了log基本是老年代一直不变,每次GC前后的大小几乎没变化,内部运维监控系统查看,CPU一直持续 120%(由于特殊原因,内部spark应用暂时看不到jvm的监控信息)。我们这个时候的堆内存是开了8G,临时加到了16G堆内存,总共有8个节点实例,加了之后启动不到半分钟又触发了一个Full GC, 表象还是老年代一直居高不下。

    排查

    出现Full GC的是在 spark driver,我们核心的业务逻辑(MQ消费,再对MQ做一系列的处理,最后才落地hive)都是在driver进行,由于heapdump下载的文件太慢,一开始我们没有执行heapdump,只是临时跑下 jhisto 查看哪些对象占用最多内存

    jmap -histo pid | sort -n -r -k 3 | head 10
    

    Read More »

  • 一次慢SQL调优

    上周日常系统维护的时候,遇到之前同事做的一个报表,关联的数据不大(SQL用到的主表数据量才5W+,其余的表2W封顶),查询速度出奇的慢 ,第一次打开的时候直接超时,超过了服务器配置的30S超时时间,折腾一番后,将SQL速度提升到8S,再折腾一番后达到37ms,简单记录下过程。

    Read More »

  • 利用openresty写的小工具

    背景

    公司内部有一个api网关服务janus,用于拦截所有的流量,并进行鉴权、防刷以及协议转换等,这里的协议转换比如http转RPC,通过网关解析http请求并且通过网关服务后台的配置找到对应的RPC服务进行调用,从而实现前端接口直接调用RPC服务。在供应链很多系统都是通过这种方式实现前端代码来实现RPC服务的调用。

    Read More »

  • ThreadDumper协助定位线程阻塞问题

    背景

    419大促值班的时候,遇到一个生产的OSP(VIP的RPC框架)的框架异常,意思大致是某个RPC服务接口出现方法级线程池爆满,而通过定位,发现该接口是定时任务每隔半个小时触发一次。初步判断是这个方法可能是某个地方组塞住了,然后每隔半个小时创建新线程执行该方法的时候,由于之前的线程都没有运行完,所以线程一直在阻塞着,导致该方法的线程池爆满。

    定位

    log

    出问题之后,第一时间就是看log,从异常栈看到是RPC的某个方法,出现这个方法级线程池爆满。而日志里面让我耳目一新的是 **Thread dump by ThreadDumpper for rejected by method level business ** ,然后接下来的是一些异常栈信息,就是把当前存活的线程的线程栈打出来,把每个存活的线程都状态,线程栈信息全打出来,类似

    "thread-dump-0" Id=13 WAITING
    	at java.lang.Object.wait(Native Method)
    	at java.util.concurrent.ForkJoinTask.externalAwaitDone(ForkJoinTask.java:334)
    	at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:405)
    	at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
    	at java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:714)
    	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
    	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    	at com.kevin.vjtool.StaticWithLmdUtils.<clinit>(StaticWithLmdUtils.java:20)
    	...
    

    Read More »

  • 从VIP-sonar检测结果看常见代码问题--持续更新

    前言

    项目稳定之后,开始逐步关注过去赶进度写的“坏”代码问题,唯品会内部订制的sonar检测规则,在每次上线的时候都会进行静态代码检查,这阵子抽空看了自己项目的代码问题,同时也看了很多别的项目的检测结果,还是挺有收获,记录下。

    Read More »

  • 解决presto long prepareStatement-一次开源项目的填坑之旅

    前言

    项目中用到presto,一个facebook开源的分布式查询引擎,号称查询速度是hive的10倍以上,是spark的3倍以上,因此在唯品会内部做实时统计的很多计算任务都是交给presto去做。但是presto有一个非常不好的地方,就是它的用户文档几乎是空的,除了基本的部署文档、基本使用文档,内部的实现细节几乎一点都没,出了问题完全只能自己debug代码去看。于是就有了这次填坑的旅程。

    Read More »

  • 一道带有遗憾的算法题

    前言

    最近面试一个非常心仪的职位,结果跪在一道算法题目上,让我几晚都睡不着,翻来覆去。面试失败后回去,结果当晚花了不到十分钟就解决了这个看似很难,实际上非常简单的题目。现在已经过去了,总结下这个问题,顺便给博客开了算法模块。

    Read More »

  • mysql死锁还原和分析

    前言

    mysql的死锁是生产环境相对常遇到,在开发、测试环境却很难重现的一个问题,以前线上出现死锁的时候,运维都是直接暴力重启mysql来解决。所以很多时候开发很难找到到底这个死锁是怎么发生的,是哪些SQL语句导致死锁的,今天花了点时间测试下,大致给一个思路来还原业务代码如何导致死锁的发生以及发生死锁后,怎么去定位是哪几条SQL导致的。

    Read More »