Dockerfile配置APM监控实现Java容器的性能监控

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 通过Dockerfile可以用来构建容器镜像,我们一般也是通过这种方式来构建一个Tomcat应用服务容器,如果要实现对容器中的Tomcat服务(或是其他Java应用)进行APM(应用性能管理)监控,就需要我们在容器中放置javaagent并做相关配置,而在已生成的容器中修改配置不符合容器管理的规范,所以我们建议在发布镜像时就将javaagent植入,这样在生成容器时就可以通过环境变量参数来决定是否开启监控。
版权声明:本文为博主原创文章,未经博主允许不得转载。欢迎访问我的博客 https://blog.csdn.net/smooth00/article/details/80858394

通过Dockerfile可以用来构建容器镜像,我们一般也是通过这种方式来构建一个Tomcat应用服务容器,如果要实现对容器中的Tomcat服务(或是其他Java应用)进行APM(应用性能管理)监控,就需要我们在容器中放置javaagent并做相关配置,而在已生成的容器中修改配置不符合容器管理的规范,所以我们建议在发布镜像时就将javaagent植入,这样在生成容器时就可以通过环境变量参数来决定是否开启监控。

(请持续关注smooth的博客:https://blog.csdn.net/smooth00,另外有关容器的文章还可以关注:《搭建Jmeter容器集群平台》、《以容器部署Ganglia并监控Hadoop集群》、《Rancher及Docker快速上手指南(一)》、《Rancher及Docker快速上手指南(二)》、《Rancher及Docker快速上手指南(三)》、《Jenkins自动化部署容器》)

以下是以Zoho Applications Manager当中的应用性能管理产品为例(像听云、OneAPM等应用性能管理也属于同类产品,原理一样,以下配置的关键是将监控代理javaagent的jar包和相关配置文件通过Dockerfile写入到镜像中,并通过环境变量更改配置项):

1、修改catalina.sh

一般APM监控,都是在catalina.sh中追加JAVA_OPTS配置,如下:

export JAVA_OPTS="$JAVA_OPTS -javaagent:$CATALINA_HOME/apminsight/apminsight-javaagent.jar"

我们这次也是这么干的,但是会加一个开关来if控制:

if [ "$APM_IS_OPEN" = "true" ] ; then
    export JAVA_OPTS="$JAVA_OPTS -javaagent:$CATALINA_HOME/apminsight/apminsight-javaagent.jar"

fi

2、修改apminsight.conf

这是监控代理的配置文件,其他产品也有类似的配置文件,主要是对以下几个参数进行标准化设置

application.name=@APM_NAME@ #这是应用名,这个名称是用来替换的

apm.host=@127.0.0.1@ #这是APM监控平台的IP,也是用来替换的

apm.port=@9090@ #这是APM监控平台的端口,也是用来替换的

3、准备好要部署tomcat的文件或要替换的配置文件

比如:jdk-8u171-linux-x64.tar.gz、apache-tomcat-8.5.32.tar.gz、tomcat-users.xml、server.xml,这些文件都是要确保可以在真实机器上安装部署和使用的。

然后准备要发布到tomcat上的应用war包或者文件,我的环境是rfzf.war

4、配置Dockerfile

# First docker file from zhengguanghua
# VERSION 1.0.1
# Author: zhengguanghua

FROM ubuntu:14.04.3
#作者
# MAINTAINER zhengguanghua <zq2599@gmail.com>
# add java and tomcat 支持包到容器中 
ADD jdk-8u171-linux-x64.tar.gz /usr/local/ 
ADD apache-tomcat-8.5.32.tar.gz /usr/local/ 
RUN mv /usr/local/apache-tomcat-8.5.32 /usr/local/tomcat
# 配置 java and tomcat 环境变量 
ENV JAVA_HOME /usr/local/jdk1.8.0_171 
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 
ENV CATALINA_HOME /usr/local/tomcat 
ENV CATALINA_BASE /usr/local/tomcat 
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin 

#定义工作目录
ENV WORK_PATH /usr/local/tomcat

#定义要发布的war包文件名
ENV WEB_APP rfzf.war

#删除原文件tomcat-users.xml,可不删除直接COPY覆盖
#RUN rm $CONF_PATH/$USER_CONF_FILE_NAME

#复制文件tomcat-users.xml
COPY  ./tomcat-users.xml $WORK_PATH/conf/
#复制文件server.xml
COPY  ./server.xml $WORK_PATH/conf/
#复制APM监控代理目录apminsight
COPY apminsight $WORK_PATH/apminsight
#复制文件catalina.sh
COPY  ./catalina.sh $WORK_PATH/bin/
#复制tomcat启动文件(文件里也包含apminsight监控代理的配置替换命令)
COPY startTomcat.sh /usr/local/

#给可执行文件赋权限,并配置东八区时区
RUN chmod +777 /usr/local/startTomcat.sh && chmod +777 $WORK_PATH/bin/catalina.sh \
    && /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo 'Asia/Shanghai' >/etc/timezone

#复制war包到wepapps目录下
COPY ./$WEB_APP $WORK_PATH/webapps/

# container listener port 
# EXPOSE 8080 
# startup web application services by self 
# CMD /usr/local/tomcat/bin/catalina.sh run
#让容器当前目录定位到工作目录下
WORKDIR $WORK_PATH
#启动容器
CMD ["sh", "/usr/local/startTomcat.sh"]

5、编写startTomcat.sh

由于容器的CMD一般只能执行一个进程命令(多个CMD命令也是最后一个覆盖前面的),所以把APM监控代理的配置文件修改命令和tomcat启动命令全放到startTomcat.sh中,通过一个CMD命令调用。

#!/bin/bash

#用sed将环境变量替换成apminsight.conf中的参数
sed -i "s/@APM_NAME@/${APM_NAME}/g" /usr/local/tomcat/apminsight/apminsight.conf
sed -i "s/@127.0.0.1@/${APM_HOST}/g" /usr/local/tomcat/apminsight/apminsight.conf
sed -i "s/@9090@/${APM_PORT}/g" /usr/local/tomcat/apminsight/apminsight.conf

#启动tomcat,容器不能用后台运行进程,所以用run在控制台显示
/usr/local/tomcat/bin/catalina.sh run

以上启动tomcat命令用run(必须用run,用catalina.sh start或是startup.sh都不好使),可以防止容器一启动就关闭(这是容器的一个特性,也是最大的一个坑,应用进程必须在前台运行,才能成为容器的守护进程,即进程一旦退出或从前台中止运行容器也会跟着停止)。

以下总结一下容器start.sh的命令原则:

(1)原则上一个容器就运行一个进程,这就是为什么容器服务要尽量简单,多进程应用需要拆分成多个容器
(2)容器中要是运行多个守护进程时,前面的进程要用后台方式运行(或添加 &),否则后面的服务无法启动
(3)容器中最后一个守护进程一定要用前台方式运行,否则start.sh退出,容器退出,所有的服务就白启动了

注:为什么CMD命令默认一定是覆盖而不是继承或追加,很多初次接触这块的人都会不理解这么设计的用意(觉得不能同时多次调用CMD不方便),其实这么实现是很有必要的,比如你在Dockerfile用FROM继承了一个基础镜像,每个基础镜像肯定都有自己的一套进程逻辑和CMD启动命令,如果不设计成覆盖的模式,那么我们对原有容器镜像的任何配置和修改,以及追加新进程,都要顾及太多原有进程的影响,这不利于镜像的继承或嵌套。

6、构建镜像

将以上所有文件都传到一个目录下,比如/home/rfzf-tomcat,然后我们进入这个目录,执行以下命令build成镜像:

docker build -t docker-tomcat:1.0 .

7、调用镜像生成容器

建议将tomcat的logs通过卷的方式持续化日志文件,在宿主机上建立目录/opt/tomcat-logs,并赋予读写权限。以下是生成容器的命令:

docker run --name docker-tomcat -d --restart=unless-stopped -p 8080:8080 -e APM_NAME=Docker_Tomcat -e APM_HOST=172.16.1.251 -e APM_PORT=9099 -e APM_IS_OPEN=true -v /opt/tomcat-logs:/usr/local/tomcat/logs docker-tomcat:1.0

这样就可以生成容器,而且通过环境变量(-e)将APM的HOST、端口等替换(在启动tomcat前被替换)了,而且通过APM_IS_OPEN=true,在catalina.sh中也会调用apminsight-javaagent.jar监控代理文件。

以下是运行的容器监视图:

通过Tomcat的业务窗体访问,在APM监控平台就能看到应用服务的监控数据:

       总结:对于性能监控来说,容器和虚拟机下操作其实没有太大差别,唯一的差别是容器是一种封装的应用,既然是封装,我们的监控服务也应该一起封装进去,而不是等容器部署完了,才开始考虑监控的配置和开启,一是不方便操作,二是不符合容器的管理要求(容器是即用即生成,不用即消亡,不适合在容器里做过多配置化操作)。

相关实践学习
通过轻量消息队列(原MNS)主题HTTP订阅+ARMS实现自定义数据多渠道告警
本场景将自定义告警信息同时分发至多个通知渠道的需求,例如短信、电子邮件及钉钉群组等。通过采用轻量消息队列(原 MNS)的主题模型的HTTP订阅方式,并结合应用实时监控服务提供的自定义集成能力,使得您能够以简便的配置方式实现上述多渠道同步通知的功能。
目录
相关文章
|
8天前
|
监控 Kubernetes Java
使用 New Relic APM 和 Kubernetes Metrics 监控 EKS 上的 Java 微服务
在阿里云AKS上运行Java微服务常遇性能瓶颈与OOMKilled等问题。本文教你通过New Relic实现集群与JVM双层监控,集成Helm部署、JVM代理注入、GC调优及告警仪表盘,打通从节点资源到应用内存的全链路观测,提升排障效率,保障服务稳定。
56 0
|
2月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
66 0
|
5月前
|
存储 机器学习/深度学习 监控
如何监控员工的电脑——基于滑动时间窗口的Java事件聚合算法实现探析​
在企业管理场景中,如何监控员工的电脑操作行为是一个涉及效率与合规性的重要课题。传统方法依赖日志采集或屏幕截图,但数据量庞大且实时性不足。本文提出一种基于滑动时间窗口的事件聚合算法,通过Java语言实现高效、低资源占用的监控逻辑,为如何监控员工的电脑提供一种轻量化解决方案。
127 3
|
7月前
|
存储 安全 算法
Java容器及其常用方法汇总
Java Collections框架提供了丰富的接口和实现类,用于管理和操作集合数据。
Java容器及其常用方法汇总
|
7月前
|
人工智能 Prometheus 监控
容器化AI模型的监控与治理:确保模型持续稳定运行
在前几篇文章中,我们探讨了AI模型的容器化部署及构建容器化机器学习流水线。然而,将模型部署到生产环境只是第一步,更重要的是确保其持续稳定运行并保持性能。为此,必须关注容器化AI模型的监控与治理。 监控和治理至关重要,因为AI模型在生产环境中面临数据漂移、概念漂移、模型退化和安全风险等挑战。全面的监控涵盖模型性能、数据质量、解释性、安全性和版本管理等方面。使用Prometheus和Grafana可有效监控性能指标,而遵循模型治理最佳实践(如建立治理框架、定期评估、持续改进和加强安全)则能进一步提升模型的可信度和可靠性。总之,容器化AI模型的监控与治理是确保其长期稳定运行的关键。
|
8月前
|
运维 监控 算法
企业局域网监控软件中 Java 优先队列算法的核心优势
企业局域网监控软件是数字化时代企业网络安全与高效运营的基石,犹如一位洞察秋毫的卫士。通过Java实现的优先队列算法,它能依据事件优先级排序,确保关键网络事件如异常流量、数据泄露等被优先处理,保障系统稳定与安全。代码示例展示了如何定义网络事件类并使用PriorityQueue处理高优先级事件,尤其在面对疑似风险时迅速启动应急措施。这一核心技术助力企业在复杂网络环境中稳健前行,护航业务腾飞。
116 32
|
8月前
|
存储 监控 算法
探秘局域网桌面监控:深入剖析 Java 语言核心算法
在数字化办公时代,局域网桌面监控如同企业的“智慧鹰眼”,确保工作效率与数据安全。本文以Java为载体,揭示哈希表在监控中的关键应用。通过高效的数据结构和算法,哈希表能快速索引设备连接信息,大幅提升监控的时效性和响应速度。代码示例展示了如何用Java实现设备网络连接监控,结合未来技术如AI、大数据,展望更智能的监控体系,助力企业在数字化浪潮中稳健前行。
|
2月前
|
存储 监控 测试技术
如何将现有的应用程序迁移到Docker容器中?
如何将现有的应用程序迁移到Docker容器中?
254 57
|
2月前
|
存储 监控 Java
如何对迁移到Docker容器中的应用进行性能优化?
如何对迁移到Docker容器中的应用进行性能优化?
245 58
|
2月前
|
NoSQL Redis Docker
使用Docker Compose工具进行容器编排的教程
以上就是使用Docker Compose进行容器编排的基础操作。这能帮你更有效地在本地或者在服务器上部署和管理多容器应用。
311 11