精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

教你如何成為Java的OOM Killer

開(kāi)發(fā) 開(kāi)發(fā)工具
雖然事隔半年,當(dāng)時(shí)排查線(xiàn)上OOM事故的過(guò)程記憶猶新,每一個(gè)步驟都?xì)v歷在目,感謝業(yè)務(wù)組、系統(tǒng)部、壓測(cè)組、監(jiān)控與應(yīng)急部對(duì)架構(gòu)組的強(qiáng)力支持,得以讓這個(gè)Java內(nèi)存問(wèn)題水落石出,經(jīng)過(guò)半年多的全面的應(yīng)用日志切割方式的改造,現(xiàn)在基本沒(méi)有OOM的問(wèn)題了,線(xiàn)上服務(wù)運(yùn)行非常健康,對(duì)可用性的保障起到了很大的作用,如果你在經(jīng)歷OOM,讀了這個(gè)文章會(huì)有很大的啟發(fā)。

[[196172]]

前言

雖然事隔半年,當(dāng)時(shí)排查線(xiàn)上OOM事故的過(guò)程記憶猶新,每一個(gè)步驟都?xì)v歷在目,感謝業(yè)務(wù)組、系統(tǒng)部、壓測(cè)組、監(jiān)控與應(yīng)急部對(duì)架構(gòu)組的強(qiáng)力支持,得以讓這個(gè)Java內(nèi)存問(wèn)題水落石出,經(jīng)過(guò)半年多的全面的應(yīng)用日志切割方式的改造,現(xiàn)在基本沒(méi)有OOM的問(wèn)題了,線(xiàn)上服務(wù)運(yùn)行非常健康,對(duì)可用性的保障起到了很大的作用,如果你在經(jīng)歷OOM,讀了這個(gè)文章會(huì)有很大的啟發(fā)。

Become OOM Killer

我們都知道JVM的內(nèi)存管理是自動(dòng)化的,Java語(yǔ)言的程序指針也不需要開(kāi)發(fā)人員手工釋放,JVM的GC會(huì)自動(dòng)的進(jìn)行回收,但是,如果編程不當(dāng),JVM仍然會(huì)發(fā)生內(nèi)存泄露,導(dǎo)致Java程序產(chǎn)生了OutOfMemoryError(OOM)錯(cuò)誤。

產(chǎn)生OutOfMemoryError錯(cuò)誤的原因包括:

  1. java.lang.OutOfMemoryError: Java heap space
  2. java.lang.OutOfMemoryError: PermGen space及其解決方法
  3. java.lang.OutOfMemoryError: unable to create new native thread
  4. java.lang.OutOfMemoryError:GC overhead limit exceeded

對(duì)于第1種異常,表示Java堆空間不夠,當(dāng)應(yīng)用程序申請(qǐng)更多的內(nèi)存,而Java堆內(nèi)存已經(jīng)無(wú)法滿(mǎn)足應(yīng)用程序?qū)?nèi)存的需要,將拋出這種異常。

對(duì)于第2種異常,表示Java永久帶(方法區(qū))空間不夠,永久帶用于存放類(lèi)的字節(jié)碼和長(zhǎng)常量池,類(lèi)的字節(jié)碼加載后存放在這個(gè)區(qū)域,這和存放對(duì)象實(shí)例的堆區(qū)是不同的,大多數(shù)JVM的實(shí)現(xiàn)都不會(huì)對(duì)永久帶進(jìn)行垃圾回收,因此,只要類(lèi)加載的過(guò)多就會(huì)出現(xiàn)這個(gè)問(wèn)題。一般的應(yīng)用程序都不會(huì)產(chǎn)生這個(gè)錯(cuò)誤,然而,對(duì)于Web服務(wù)器來(lái)講,會(huì)產(chǎn)生有大量的JSP,JSP在運(yùn)行時(shí)被動(dòng)態(tài)的編譯成Java Servlet類(lèi),然后加載到方法區(qū),因此,太多的JSP的Web工程可能產(chǎn)生這個(gè)異常。

對(duì)于第3種異常,本質(zhì)原因是創(chuàng)建了太多的線(xiàn)程,而能創(chuàng)建的線(xiàn)程數(shù)是有限制的,導(dǎo)致了這種異常的發(fā)生。

對(duì)于第4種異常,是在并行或者并發(fā)回收器在GC回收時(shí)間過(guò)長(zhǎng)、超過(guò)98%的時(shí)間用來(lái)做GC并且回收了不到2%的堆內(nèi)存,然后拋出這種異常進(jìn)行提前預(yù)警,用來(lái)避免內(nèi)存過(guò)小造成應(yīng)用不能正常工作。

下面兩個(gè)異常與OOM有關(guān)系,但是,又沒(méi)有絕對(duì)關(guān)系。

  1. java.lang.StackOverflowError ...
  2. java.net.SocketException: Too many open files

對(duì)于第1種異常,是JVM的線(xiàn)程由于遞歸或者方法調(diào)用層次太多,占滿(mǎn)了線(xiàn)程堆棧而導(dǎo)致的,線(xiàn)程堆棧默認(rèn)大小為1M。

對(duì)于第2種異常,是由于系統(tǒng)對(duì)文件句柄的使用是有限制的,而某個(gè)應(yīng)用程序使用的文件句柄超過(guò)了這個(gè)限制,就會(huì)導(dǎo)致這個(gè)問(wèn)題。

上面介紹了OOM相關(guān)的基礎(chǔ)知識(shí),接下來(lái)我們開(kāi)始講述筆者經(jīng)歷的一次OOM問(wèn)題的定位和解決的過(guò)程。

1. 產(chǎn)生問(wèn)題的現(xiàn)象

在某一段時(shí)間內(nèi),我們發(fā)現(xiàn)不同的業(yè)務(wù)服務(wù)開(kāi)始偶發(fā)的報(bào)OOM的異常,有的時(shí)候是白天發(fā)生,有的時(shí)候是晚上發(fā)生,有的時(shí)候是基礎(chǔ)服務(wù)A發(fā)生,有的時(shí)候是上層服務(wù)B發(fā)生,有的時(shí)候是上層服務(wù)C發(fā)生,有的時(shí)候是下層服務(wù)D發(fā)生,絲毫看不到一點(diǎn)規(guī)律。

