背景

最近在支持公司priority 1 的项目:性能测试
作为ci/cd team,我们的职责是准备docker化的测试site。

break down task

  • 基于k8s cluster 部署services的yml文件
  • 集成monitor工具-newrelic 监控java apm信息
  • import performance data
    总体方案:
    部署learn-tomcat 、集成newrelic、import data 作为三个进程执行,部署在一个container中(name:learn)。
    初步验证:
    import data 进程(sh batch_ImportExport.sh 260个data txt文件 行分布,每行一条data)花费了25个小时,这么长时间,出现中断不稳定的可能性很大,risk很大。于是准备优化。

踩过的坑

mesos 环境部署时,为learn container分配了 5个cpu 10G memory。 导入260条course data,占用了3.4G memory。
一条data 277M ,260条data 约72G。
现象:移植到k8s 时,花费将近50个小时,偶尔出现import数据中断。request :memory 5G cpu 5个 limit 未设置
排查:
kubectl exec 进入container,ps -aux|grep java ,发现进程意外退出。
分析:
为什么jvm的进程会意外退出?
猜测原因,逐步验证:
google一把,“Java options that can have an impact on server performance.”
测试思维,对比测试。测试环境有问题时,不知道如何分析排查问题,则找生产环境看看。寻找灵感,于是查找一个正确的site ,对比进程信息,寻找蛛丝马迹。

bbuser      361    359 14 Nov28 ?        10:30:35 /usr/lib/jvm/java-8-oracle/bin/java -d64 -server -Dblackboard.wrapper.anchorfile=/usr/local/blackboard/apps/tomcat/work/tomcat.anchor -Dblackboard.wrapper.commandfile=/usr/local/blackboard/apps/tomcat/work/wrapper.command -Xss1M -Djava.io.tmpdir=/usr/local/blackboard/apps/tomcat/temp -Djava.security.manager -Djava.security.policy==/usr/local/blackboard/apps/tomcat/conf/catalina.policy -Djava.util.logging.config.file=/usr/local/blackboard/config/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Dfile.encoding=UTF-8 -Dcatalina.home=/usr/local/blackboard/apps/tomcat -Dcatalina.base=/usr/local/blackboard/apps/tomcat -Dblackboard.home=/usr/local/blackboard -Dblackboard.shared.home=/mnt/mesos/sandbox/bbcontent -Dbbservices_config=/usr/local/blackboard/config/service-config.properties -Djava.awt.headless=true -Dcom.sun.management.jmxremote -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/blackboard/logs/tomcat -Xloggc:/usr/local/blackboard/logs/tomcat/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:ReservedCodeCacheSize=128m -XX:InitialCodeCacheSize=16m -XX:+DoEscapeAnalysis -XX:+CMSClassUnloadingEnabled -Dsun.net.inetaddr.ttl=60 -Djava.net.preferIPv4Stack=true -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45 -XX:+UseStringDeduplication -XX:MetaspaceSize=1024m -Dsun.net.maxDatagramSockets=512 -XX:StringTableSize=200003 -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2 -Dsun.net.client.defaultConnectTimeout=30000 -Dsun.net.client.defaultReadTimeout=30000 -Dorg.apache.activemq.SERIALIZABLE_PACKAGES=java.lang,java.util,org.apache.activemq,org.fusesource.hawtbuf,com.thoughtworks.xstream.mapper,net.sf.ehcache.distribution -javaagent:/usr/local/blackboard/apps/newrelic/newrelic.jar -Xms2048m -Xmx2048m -Djava.library.path=/usr/local/blackboard/apps/service-wrapper/lib:/usr/local/blackboard/apps/tomcat/lib:/usr/local/blackboard/apps/exec/lib:/usr/local/blackboard/apps/oracle-client/lib64:/usr/local/blackboard/apps/sigar/lib -classpath /usr/local/blackboard/apps/service-wrapper/lib/wrapper.jar:/usr/lib/jvm/java-8-oracle/lib/tools.jar:/usr/local/blackboard/apps/tomcat/lib/bb-tomcat-bootstrap.jar:/usr/local/blackboard/apps/tomcat/bin/bootstrap.jar:/usr/local/blackboard/apps/tomcat/bin/tomcat-juli.jar -Dwrapper.key=Wqxt3eT4aRqrbpQJ -Dwrapper.port=32000 -Dwrapper.jvm.port.min=31000 -Dwrapper.jvm.port.max=31999 -Dwrapper.pid=359 -Dwrapper.version=3.2.3 -Dwrapper.native_library=wrapper.64 -Dwrapper.disable_shutdown_hook=TRUE -Dwrapper.cpu.timeout=10 -Dwrapper.jvmid=1 org.tanukisoftware.wrapper.WrapperStartStopApp blackboard.tomcat.startup.ThreadDumpWrapper 1 start blackboard.tomcat.startup.ThreadDumpWrapper true 1 stop

由于newrelic的集成,是我负责的。当时-javaagent option后面有一串特殊的字符“-Xms2048m -Xmx2048m ” 当时无知,不太清楚这是什么含义,由于有事情没有细究。
老大知道这个不稳定的问题后,在manager会议上,了解到开发在生产环境 import数据的脚本分享给我们。
查看脚本,发现了如下信息:

sed -i '/OPTS=""/a OPTS="$OPTS -Xmx28g"' /usr/local/blackboard/apps/content-exchange/bin/batch_ImportExport.sh

突然灵感一现,好熟悉的字眼。锁定“$OPTS -Xmx28g”。
修改方案:
假设是导数据的过程需要耗费大量的memory,一次性倒入260条数据,边倒入边写db,则换个思路,切割data文件,一次性读取50个,则需要耗费的memory是不是会减小?
k8s 同一个container内的三个进程是不是共享memory的?

学到知识点

  • jvm opts: -Xms2048m -Xmx2048m heap size 最小 最大值 一般情况两个值设置为一样,等于系统Ram的一半最佳。过小,会影响server performance ;过大,会增加垃圾回收时间。
  • jvm opts: -javaagent newrelic.jar 插件jar包形式 一种开发思维
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