抢购性能问题排查之二——日志打印的锁竞争

1 问题的现象

经过第一轮数据库的优化,微服务的请求响应耗时都比较能接受了。然而网络请求的总耗时还是很慢。
这个问题的关键就在网关层了。

2 问题的分析

至于机器为啥会慢,分析完机器的运行状态数据感觉,除了CPU高点以外,其他指标都还比较正常。

第一时间怀疑到的自然是GC问题,结果打印了GC日志发现极其正常。

第二步就考虑还是打印一下jstack(中间有个乌龙事件,jstack只能使用当前用户执行,root权限并不能打印其他用户的栈)
结果打印结果来看全部卡在了logback输出日志。


"http-nio-20070-exec-1480" #33017 daemon prio=5 os_prio=0 tid=0x00007f38a8268800 nid=0x5c57 waiting on condition [0x00007f388330d000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000c0129698> (a java.util.concurrent.locks.ReentrantLock$FairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
    at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:224)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
    at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:210)
    at ch.qos.logback.core.rolling.RollingFileAppender.subAppend(RollingFileAppender.java:228)
    at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:100)
    at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
    at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48)
    at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
    at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
    at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
    at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
    at ch.qos.logback.classic.Logger.info(Logger.java:579)

然而用iostat来看确实磁盘的性能还有很足的空余,难道是程序慢?

3 问题的解决

找到一个栈信息分析的网站https://fastthread.io/

分析完之后发现,很多都有锁在同一个对象上。刚好有一个栈文件能看到这个锁是logback程序持有的。
然后去查源码,看了一下发现,日志输出肯定要有一个锁来实现打印内容的同步。

仔细看完代码,发现logback 1.1.7的版本,采用的是一个公平锁。极端并发场景会导致严重的性能问题。
然后,我们又发现在logback最新的1.2.3版本把这个改成了非公平锁。

把logback版本升级后发现,性能问题解决。

你可能感兴趣的:(抢购性能问题排查之二——日志打印的锁竞争)