前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java进程管理规范

Java进程管理规范

原创
作者头像
iginkgo18
发布2023-07-21 15:08:56
2700
发布2023-07-21 15:08:56
举报
文章被收录于专栏:devops_k8sdevops_k8s

1 需求

无论是在spring boot 还是spring cloud 项目中,随着应用的不断增多,JVM参数的统一管理的重要性就会凸显出来,否则你可能会遇到几个问题:

  • Java进程出现性能问题,无GC日志支撑提供重要信息;
  • OOM异常频发,无法通过dump文件进行分析定位;
  • JVM堆内存设置规格不一致,被动等待出问题时发现;

作为运维,虽然没有超强的能力去最终的定位、分析、排查问题,但并不意味着我们就可以袖手旁观,那么我们能做什么呢?

  • 首先,我们要知道Java进程默认参数启动并不会打印某些我们需要的日志,而是需要我们按需去设置的。
  • 其次,即使开启了相应的日志参数,其统一输出位置就成了我们需要面对的问题,毕竟我们不希望满盘搜文件,浪费不必要的时间。
  • 最后,各种个性化的JVM参数,无益于运维对数量为百、千级别进程的有效管理。

此时统一的Java进程管理规范就可以发挥作用,通过标准化部署,Java使用统一的JVM参数运行,一旦某个应用出现异常,我们可以快速收集各种异常日志提供给研发进一步定位问题。

最终目标是,运维能提供给研发的有效信息,肯定是排除了因环境差异、参数配置差异等这些低级别干扰因素的,这样才能保证运维和研发的快速定位。

2 进程规范

2.1 GC日志

GC日志是用来描述JAVA虚拟机垃圾回收情况,主要用来快速定位潜在的内存故障和性能瓶颈。默认情况下是关闭的,我们需要通过参数设置启用。

参数格式如下:

代码语言:javascript
复制
-XX:+PrintGC 输出简要GC日志 
-XX:+PrintGCDetails 输出详细GC日志 
# gc.log输出到统一的日志目录
-Xloggc:/data/logs/gc.log  输出GC日志到文件
-XX:+PrintGCTimeStamps 输出GC的时间戳(以JVM启动到当期的总时长的时间戳形式) 
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800) 
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-XX:+PrintReferenceGC 打印年轻代各个引用的数量以及时长

2.2 dump文件

dump文件是Java进程出现OOM时自动生成的文件,通过此文件可以定位进程发生OOM的位置。可配置参数自动生成 dump 文件。

代码语言:javascript
复制
-XX:+HeapDumpOnOutOfMemoryError 
# dump文件输出到统一的日志目录
-XX:HeapDumpPath=/data/logs/HeapDumpOnOutOfMemoryError.dump

2.3 堆内存

堆内存设置是我们最容易设置混乱的参数,但对于我们标准化交付的服务器,虽不至于所有的应用使用完全一致的堆内存参数,但是大多数情况下是可以统一的。

代码语言:javascript
复制
-Xms2048m
-Xmx2048m
-XX:MaxPermSize:256m

至此,常见的JVM参数设置完毕,由于这些参数多和开发定位问题有关,因此我们在此只是将其作为进程管理规范的内容进行讲解,而不是研究其具体作用。但你以为我们的工作就到此为止了吗?

我们还可以通过设置JVM环境变量来实现部分扩展功能,因此也需要将环境变量作为进程管理规范的一部分。

2.4 JVM环境变量

环境变量便于运维能够灵活控制java进程运行的参数,这样可以和自动化相结合,实现应用的统一部署,有效避免更改配置文件的动作。

关于环境变量的定义,需要结合各自的生产环境特性来自行定义,我这面的定义的变量如下:

代码语言:javascript
复制
# 应用名
-Dapp.name=test
# 环境区分
-Denv=prod或uat或stg
# 临时文件目录
-Djava.io.tmpdir=/data/tmpdir

其中比较重要的是-Denv=xxx,通过在各个环境预设此变量,可实现不同环境配置文件的绑定。例如:在spring cloud项目中可以和各环境的配置中心调用进行关联。

其他环境变量大家可以和研发协商按需灵活添加。

3 按规范管理

3.1 统一管理

通过以上各参数的简单讲解,我们有了一套比较固定且完整的JVM参数,稳定性和灵活性兼顾,也便于我们后续的管理。

代码语言:javascript
复制
-server
-Xms2048m
-Xmx2048m
-XX:MaxPermSize:256m
-Dapp.name=test
-Denv=prod
-Djava.io.tmpdir=/data/tmpdir
-Xloggc:/data/logs/gc.log
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC
-XX:+PrintReferenceGC
-Dsun.jnu.encoding=UTF-8

3.2 supervisor 守护管理

随着JVM启动参数的尘埃落定,如何启动Java进程就是我们接下来要面对的问题。我们经常使用的后台启动方式有以下几种:

  • nohup
  • screen
  • supervisor

其中nohup、screen都需要配合脚本,才能更友好的管理,因此我还是选择supervisor作为java应用的守护进程。

代码语言:javascript
复制
# 1.安装
yum install supervisor
systemctl enable supervisord
systemctl start supervisord

# 2.配置
vim /etc/supervisord.d/test.ini
[program:test]
;启动用户
user=work
;程序启动命令
command=java -server -Xms2048m -Xmx2048m -XX:MaxPermSize:256m -Dapp.name=test -Denv=prod -Djava.io.tmpdir=/data/tmpdir -Xloggc:/data/logs/gc.log -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps  -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintReferenceGC -Dsun.jnu.encoding=UTF-8 -jar test.jar
numprocs=1
;程序启动目录
directory=/App/java_app/test
;在supervisord启动时自启动
autostart=true
;程序异常退出后自动重启,可选值:[unexpected,true,false],默认为unexpected
autorestart=true
;启动10秒后没有异常退出,就表示进程正常启动了
startsecs=10
;启动失败自动重试次数
startretries=3

# 3.更新配置文件,更新配置文件并重启
supervisorctl update

# 4.重载配置文件 ,注意reload会导致supervisor重启,所管理的进程会重启
supervisorctl reload

# 5.查看状态
supervisorctl status

# 6.启动
supervisorctl start test

在此需要注意的是supervisor并不能托管任何进程,而只适合管理运行于前台的进程(如java 直接启动),对于运行后台daemon的进程(如tomcat),supervisorctl status会报错"BACKOFF Exited too quickly (process log may have details"。

4 小结

总结出一份用于运维过程中各个环境的JVM参数其实很简单,关键在于我们是否意识到了一份进程管理规范的重要性,怎样和当前的自动化水平来结合,实现其最终的价值。而对于只负责躺平的规范来说,我们做的这些工作意义不大。

原创: 三页 木纳大叔爱运维

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 需求
  • 2 进程规范
    • 2.1 GC日志
      • 2.2 dump文件
        • 2.3 堆内存
          • 2.4 JVM环境变量
          • 3 按规范管理
            • 3.1 统一管理
              • 3.2 supervisor 守护管理
              • 4 小结
              相关产品与服务
              微服务引擎 TSE
              微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档