產(chǎn)生問(wèn)題的異常如下:

  1. Caused by: java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) 
  2. at java.lang.Thread.start(Thread.java:597) 
  3. at java.util.Timer.<init>(Timer.java:154) 

2. 解決問(wèn)題的思路和過(guò)程

經(jīng)過(guò)細(xì)心觀察發(fā)現(xiàn),產(chǎn)生問(wèn)題雖然在不同的時(shí)間發(fā)生在不同的服務(wù)池,但是,晚上0點(diǎn)發(fā)生的時(shí)候概率較大,也有其他時(shí)間偶發(fā),但是都在整點(diǎn)。

這個(gè)規(guī)律很重要,雖然不是一個(gè)時(shí)間,但是基本都在整點(diǎn)左右發(fā)生,并且晚上0點(diǎn)居多。從這個(gè)角度思考,整點(diǎn)或者0點(diǎn)系統(tǒng)是否有定時(shí),與出問(wèn)題的每個(gè)業(yè)務(wù)系統(tǒng)技術(shù)負(fù)責(zé)人核實(shí),0點(diǎn)沒(méi)有定時(shí)任務(wù),其他時(shí)間的整點(diǎn)有定時(shí)任務(wù),但是與發(fā)生問(wèn)題的時(shí)間不吻合,這個(gè)思路行不通。

到現(xiàn)在為止,從現(xiàn)象的規(guī)律上我們已經(jīng)沒(méi)法繼續(xù)分析下去了,那我們回顧一下錯(cuò)誤本身:

  1. java.lang.OutOfMemoryError: unable to create new native thread

顧名思義,錯(cuò)誤產(chǎn)生的原因就是應(yīng)用不能創(chuàng)建線(xiàn)程了,但是,應(yīng)用還需要?jiǎng)?chuàng)建線(xiàn)程。為什么程序不能創(chuàng)建線(xiàn)程呢?

有兩個(gè)具體原因造成這個(gè)異常:

  1. 由于線(xiàn)程使用的資源過(guò)多,操作系統(tǒng)已經(jīng)不能再提供給應(yīng)用資源了。
  2. 操作系統(tǒng)設(shè)置了應(yīng)用創(chuàng)建線(xiàn)程的最大數(shù)量,并且已經(jīng)達(dá)到了最大允許數(shù)量。

上面第1條資源指的是內(nèi)存,而第2條中,在Linux下線(xiàn)程使用輕量級(jí)進(jìn)程實(shí)現(xiàn)的,因此線(xiàn)程的最大數(shù)量也是操作系統(tǒng)允許的進(jìn)程的最大數(shù)量。

內(nèi)存計(jì)算

操作系統(tǒng)中的最大可用內(nèi)存除去操作系統(tǒng)本身使用的部分,剩下的都可以為某一個(gè)進(jìn)程服務(wù),在JVM進(jìn)程中,內(nèi)存又被分為堆、本地內(nèi)存和棧等三大塊,Java堆是JVM自動(dòng)管理的內(nèi)存,應(yīng)用的對(duì)象的創(chuàng)建和銷(xiāo)毀、類(lèi)的裝載等都發(fā)生在這里,本地內(nèi)存是Java應(yīng)用使用的一種特殊內(nèi)存,JVM并不直接管理其生命周期,每個(gè)線(xiàn)程也會(huì)有一個(gè)棧,是用來(lái)存儲(chǔ)線(xiàn)程工作過(guò)程中產(chǎn)生的方法局部變量、方法參數(shù)和返回值的,每個(gè)線(xiàn)程對(duì)應(yīng)的棧的默認(rèn)大小為1M。

Linux和JVM的內(nèi)存管理示意圖如下:

內(nèi)存結(jié)構(gòu)模型

因此,從內(nèi)存角度來(lái)看創(chuàng)建線(xiàn)程需要內(nèi)存空間,如果JVM進(jìn)程正當(dāng)一個(gè)應(yīng)用創(chuàng)建線(xiàn)程,而操作系統(tǒng)沒(méi)有剩余的內(nèi)存分配給此JVM進(jìn)程,則會(huì)拋出問(wèn)題中的OOM異常:unable to create new native thread。

如下公式可以用來(lái)從內(nèi)存角度計(jì)算允許創(chuàng)建的最大線(xiàn)程數(shù):

  • 最大線(xiàn)程數(shù) = (操作系統(tǒng)最大可用內(nèi)存 - JVM內(nèi)存 - 操作系統(tǒng)預(yù)留內(nèi)存)/ 線(xiàn)程棧大小

根據(jù)這個(gè)公式,我們可以通過(guò)剩余內(nèi)存計(jì)算可以創(chuàng)建線(xiàn)程的數(shù)量。

下面是問(wèn)題出現(xiàn)的時(shí)候,從生產(chǎn)機(jī)器上執(zhí)行前面小節(jié)介紹的Linux命令free的輸出:

  1. free -m >> /tmp/free.log 
  2.              total       used       free     shared    buffers     cached 
  3. Mem:          7872       7163        709          0         31       3807 
  4. -/+ buffers/cache:       3324       4547 
  5. Swap:         4095        173       3922 
  6. Tue Jul 5 00:27:51 CST 2016 

從上面輸出可以得出,生產(chǎn)機(jī)器8G內(nèi)存,使用了7G,剩余700M可用,其中操作系統(tǒng)cache使用3.8G。操作系統(tǒng)cache使用的3.8G是用來(lái)緩存IO數(shù)據(jù)的,如果進(jìn)程內(nèi)存不夠用,這些內(nèi)存是可以釋放出來(lái)優(yōu)先分配給進(jìn)程使用。然而,我們暫時(shí)并不需要考慮這塊內(nèi)存,剩余的700M空間完全可以繼續(xù)用來(lái)創(chuàng)建線(xiàn)程數(shù):

  • 700M / 1M = 700個(gè)線(xiàn)程

