学习此篇之前,你必须具备两项前置技能:

1.学会使用docker以及在idea中使用docker插件.https://blog.csdn.net/lovexiaotaozi/article/details/82797236

2.学会jvm调优.https://blog.csdn.net/lovexiaotaozi/article/details/82883365


下面就带领大家一起实现在IDEA中通过docker插件实现一件自动部署+自动jvm调优,如此一来部署将变得异常简单,而且经过调优以后,容器对内存的占用率会大幅下降,可以增加部署的数量,同时因为docker天然的优势,在某些服务出现异常宕机时,不至于影响其它服务.

第一步:通过前置的Jvm调优得出具体的调优参数,我这里通过反复分析垃圾回收日志,不断调试最终得出的Jvm调优参数如下(仅供参考):

-Xms256m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200

第二步:在你的dockerfile里添加:

(其中$JAVA_OPTS你可以随便命名,但为了规范还是推荐大家按这样命名,xxx.jar为你打包之后的项目名)

ENTRYPOINT exec java $JAVA_OPTS -jar xxx.jar

出于有人对dockerfile不熟的考虑,所以这里完整的dockerfile也给大家看一下:

From hub.c.163.com/library/java:8-jre

ADD target/*.jar ylt-zipkin.jar

EXPOSE 9411

ENTRYPOINT exec java $JAVA_OPTS -jar ylt-zipkin.jar

第三步:

Run->EditConfigurations->docker->Dockerfile->填写相关内容,并把你调优后的参数添加至Enviroment variables里,值得注意的是,

key必须为JAVA_OPTS(也就是必须跟前面Dockerfile里写的那个名字一样),value为你最终得出的jvm调优参数.

如此一来就大功告成了,为了测试到底有没有生效,你可以在你服务器上用free -m来观察项目启动前后的内存占用率,然后再在服务器里直接使用docker run 不添加参数来启动容器,观察内存占用率,我这里观察确认使用调优后的内存占用率比没使用前大约节省了一半左右的内存.

这是尚未启动该服务前的内存:

使用普通方式启动该容器后的内存:

可以看出该服务仅在启动后就差不多占用了800M的内存.

使用jvm调优一键部署方式启动后的内存:

可以看出,调优后的内存占用率只有350M,节约了一半多的内存空间,这对于小公司来说其实是一笔非常可观的支出节省,我们公司一共四台服务器,如果服务都使用这种方式部署,跟原来比就相当于拥有了8台服务器,而且宕机互不影响,不会一崩全崩,按目前三大云的价格,多出的四台服务器价格每年节省好几万,再说部署效率,使用这种方式部署后,比原来会节省很多时间,原来10多个微服务如果有内容修改了之后,需要一个一个打包,杀进程,上传至服务器,启动,如此繁琐...有时候本地调的好好的项目在服务器上部署后却有问题,不方便排查,即便排查好了那么多服务重新部署又很累...,现在只需要在本地IDEA里点一下按钮,OK部署成功...对整个团队来说,一年下来节约的时间成本绝对是一笔不小的数目,所以再次强烈推荐.


再说网上常见的docker下的jvm调优:

网上搜到的一般会让你在dockerfile里直接指定调优参数,比如:

CMD ["java", "-Xmx600m", "-jar", "/usr/local/test/data/test-1.0-SNAPSHOT.jar"]

 但是这种方式下只能指定个堆大小,并不能指定你使用哪种GC方式,以及更多的JVM调优参数,于是你开始尝试在启动容器时添加参数,比如:

docker run -e JAVA_OPTS=’-Xmx3g -Xms3g -XX:+UseG1GC’ spring-boot-javaopts

但你发现这样启动和没加参数启动效果是一样的,并没有生效,究其原因可以参考这里(访问不了的话请翻墙):

https://medium.com/@cl4r1ty/docker-spring-boot-and-java-opts-ba381c818fa2

BB了这么多就是想告诉你,别去看网上那些了,坑很多,并没有给你一个行之有效的解决方法,我在这个坑里摸爬滚打了一个下午才爬出来,这些都是总结的经验所得,直接拿去用就好了,不要质疑...


 

最后谈一下Jdk版本,目前大多数公司使用的Jdk版本是1.8或更旧的版本,但目前jdk已出到11了,大部分人都不愿意尝试更新的Jdk版本,原因是未使用过,然后用的人也不多,怕里面有一些未知的bug,或者说怕踩坑,万一踩到了又会因为用的人少缺乏解决的办法等,各种因素加起来使得大多数公司都比较保守,使用比较老旧的jdk版本,图个稳定,但我个人是更加推崇使用较新的jdk版本的,即便你不使用jdk新版本里的新特性,但仍有些地方是你可以用到的,比如jvm调优,jdk9的G1GC已经非常成熟,调优变得更加自动化简单高效.对docker的支持也更加完善...

可以参考:http://m.it168.com/detailText.html?id=5009180

在IT行业,技术的变更和迭代是非常快的,如果一昧的因循守旧,不愿意尝试新的技术,那只会被时代的潮流所抛弃,就像springboot,一开始还没多少人用吧,现在你可以出去看看,不会springboot找工作谁还要你...我还是比较推荐大家激进一点,尝试更高的Jdk版本,年轻多尝试新事物,不要怕踩坑,万一真踩到了就想办法爬出来,用尽一切办法,爬出来之后你会发现你的能力会有更大提升,绝不止步于浪费了时间.

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