实例 FROM java:8 VOLUME /tmp ADD app.jar app.jar RUN bash -c 'touch /app.jar' EXPOSE 9001 ENV JAVA_OPTS=" -server -Xmx4g -Xms4g -Xmn2g -XX:SurvivorRatio=8 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy -XX:+PrintGCDetails -XX:+PrintTenuringDistribution -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/ -Xloggc:/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileS.... dockerfile指定jvm参数 Docker java jvm OOM内存溢出问题排查 诊断监控 java
这两天客户这边有一台服务器一到下午3点左右就开始卡住,页面无法访问,服务器CPU占用达到300%多 开始以为只是可能只是意外事件,重启一下就好,但是发现重启之后没几分钟服务器马上又反应无法访问,我就开始检查自己写的代码是不是有什么非常消耗CPU资源的逻辑,但是找了一段时间之后还是一无所获,不过马上反应的就是先把最新提交发布的代码还原到上一个版本。但是没过多久还是反应服务器开始又开始无法访问了。 于是就 第一步: 通过 top命令查找到这个消耗CPU的进程号PID 8958 top 第二步:使用 top -Hp pid( shift+p 按cpu排序,shift+m 按内存排序 ) top -Hp 8958 获取到这个进程下面所有线程,通过查看%CPU找到最耗费CPU的是线程PID 第三步:使用 printf '%x\n' PID (PID为上一步中获取到的线程号)转换成对应的16进制PID 5c7e 第四步:使用jstack 获取对应的线程信息 jstack 8958 | grep 5c7e 注意:8958是一开始获取的进程号,而5c7e则是这个进程下面最最耗费CPU的线程号 .... JVM找出占用CPU最高的线程 jvm
1. 问题 spring-cloud-gateway 网关新增了一个限流功能,使用的是模块自带的限流过滤器 RequestRateLimiterGatewayFilterFactory,基于令牌桶算法,通过 redis 实现。 其原理是 redis 中针对每个限流要素(比如针对接口限流),保存 2 个 key:tokenKey(令牌数量),timeKey(调用时间)。每次接口调用时,更新 tokenKey 的值为:原先的值 + (当前时间 - 原先时间)* 加入令牌的速度,如果新的 tokenKey 的值大于 1,那么允许调用,否则不允许;同时更新 redis 中 tokenKey,timeKey 的值。整个过程通过 lua 脚本实现。 在加入限流功能之前,500 客户端并发访问,tps 为 6800 req/s,50% 时延为 70ms;加入限流功能之后,tps 为 2300 req/s,50% 时延为 205ms,同时,原先 cpu 占用率几乎 600%(6 核) 变成不到 400%(cpu 跑不满了)。 2. 排查和解决过程 2.1 单个 CPU 跑满 查看单个线程的 cpu .... java性能调优记录 java
在java程序运行时,如果替换classpath下的某个jar包文件,可能会导致程序出现ClassNotFoundException**。 具体场景 我们要升级线上服务时,可能经常只需要替换其中一两个jar包即可完成升级。有时我们为了方便,经常会先替换完jar包再进行重启。其实这样的做法会有一个隐患,如果在你重启之前程序需要从这个jar包加载某个类的话,即使这个类在这个jar包中,也会导致程序出现ClassNotFoundException。 我们可以写个demo来验证一下这个问题 : public class A { public static void main(String[] args) throws InterruptedException { System.out.println("begin"); //在sleep期间jar包发生了改变 Thread.sleep(10000L); B b = new B(); b.print(); } } public class B { void print() { System.out.println("print B"); } }.... 有更新! 不要替换运行中JVM的相关jar包 jvm