因此,根據(jù)內(nèi)存可用計(jì)算,當(dāng)OOM異常:unable to create new native thread問(wèn)題發(fā)生的時(shí)候,還有700M可用內(nèi)存,可以創(chuàng)建700個(gè)線(xiàn)程。

到現(xiàn)在為止可以證明此次OOM異常不是因?yàn)榫€(xiàn)程吃光所有的內(nèi)存而導(dǎo)致的。

線(xiàn)程數(shù)對(duì)比

上面提到,有兩個(gè)具體原因造成這個(gè)異常,我們上面已經(jīng)排除了第1個(gè)原因,那我們現(xiàn)在從第2個(gè)原因入手,評(píng)估是否操作系統(tǒng)設(shè)置了應(yīng)用創(chuàng)建線(xiàn)程的最大數(shù)量,并且已經(jīng)達(dá)到了最大允許數(shù)量。

在問(wèn)題出現(xiàn)的生產(chǎn)機(jī)器上使用ulimit -a來(lái)顯示當(dāng)前的各種系統(tǒng)對(duì)用戶(hù)使用資源的限制:

  1. robert@robert-ubuntu1410:~$ ulimit -a 
  2. core file size          (blocks, -c) 0 
  3. data seg size           (kbytes, -d) unlimited 
  4. scheduling priority             (-e) 0 
  5. file size               (blocks, -f) unlimited 
  6. pending signals                 (-i) 62819 
  7. max locked memory       (kbytes, -l) 64 
  8. max memory size         (kbytes, -m) unlimited 
  9. open files                      (-n) 65535 
  10. pipe size            (512 bytes, -p) 8 
  11. POSIX message queues     (bytes, -q) 819200 
  12. real-time priority              (-r) 0 
  13. stack size              (kbytes, -s) 10240 
  14. cpu time               (seconds, -t) unlimited 
  15. max user processes              (-u) 1024 
  16. virtual memory          (kbytes, -v) unlimited 
  17. file locks                      (-x) unlimited 

這里面我們看到生產(chǎn)機(jī)器設(shè)置的允許使用的最大用戶(hù)進(jìn)程數(shù)為1024:

  1. max user processes (-u) 1024 

現(xiàn)在,我們必須獲得問(wèn)題出現(xiàn)的時(shí)候,用戶(hù)下創(chuàng)建的線(xiàn)程情況。

在問(wèn)題產(chǎn)生的時(shí)候,我們使用前面小結(jié)介紹的JVM監(jiān)控命令jstack命令打印出了Java線(xiàn)程情況,jstack命令的示例輸出如下:

  1. robert@robert-ubuntu1410:~$ jstack 2743 
  2. 2017-04-09 12:06:51 
  3. Full thread dump Java HotSpot(TM) Server VM (25.20-b23 mixed mode): 
  4.  
  5. "Attach Listener" #23 daemon prio=9 os_prio=0 tid=0xc09adc00 nid=0xb4c waiting on condition [0x00000000] 
  6.    java.lang.Thread.State: RUNNABLE 
  7.  
  8. "http-nio-8080-Acceptor-0" #22 daemon prio=5 os_prio=0 tid=0xc3341000 nid=0xb02 runnable [0xbf1bd000] 
  9.    java.lang.Thread.State: RUNNABLE 
  10.     at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) 
  11.     at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:241) 
  12.     - locked <0xcf8938d8> (a java.lang.Object) 
  13.     at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:688) 
  14.     at java.lang.Thread.run(Thread.java:745) 
  15.  
  16. "http-nio-8080-ClientPoller-1" #21 daemon prio=5 os_prio=0 tid=0xc35bc400 nid=0xb01 runnable [0xbf1fe000] 
  17.    java.lang.Thread.State: RUNNABLE 
  18.     at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) 
  19.     at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) 
  20.     at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79) 
  21.     at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) 
  22.     - locked <0xcf99b100> (a sun.nio.ch.Util$2) 
  23.     - locked <0xcf99b0f0> (a java.util.Collections$UnmodifiableSet) 
  24.     - locked <0xcf99aff8> (a sun.nio.ch.EPollSelectorImpl) 
  25.     at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) 
  26.     at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1052) 
  27.     at java.lang.Thread.run(Thread.java:745) 
  28. ...... 

從jstack命令的輸出并統(tǒng)計(jì)后,我們得知,JVM一共創(chuàng)建了904個(gè)線(xiàn)程,但是,這還沒(méi)有到最大的進(jìn)程限制1024。

  1. robert@robert-ubuntu1410:~$ grep "Thread " js.log | wc -l 
  2.      904 

這是我們思考,除了JVM創(chuàng)建的應(yīng)用層線(xiàn)程,JVM本身可能會(huì)有一些管理線(xiàn)程存在,而且操作系統(tǒng)內(nèi)用戶(hù)下可能也會(huì)有守護(hù)線(xiàn)程在運(yùn)行。

