问题描述
在实际开发过程中, 将 springboot 项目打成 Docker 镜像部署在 kubernetes 集群中, 并启动容器实例, 打开日志, 发现很久才能刷一条日志, 并且项目启动超过 10 分钟!!!
如下为服务 yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-${SVC_NAME}
namespace: ${NAMESPACE}
spec:
replicas: 2
selector:
matchLabels:
app: ${SVC_NAME}
template:
metadata:
labels:
app: ${SVC_NAME}
spec:
containers:
- name: container-${SVC_NAME}
image: ${IMAGE_NAME}
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 3G
解决方案
排查的过程就不过多描述了, 究其原因, 是启动实例时, 对实例 CPU 资源限制所导致的, 也就是 yaml 文件中 resources.limits.cpu=100m
所致, 增加分配给服务的 CPU, 可相应缩短服务的启动时间, 在我的环境中, 分配 1core, 对服务启动速度的提升任然收效甚微, 所以我索性把 CPU 的资源限制去掉了, 原本启动要 1000s+, 现在的启动速度为 10s+.resources.limits.cpu=100m
为什么 CPU 资源对服务启动的影响如此之大:
jvm在启动的时候会装载并连接所有除反射以外的类,而class文件是二进制的文件,需要从磁盘加载到内存然后解析,这种解析是很耗费cpu的,那么class文件越多,cpu耗费就越高
这里列出几种提升 springboot 服务启动速度的方案
- 加cpu,效果十分明显
- 去掉不必要的pom依赖,特别是大的jar,效果和jar大小直接相关
- 随机数改成伪随机数,/dev/random改成/dev/./urandom可能十分明显,也能完全没有效果
- 修改JVM参数,屏蔽字节码校验,效果不明显
- 排除不必要的自动配置,效果不明显
如有遇到相同情况的朋友可以参考批评指正, 另外如果有优化启动的其他方案也欢迎留言.
网友评论