我們繼續(xù)從操作系統(tǒng)的角度來(lái)統(tǒng)計(jì)線(xiàn)程數(shù),我們使用上面小結(jié)介紹的Linux操作系統(tǒng)命令pstack,并得到如下的輸出:

  1. PID   LWP USER     %CPU %MEM CMD 
  2.     1     1 root      0.0  0.0 /sbin/init 
  3.     2     2 root      0.0  0.0 [kthreadd] 
  4.     3     3 root      0.0  0.0 [migration/0] 
  5.     4     4 root      0.0  0.0 [ksoftirqd/0] 
  6.     5     5 root      0.0  0.0 [migration/0] 
  7.     6     6 root      0.0  0.0 [watchdog/0] 
  8.     7     7 root      0.0  0.0 [migration/1] 
  9.     8     8 root      0.0  0.0 [migration/1] 
  10.     9     9 root      0.0  0.0 [ksoftirqd/1] 
  11.    10    10 root      0.0  0.0 [watchdog/1] 
  12.    11    11 root      0.0  0.0 [migration/2] 
  13.    12    12 root      0.0  0.0 [migration/2] 
  14.    13    13 root      0.0  0.0 [ksoftirqd/2] 
  15.    14    14 root      0.0  0.0 [watchdog/2] 
  16.    15    15 root      0.0  0.0 [migration/3] 
  17.    16    16 root      0.0  0.0 [migration/3] 
  18.    17    17 root      0.0  0.0 [ksoftirqd/3] 
  19.    18    18 root      0.0  0.0 [watchdog/3] 
  20.    19    19 root      0.0  0.0 [events/0] 
  21.    20    20 root      0.0  0.0 [events/1] 
  22.    21    21 root      0.0  0.0 [events/2] 
  23.    22    22 root      0.0  0.0 [events/3] 
  24.    23    23 root      0.0  0.0 [cgroup] 
  25.    24    24 root      0.0  0.0 [khelper] 
  26.  
  27.  ...... 
  28.  
  29.  7257  7257 zabbix    0.0  0.0 /usr/local/zabbix/sbin/zabbix_agentd: active checks #2 [idle 1 sec] 
  30.  7258  7258 zabbix    0.0  0.0 /usr/local/zabbix/sbin/zabbix_agentd: active checks #3 [idle 1 sec] 
  31.  7259  7259 zabbix    0.0  0.0 /usr/local/zabbix/sbin/zabbix_agentd: active checks #4 [idle 1 sec] 
  32.  
  33.  ...... 
  34.  
  35.  9040  9040 app       0.0 30.5 /apps/prod/jdk1.6.0_24/bin/java -Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Ddbconfigpath=/apps/dbconfig/ -Djava.io.tmpdir=/apps/data/java-tmpdir -server -Xms2048m -Xmx2048m -XX:PermSize=128m -XX:MaxPermSize=512m -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.10.194 -Dcom.sun.management.jmxremote.port=6969 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Xshare:off -Dhostname=sjsa-trade04 -Djute.maxbuffer=41943040 -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -Dworkdir=/apps/data/tomcat-work -Djava.endorsed.dirs=/apps/product/tomcat-trade/endorsed -classpath commonlib:/apps/product/tomcat-trade/bin/bootstrap.jar:/apps/product/tomcat-trade/bin/tomcat-juli.jar -Dcatalina.base=/apps/product/tomcat-trade -Dcatalina.home=/apps/product/tomcat-trade -Djava.io.tmpdir=/apps/data/tomcat-temp/ org.apache.catalina.startup.Bootstrap start 
  36.  9040  9041 app       0.0 30.5 /apps/prod/jdk1.6.0_24/bin/java -Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Ddbconfigpath=/apps/dbconfig/ -Djava.io.tmpdir=/apps/data/java-tmpdir -server -Xms2048m -Xmx2048m -XX:PermSize=128m -XX:MaxPermSize=512m -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.10.194 -Dcom.sun.management.jmxremote.port=6969 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Xshare:off -Dhostname=sjsa-trade04 -Djute.maxbuffer=41943040 -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -Dworkdir=/apps/data/tomcat-work -Djava.endorsed.dirs=/apps/product/tomcat-trade/endorsed -classpath commonlib:/apps/product/tomcat-trade/bin/bootstrap.jar:/apps/product/tomcat-trade/bin/tomcat-juli.jar -Dcatalina.base=/apps/product/tomcat-trade -Dcatalina.home=/apps/product/tomcat-trade -Djava.io.tmpdir=/apps/data/tomcat-temp/ org.apache.catalina.startup.Bootstrap start 
  37.  
  38. ...... 

通過(guò)命令統(tǒng)計(jì)用戶(hù)下已經(jīng)創(chuàng)建的線(xiàn)程數(shù)為1021。

  1. $ grep app pthreads.log | wc -l 
  2.     1021 

現(xiàn)在我們確定,1021的數(shù)字已經(jīng)相當(dāng)?shù)慕咏?021的最大進(jìn)程數(shù)了,正如前面我們提到,在Linux操作系統(tǒng)里,線(xiàn)程是通過(guò)輕量級(jí)的進(jìn)程實(shí)現(xiàn)的,因此,限制用戶(hù)的最大進(jìn)程數(shù),就是限制用戶(hù)的最大線(xiàn)程數(shù),至于為什么沒(méi)有精確達(dá)到1024這個(gè)最大值就已經(jīng)報(bào)出異常,應(yīng)該是系統(tǒng)的自我保護(hù)功能,在還剩下3個(gè)線(xiàn)程的前提下,就開(kāi)始報(bào)錯(cuò)。

到此為止,我們已經(jīng)通過(guò)分析來(lái)找到問(wèn)題的原因,但是,我們還是不知道為什么會(huì)創(chuàng)建這么多的線(xiàn)程,從第一個(gè)輸出得知,JVM已經(jīng)創(chuàng)建的應(yīng)用線(xiàn)程有907個(gè),那么他們都在做什么事情呢?

于是,在問(wèn)題發(fā)生的時(shí)候,我們又使用JVM的jstack命令,查看輸出得知,每個(gè)線(xiàn)程都阻塞在打印日志的語(yǔ)句上,log4j中打印日志的代碼實(shí)現(xiàn)如下:

  1. public void callAppenders(LoggingEvent event) { 
  2.     int writes = 0; 
  3.     for(Category c = this; c != null; c=c.parent) { 
  4.         // Protected against simultaneous call to addAppender, removeAppender,... 
  5.         synchronized(c) { 
  6.             if(c.aai != null) { 
  7.                 writes += c.aai.appendLoopOnAppenders(event); 
  8.             } 
  9.             if(!c.additive) { 
  10.                 break; 
  11.             } 
  12.         } 
  13.     } 
  14.     if(writes == 0) { 
  15.         repository.emitNoAppenderWarning(this); 
  16.     } 

在log4j中,打印日志有一個(gè)鎖,鎖的作用是讓打印日志可以串行,保證日志在日志文件中的正確性和順序性。

那么,新的問(wèn)題又來(lái)了,為什么只有凌晨0點(diǎn)會(huì)出現(xiàn)打印日志阻塞,其他時(shí)間會(huì)偶爾發(fā)生呢?這時(shí),我們帶著新的線(xiàn)索又回到問(wèn)題開(kāi)始的思路,凌晨12點(diǎn)應(yīng)用沒(méi)有定時(shí)任務(wù),系統(tǒng)會(huì)不會(huì)有其他的IO密集型的任務(wù),比如說(shuō)歸檔日志、磁盤(pán)備份等?

經(jīng)過(guò)與運(yùn)維部門(mén)碰頭,基本確定是每天凌晨0點(diǎn)日志切割導(dǎo)致磁盤(pán)IO被占用,于是堵塞打印日志,日志是每個(gè)工作任務(wù)都必須的,日志阻塞,線(xiàn)程池就阻塞,線(xiàn)程池阻塞就導(dǎo)致線(xiàn)程池被撐大,線(xiàn)程池里面的線(xiàn)程數(shù)超過(guò)1024就會(huì)報(bào)錯(cuò)。

到這里,我們基本確定了問(wèn)題的原因,但是還需要對(duì)日志切割導(dǎo)致IO增大進(jìn)行分析和論證。

首先我們使用前面小結(jié)介紹的vmstat查看問(wèn)題發(fā)生時(shí)IO等待數(shù)據(jù):

  1. vmstat 2 1 >> /tmp/vm.log 
  2. procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- 
  3.  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st 
  4.  3  0 177608 725636  31856 3899144    0    0     2    10    0    0  39  1 1  59  0     
  5. Tue Jul 5 00:27:51 CST 2016 

可見(jiàn),問(wèn)題發(fā)生的時(shí)候,CPU的IO等待為59%,同時(shí)又與運(yùn)維部門(mén)同事復(fù)盤(pán),運(yùn)維同事確認(rèn),腳本切割通過(guò)cat命令方法,先把日志文件cat后,通過(guò)管道打印到另外一個(gè)文件,再清空原文件,因此,一定會(huì)導(dǎo)致IO的上升。

其實(shí),問(wèn)題的過(guò)程中,還有一個(gè)疑惑,我們認(rèn)為線(xiàn)程被IO阻塞,線(xiàn)程池被撐開(kāi),導(dǎo)致線(xiàn)程增多,于是,我們查看了一下Tomcat線(xiàn)程池的設(shè)置,我們發(fā)現(xiàn)Tomcat線(xiàn)程池設(shè)置了800,按理說(shuō),永遠(yuǎn)不會(huì)超過(guò)1024。

  1. <Connector port="8080"      
  2.                maxThreads="800" minSpareThreads="25" maxSpareThreads="75"      
  3.                enableLookups="false" redirectPort="8443" acceptCount="100"      
  4.                debug="0" connectionTimeout="20000"       
  5.                disableUploadTimeout="true" /> 

關(guān)鍵在于,筆者所在的支付平臺(tái)服務(wù)化架構(gòu)中,使用了兩套服務(wù)化框架,一個(gè)是基于dubbo的框架,一個(gè)是點(diǎn)對(duì)點(diǎn)的RPC,用來(lái)緊急情況下dubbo服務(wù)出現(xiàn)問(wèn)題,服務(wù)降級(jí)使用。

每個(gè)服務(wù)都配置了點(diǎn)對(duì)點(diǎn)的RPC服務(wù),并且獨(dú)享一個(gè)線(xiàn)程池:

  1. <Connector port="8090"      
  2.                maxThreads="800" minSpareThreads="25" maxSpareThreads="75"      
  3.                enableLookups="false" redirectPort="8443" acceptCount="100"      
  4.                debug="0" connectionTimeout="20000"       
  5.                disableUploadTimeout="true" /> 

由于我們?cè)趯?duì)dubbo服務(wù)框架進(jìn)行定制化的時(shí)候,設(shè)計(jì)了自動(dòng)降級(jí)原則,如果dubbo服務(wù)負(fù)載變高,會(huì)自動(dòng)切換到點(diǎn)對(duì)點(diǎn)的RPC框架,這也符合微服務(wù)的失效轉(zhuǎn)移原則,但是設(shè)計(jì)中沒(méi)有進(jìn)行全面的考慮,一旦一部分服務(wù)切換到了點(diǎn)對(duì)點(diǎn)的RPC,而一部分的服務(wù)沒(méi)有切換,就導(dǎo)致兩個(gè)現(xiàn)場(chǎng)池都被撐滿(mǎn),于是超過(guò)了1024的限制,就出了問(wèn)題。

到這里,我們基本可以驗(yàn)證,問(wèn)題的根源是日志切割導(dǎo)致IO負(fù)載增加,然后阻塞線(xiàn)程池,最后發(fā)生OOM:unable to create new native thread。

剩下的任務(wù)就是最小化重現(xiàn)的問(wèn)題,通過(guò)實(shí)踐來(lái)驗(yàn)證問(wèn)題的原因。我們與性能壓測(cè)部門(mén)溝通,提出壓測(cè)需求:

  1. Tomcat線(xiàn)程池最大設(shè)置為1500.
  2. 操作系統(tǒng)允許的最大用戶(hù)進(jìn)程數(shù)1024.
  3. 在給服務(wù)加壓的過(guò)程中,需要人工制造繁忙的IO操作,IO等待不得低于50%。

經(jīng)過(guò)壓測(cè)壓測(cè)部門(mén)的一下午努力,環(huán)境搞定,結(jié)果證明完全可以重現(xiàn)此問(wèn)題。

最后,與所有相關(guān)部門(mén)討論和復(fù)盤(pán),應(yīng)用解決方案,解決方案包括:

  1. 全部應(yīng)用改成按照小時(shí)切割,或者直接使用log4j的日志滾動(dòng)功能。
  2. Tomcat線(xiàn)程池的線(xiàn)程數(shù)設(shè)置與操作系統(tǒng)的線(xiàn)程數(shù)設(shè)置不合理,適當(dāng)?shù)臏p少Tomcat線(xiàn)程池線(xiàn)程數(shù)量的大小。
  3. 升級(jí)log4j日志,使用logback或者log4j2。

這次OOM問(wèn)題的可以歸結(jié)為“多個(gè)因、多個(gè)果、多臺(tái)機(jī)器、多個(gè)服務(wù)池、不同時(shí)間”,針對(duì)這個(gè)問(wèn)題,與運(yùn)維部、監(jiān)控部和性能壓測(cè)部門(mén)的同事奮斗了幾天幾夜,終于通過(guò)在線(xiàn)上抓取信息、分析問(wèn)題、在性能壓測(cè)部門(mén)同事的幫助下,最小化重現(xiàn)問(wèn)題并找到問(wèn)題的根源原因,最后,針對(duì)問(wèn)題產(chǎn)生的根源提供了有效的方案。

3. 與監(jiān)控同事現(xiàn)場(chǎng)編寫(xiě)的腳本

本節(jié)提供一個(gè)筆者在實(shí)踐過(guò)程中解決OOM問(wèn)題的一個(gè)簡(jiǎn)單腳本,這個(gè)腳本是為了解決OOM(unable to create native thread)的問(wèn)題而在問(wèn)題機(jī)器上臨時(shí)編寫(xiě),并臨時(shí)使用的,腳本并沒(méi)有寫(xiě)的很專(zhuān)業(yè),筆者也沒(méi)有進(jìn)行優(yōu)化,保持原汁原味的風(fēng)格,這樣能讓讀者有種身臨其境的感覺(jué),只是為了抓取需要的信息并解決問(wèn)題,但是在線(xiàn)上問(wèn)題十分火急的情況下,這個(gè)腳本會(huì)有大用處。

  1. #!/bin/bash 
  2.  
  3. ps -Leo pid,lwp,user,pcpu,pmem,cmd >> /tmp/pthreads.log 
  4. echo "ps -Leo pid,lwp,user,pcpu,pmem,cmd >> /tmp/pthreads.log" >> /tmp/pthreads.log 
  5. echo `date` >> /tmp/pthreads.log 
  6. echo 1 
  7.  
  8. pid=`ps aux|grep tomcat|grep cwh|awk -F ' ' '{print $2}'
  9. echo 2 
  10.  
  11. echo "pstack $pid >> /tmp/pstack.log" >> /tmp/pstack.log 
  12. pstack $pid >> /tmp/pstack.log 
  13. echo `date` >> /tmp/pstack.log 
  14. echo 3 
  15.  
  16. echo "lsof >> /tmp/sys-o-files.log" >> /tmp/sys-o-files.log 
  17. lsof >> /tmp/sys-o-files.log 
  18. echo `date` >> /tmp/sys-o-files.log 
  19. echo 4 
  20.  
  21. echo "lsof -p $pid >> /tmp/service-o-files.log" >> /tmp/service-o-files.log 
  22. lsof -p $pid >> /tmp/service-o-files.log 
  23. echo `date` >> /tmp/service-o-files.log 
  24. echo 5 
  25.  
  26. echo "jstack -l $pid  >> /tmp/js.log" >> /tmp/js.log 
  27. jstack -l -F $pid  >> /tmp/js.log 
  28. echo `date` >> /tmp/js.log 
  29. echo 6  
  30.  
  31. echo "free -m >> /tmp/free.log" >> /tmp/free.log 
  32. free -m >> /tmp/free.log 
  33. echo `date` >> /tmp/free.log 
  34. echo 7 
  35.  
  36. echo "vmstat 2 1 >> /tmp/vm.log" >> /tmp/vm.log 
  37. vmstat 2 1 >> /tmp/vm.log 
  38. echo `date` >> /tmp/vm.log 
  39. echo 8 
  40.  
  41. echo "jmap -dump:format=b,file=/tmp/heap.hprof 2743" >> /tmp/jmap.log 
  42. jmap -dump:format=b,file=/tmp/heap.hprof >> /tmp/jmap.log 
  43. echo `date` >> /tmp/jmap.log 
  44. echo 9 
  45.  
  46. echo end 

如果讀者在線(xiàn)上已經(jīng)遇到了OOM的問(wèn)題,可以順著這個(gè)看似簡(jiǎn)陋而又信息滿(mǎn)滿(mǎn)的Java服務(wù)的監(jiān)控腳本的思路,利用本文提供的各種腳本和命令來(lái)深挖問(wèn)題的根本原因。

點(diǎn)擊《教你如何成為Java的OOM Killer》閱讀原文。

【本文為51CTO專(zhuān)欄作者“李艷鵬”的原創(chuàng)稿件,轉(zhuǎn)載可通過(guò)作者簡(jiǎn)書(shū)號(hào)(李艷鵬)或51CTO專(zhuān)欄獲取聯(lián)系】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專(zhuān)欄
相關(guān)推薦

2020-07-08 07:50:50

OOM虛擬機(jī)Java

2012-09-27 10:41:26

2019-01-28 11:54:28

程序員技能溝通

2021-02-05 14:56:39

YouTube編程程序員

2009-06-17 15:18:09

Java環(huán)境

2020-07-08 09:50:37

Java內(nèi)存快速定位

2019-11-05 08:24:34

JavaOOM快速定位

2023-10-09 22:44:51

調(diào)試代碼

2021-12-10 23:48:19

Java開(kāi)發(fā)技術(shù)

2021-09-09 16:32:41

Java泛型框架

2015-10-08 10:04:39

Python高手

2022-10-12 10:30:35

IT思想領(lǐng)袖企業(yè)

2014-03-06 10:34:18

RSA2014

2011-09-01 15:01:38

網(wǎng)頁(yè)設(shè)計(jì)

2022-05-01 09:23:50

RosedbContributo重構(gòu)

2021-02-21 13:49:48

Java程序員開(kāi)發(fā)

2021-12-06 10:21:50

LinuxDNS 查詢(xún)

2010-07-22 13:14:26

telnet mail

2011-02-21 17:04:57

postfix

2011-05-04 10:53:46

打印機(jī)技巧
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

日韩精品亚洲人成在线观看| 国产成人免费在线视频| 99热这里只有精品在线| 欧洲一区二区在线| 亚洲精品一卡二卡| 久久麻豆视频| 美女100%露胸无遮挡| 欧美一区二区三区精品电影| 懂色av一区二区三区免费观看| 在线视频91p| www.com黄色片| 在线看日韩欧美| 久久精品卡一| 中文日本在线观看| 欧美在线aaa| 久久精品99无色码中文字幕| 久久精品av麻豆的观看方式| 在线观看精品一区二区三区| 日韩手机在线观看视频| 亚洲最新中文字幕| 久久精品国产精品亚洲精品| 日本在线免费| 在线观看免费视频国产| 97在线视频一区| 国产清纯美女被跳蛋高潮一区二区久久w| 国产精品高颜值在线观看| 新91视频在线观看| 91丝袜美腿美女视频网站| 一区二区三区毛片| 亚洲人成亚洲精品| 在线免费看av的网站| 国产一级大片免费看| 国产视频在线一区二区| 久久99精品国产麻豆婷婷洗澡| av软件在线观看| 素人fc2av清纯18岁| 91影视免费在线观看| 午夜视频久久久久久| 国产精品探花在线观看| 99久久精品无免国产免费| 99色精品视频| 欧美精品久久一区二区| 亚洲色图.com| 欧美成人自拍| 精品影院一区| 国产精品揄拍100视频| 91免费精品国偷自产在线| 色婷婷精品久久二区二区蜜臀av| 亚洲视频电影在线| 性开放的欧美大片| 爱爱的免费视频| 精品一区二区视频| 亚洲第一视频网站| 成人午夜又粗又硬又大| 蜜桃精品视频| 国产黄色高清视频| 黄色一级片免费播放| 国产精品亚洲综合天堂夜夜| 在线观看91精品国产入口| 久久久久久久欧美精品| 欧美aa在线观看| 亚洲欧美日韩激情| 亚洲精品一二三四五区| 国产欧美日韩丝袜精品一区| 欧美性欧美巨大黑白大战| 蜜臀a∨国产成人精品| 97色婷婷成人综合在线观看| 一个人看的www日本高清视频| 国内国产精品天干天干| 亚洲va男人天堂| 精品国产凹凸成av人网站| 99精品久久久久久| 欧美理论电影大全| 天堂а√在线资源在线| 免费在线观看国产精品| 免费看日本毛片| 国产日韩av高清| 精品国产免费人成电影在线观看四季 | 亚洲国产精品影院| 久久久久久久高潮| 91综合精品国产丝袜长腿久久| 亚洲av毛片成人精品| 欧洲美女女同性互添| 北条麻妃在线视频观看| 国产精品青草久久久久福利99| 欧美一区二区啪啪| 久久久久88色偷偷免费| 欧美激情视频一区二区三区在线播放 | 亚洲sss综合天堂久久| 亚洲欧美国产制服动漫| 亚洲蜜臀av乱码久久精品| 久久九九99| 女同久久另类99精品国产| 精品孕妇一区二区三区| 中文字幕在线天堂| 午夜男人的天堂| 日本丰满少妇黄大片在线观看| 日本中文字幕不卡免费| 欧美tk丨vk视频| 亚洲少妇中出一区| 狠狠色综合日日| 久久亚洲成人| 中文字幕成人| 免费黄网站在线| 一级黄色短视频| 国产黄色片在线| 色一情一区二区三区| 亚洲三区四区| 国产日韩在线视频| 菠萝蜜影院一区二区免费| 色婷婷精品大视频在线蜜桃视频| 91丝袜高跟美女视频| 亚洲欧美日韩一区在线观看| 日本国产精品| 视频欧美精品| 神马午夜伦理不卡| 无码精品人妻一区二区| 天天干在线播放| 蜜桃视频最新网址| 波多野结衣网页| 黄页免费在线观看视频| 日韩av电影免费播放| 成人福利视频网| 欧美国产精品va在线观看| 亚洲国产精彩中文乱码av| 狠狠做深爱婷婷久久综合一区| 国产日本欧美一区二区| 国产福利不卡视频| 日韩国产欧美在线观看| 欧美一区精品| 日本一本不卡| 国产精品午夜av| 日韩综合av| a天堂资源在线| 国产人成网在线播放va免费| 欧美日韩在线精品一区二区三区激情综| 成人毛片一区二区三区| 国产亚洲精品av| 成人免费视频入口| 亚洲一级中文字幕| 亚洲av成人片色在线观看高潮| 久久99999| 麻豆av免费在线| 日韩欧美一区二| 免费拍拍拍网站| 91xxx视频| 一区二区三区三区在线| 日韩国产高清一区| 欧美噜噜久久久xxx| 久久五月天色综合| 久久午夜a级毛片| 欧美日韩在线第一页| 亚洲午夜三级在线| 性做久久久久久免费观看欧美| 亚洲人成7777| 亚洲午夜电影网| 亚洲国产精品久久艾草纯爱| 夜夜爽夜夜爽精品视频| 亚洲一区二区三区四区中文字幕| 综合激情成人伊人| 亚洲理论在线观看| 五月天网站亚洲| 色狠狠色狠狠综合| 欧美日韩成人一区二区| 91精品国产一区二区人妖| 日韩免费看网站| 亚洲国产精品久久久久| 亚洲女成人图区| 中文日韩电影网站| 久久中文字幕一区| 2019中文字幕全在线观看| 国产精国产精品| 亚洲在线一区二区| 久久香蕉综合色| 国产91av视频在线观看| www.国产在线播放| www.天天射.com| 日本少妇一区二区三区| 中文字幕在线免费看线人| 91导航在线观看| 日本一二三区不卡| 中文字幕在线2019| 亚洲第一天堂影院| 免费高清在线观看| 国产经典一区| 日日狠狠久久偷偷综合色| 99久久夜色精品国产亚洲96| 久久黄色网页| 99视频精品免费视频| 玉足女爽爽91| 欧美人体做爰大胆视频| 亚洲欧美国产一本综合首页| 欧美高清无遮挡| 91久久精品国产91久久性色tv| 神马影院我不卡午夜| 欧美一区二区三区爽大粗免费| 伊人成人免费视频| 亚洲а∨天堂久久精品2021| 国产第一页在线播放| 好吊视频一区二区三区| www.欧美日本韩国| 精品视频一区二区三区| 亚洲成av人片乱码色午夜| 美女一区二区三区| 亚洲天堂中文字幕| 制服丝袜中文字幕亚洲| 不卡av日日日| 国产精品国产精品国产专区不卡| 男女爱爱视频网站| 在线看黄色的网站| 日韩毛片在线播放| 日韩电影免费| 欧美黄色成人| 午夜精品网站| 2020国产成人综合网| 狠狠操狠狠色综合网| 亚洲午夜精品视频| 91午夜在线播放| 91丨porny丨探花| 88久久精品无码一区二区毛片| 国产在线观看第一页| a免费在线观看| 国产精品亚洲二区| 国产激情一区二区三区四区 | 美女隐私在线观看| 加勒比色综合久久久久久久久| 久久免费国产| 亚洲综合免费观看高清在线观看| 亚洲人成在线观看网站高清| 成人观看高清在线观看免费| a级免费在线观看| 亚洲熟女少妇一区二区| 天堂中文在线观看视频| 亚洲午夜国产成人| 美女黄色成人网| 一区二区三区免费网站| 神马久久久久久| 免费国产一区| 蜜臀av粉嫩av懂色av| 国产精品久久久久久久一区二区 | 国产黄色在线网站| 日本久久综合| 91蜜桃婷婷狠狠久久综合9色| 日韩三级视频在线观看| 国产主播欧美精品| 超碰影院在线观看| 一级片免费在线播放| 中国色在线日|韩| 亚洲福利免费| 性做久久久久久免费观看欧美| 久99久在线视频| 中国老女人av| 九九热视频精品| 欧美videossex| 欧美日韩日本国产亚洲在线| 一区二区三区在线视频观看| 日韩中文字幕视频在线| 在线免费观看成人网| 欧美一级片在线视频| 老司机99精品99| 一本到12不卡视频在线dvd| √…a在线天堂一区| 九九热这里只有精品免费看| 91网站在线观看免费| 亚洲国产成人精品激情在线| 亚洲涩涩在线| 久久99精品久久久久久久久久久久| 欧美美女直播网站| 草莓视频一区| japanese中文字幕| 国产在线观看免费麻豆| 亚洲精品视频啊美女在线直播| 亚洲成人一区在线| 国产精品美女呻吟| 老司机av网站| 国产在线色视频| 国产精品www994| 欧美在线一区二区| 国产精品区一区二区三含羞草| 中文字幕在线播放一区| 免费av网站在线观看| 国产毛片一区| 日韩欧美高清在线| 日韩欧美亚洲在线| 精品在线视频免费| 精品国产一级| 国产精品久久久久久久久久久免费看 | 亚洲大胆美女视频| 婷婷视频在线播放| 天天干天天插天天射| 国产毛片久久久| 亚洲另类春色国产| 成人综合网网址| 免费在线观看a视频| 国产精品电影| 91丨porny丨蝌蚪视频| 欧美黑人国产人伦爽爽爽| 一级片视频免费观看| 久草视频在线看| 亚洲欧美大片| 精品亚洲一区二区三区| 国产精品97在线| 黄色片在线免费观看| 欧美亚洲三级| 亚洲视屏在线播放| 亚洲成人av免费看| 91九色在线porn| 久久99精品久久久久久动态图 | 日本网站在线看| 怡红院在线观看| 成人激情免费电影网址| 91精品国产91久久久久久不卡| 在线免费看黄色片| 伊人色综合一区二区三区影院视频| 久久精品视频在线看| 国产精品久久久久久久久粉嫩av| 国产一区二区三区四区在线| 草民电影神马电影一区二区| 亚洲欧美激情小说另类| 国产精品久久久久久久久久久久午夜片 | 久久免费福利视频| 黑人巨大精品欧美| 伊人久久大香伊蕉在人线观看热v| 亚洲卡通欧美制服中文| 欧美精品成人一区二区在线观看| 最近中文字幕av| 欧美精品国产| 中文字幕一区二区三区电影| 色综合久久久无码中文字幕波多| yellow在线观看网址| 中文字幕一区二区日韩精品绯色| 91九色在线观看| 国产精品51麻豆cm传媒 | 亚洲精品一区二区三区香蕉| 天堂在线资源视频| 欧美私密网站| 亚洲午夜久久久久久久久电影网| 色一情一乱一伦一区二区三区| 精品人妻午夜一区二区三区四区| 久久久噜噜噜| 欧美一区二区色| 国产成人无码精品久久久久| 亚洲女同另类| 久久香蕉国产线看观看网| 国产午夜精品福利视频| 亚洲动漫精品| 亚洲欧美精品中文字幕在线| 涩视频在线观看| 欧洲精品99毛片免费高清观看| 欧美日韩你懂得| 亚洲xxxx2d动漫1| 全球最大av网站久久| 欧美色综合网站| 色国产在线视频| 欧洲精品久久久久毛片完整版| 色偷偷88欧美精品久久久| 欧美日韩国产精品激情在线播放| 九九精品调教| 亚洲一区二区三区激情| 欧美精品在欧美一区二区| 亚洲淫性视频| 亚洲二区在线视频| 久久国产亚洲精品无码| 三上悠亚激情av一区二区三区| 狠狠综合久久av一区二区小说| 国产极品美女高潮无套久久久| 亚洲成人激情社区| 欧美日韩高清一区二区三区| 女同性αv亚洲女同志| 欧美成人基地| 日韩亚洲一区二区| 日韩免费在线视频观看| 日韩vs国产vs欧美| 亚洲综合日韩在线| 欧美色视频免费| 亚洲欧美视频在线观看| 精品成在人线av无码免费看| 亚洲天堂资源| 日韩免费电影一区| 99精品欧美一区二区| 欧美日韩国产高清| 国产精品日韩欧美综合| 亚洲AV无码精品色毛片浪潮| 久久久精品中文字幕麻豆发布| 国产免费一区二区三区四在线播放| 福利写真视频网站在线| 欧美日韩国产一二三| 欧美深性狂猛ⅹxxx深喉| 综合精品一区| 国产欧美精品va在线观看| 色婷婷av一区二区三区之红樱桃 | 捆绑调教一区二区三区| 欧美精品欧美精品| 蜜桃视频在线观看播放| 精品国产一区二区在线观看| 亚洲人与黑人屁股眼交| 日韩精品久久久久久| 欧美下载看逼逼| 欧美亚洲韩国| 亚洲日韩中文字幕在线播放|