日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

docker tomcat 多开 实例_Docker zabbix-agent 监控 docker tomcat 多实例

發布時間:2024/9/19 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 docker tomcat 多开 实例_Docker zabbix-agent 监控 docker tomcat 多实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

監控方案概述

我們使用 zabbix-agent 的方式來監控 多個 tomcat 8.5.51 ,由于我們需要監控的是 Docker 容器里的 Tomcat ,而 zabbix 官方模板并不支持,而且官方提供的第三方方案也不支持多實例監控,所以只能參考很多互聯網上的一些解決方案,最終形成了適合我們自己的應用場景的解決方案(監控虛擬機里的多個 tomcat 實例方案見文末的參考資料)。

本文詳細描述了整個方案的詳細過程和原理,如果只是想監控 tomcat 多個 Docker 實例,請參考:tomcat 監控實際操作

準備工作

配置 tomcat 容器的 LABEL 標簽:JMX_PORT 和 JMX_MONITOR_UUID 用于定義使用的 jmx 端口和 tomcat 的 UUID 標記。

tomcat 配置 jmx,實際上 java 應用的 jmx 監控中原理都相同,開啟并配置 jmx 的遠程監控配置即可,這個是監控的前提條件。

tomcat 自動發現腳本

tomcat_jmx 監控數據源腳本

cmdline-jmxclient-0.10.3.jar 來監控數據

處理 zabbix-server 獲取不到 zabbix-agent 收集的數據問題

處理 zabbix-agent 鏡像掛載容器外的 docker 進程時候報錯:permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

tomcat 容器鏡像啟動

拉取 tomcat 鏡像

docker pull develop-harbor.geostar.com.cn/base/apache-tomcat:8.5.51-8u231

啟動 tomcat 多實例

docker run -p 8088:8080 -p 10057:10057 --name tomcat-test1 -l JMX_MONITOR_UUID=bc47dcd484724fb48fe81bc9f0e3d802 -l JMX_PORT=10057 -d develop-harbor.geostar.com.cn/base/apache-tomcat:8.5.51-8u231

docker run -p 8089:8080 -p 10058:10058 --name tomcat-test2 -l JMX_MONITOR_UUID=bc47dcd484724fb48fe81bc9f0e3d803 -l JMX_PORT=10058 -d develop-harbor.geostar.com.cn/base/apache-tomcat:8.5.51-8u231

注意:這里啟動了 2 個 tomcat 容器實例,第一個容器內部 8080 映射到外部為 8088,jmx使用 10057 端口,第一個容器內部 8080 映射到外部為8089,jmx 使用 10058 端口。這里定義的我們約定的標簽有 JMX_PORT 和 JMX_MONITOR_UUID ,JMX_PORT 用于定義使用的 jmx 端口,JMX_MONITOR_UUID 用于定義 tomcat 實例的 UUID 標記,區分各個 tomcat實例。

定義這兩個標簽是為了后續使用 Docker 的 api 來獲取 tomcat 的監控信息(jmx 的端口、容器內部 ip、)

進入每個tomcat容器實例內部(以tomcat-test1為例子)

docker exec -it tomcat-test1 bash

配置 jmx 監聽

vi /srv/tomcat8/bin/catalina.sh

加入以下配置

CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10057 -Dcom.sun.management.jmxremote.rmi.port=10057 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=172.16.101.245"

其中-Djava.rmi.server.hostname=配置為當前服務器 ip,請自行修改,

-Dcom.sun.management.jmxremote.port=10057

-Dcom.sun.management.jmxremote.rmi.port=10057

這兩個 jmx 的端口需要與容器啟動時候用的 jmx 端口保持一致。

退出 tomcat 容器,重啟 tomcat 容器

exit

docker restart tomcat-test1

測試 jmx 能否獲取到數據,打開 jdk 目錄下面的 jconsole 工具,輸入 jmx 遠程連接 ip 和 jmx 連接端口

點連接后正常連接就證明 jmx 已正常啟用

在這個過程中我們發現一些主要的注意事項,請您在結合自己的監控場景的時候也一定注意:

帶密碼的 jmx 配置

我們在監控的時候因為會有很多個 tomcat 的 docker 實例,為了簡化監控,所以使用 jmx 連接并沒有設置密碼,如果需要密碼訪問 jmx ,那么需要設置如下的:

CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10057 -Dcom.sun.management.jmxremote.rmi.port=10057 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=172.16.101.245

-Dcom.sun.management.jmxremote.access.file=/srv/tomcat8/conf/jmx.access

-Dcom.sun.management.jmxremote.password.file=/srv/tomcat8/conf/jmx.password"

authenticate:改為 true

access.file:設置訪問權限,readonly:只能讀取 MBean 的屬性和接受通知。

readonly:只能讀取 MBean 的屬性和接受通知。

readwrite:還允許設置屬性,調用方法,創建和刪除 MBean。

# cat /srv/tomcat8/conf/jmx.access 如果不存在這個文件請自行創建

admin readwrite

password.file:訪問密碼

# cat /srv/tomcat8/conf/jmx.password 如果不存在這個文件請自行創建

admin tomcat

創建完成上述文件后,修改文件權限(這一步很關鍵,因為這些屬于敏感信息,所以需要限制訪問權限,不修改的話會在監控的時候報錯)

# chmod 400 jmx.*

注意:這個時候需要重啟 tomcat 容器讓配置生效

端口的映射問題

采用 tomcat 的 jmx 監控有一個限制,容器對外映射 jmx 端口,容器內部 jmx 端口,配置文件里的 jmx 端口,三者必須嚴格保持一致,不然無法正常獲取到監控數據,所以,必須是 -p 10057:10057 這種形式來啟動 tomcat 容器,如果是 10058:10057這種形式會失敗,或者在 dockerfile 里用 expose 10057,外部映射隨機端口,同樣會失敗,這個坑一定要注意。雖然 oracle 的工程師通過別的解決方案解決了這個問題,但是會引入 oracle 的一些商業軟件進來,規避了這個問題本身,所以不采取他們的方案:http://thegridman.com/coherence/oracle-coherence-on-docker/#jmx

ps ef | grep tomcat 過濾 tomcat jmx 端口方案

相對于用 docker api 的方式獲取 tomcat 容器 jmx 端口的方案,還有另外一種方案,僅供參考。

jmx_tomcat_discovery.sh,執行下面這個腳本就可以獲取 tomcat jmx 監控的端口號,如果是在 docker 版的 zabbix-agent 容器內執行,還需要在啟動這個 agent 容器的時候加上 --pid=host 這個啟動參數。

#!/bin/bash

# this is the server ip

serverip=127.0.0.1

# serverObj example:"{#SERVER_IP}": "172.16.101.181", "{#TOMCAT_NAME}": "tomcat_10053"

serverObj=""

# this cmd returns the jmx port the tomcat instances using

tomcat_jxm_ports_res=`ps -aux | grep "tomcat" | awk '{for(i=1;i<=NF;i++){print $i;}}' | grep jmxremote.port | cut -d'=' -f 2`

for tomcat_jmx_port in $tomcat_jxm_ports_res

do

tmp=\{\"{#SERVER_IP}\":\"$serverip\",\"{#TOMCAT_NAME}\":\"tomcat_$tomcat_jmx_port\",\"{#TOMCAT_PORT}\":\"$tomcat_jmx_port\"\},

serverObj="$serverObj$tmp"

done

# subString the last comma of the serverObj string

if [ $serverObj ] ; then

serverObj=${serverObj:0:-1}

fi

# the jsonResult is like {"data": [{"{#SERVER_IP}": "172.16.101.181", "{#TOMCAT_NAME}": "tomcat_10053", "{#TOMCAT_PORT}": "10053"}, {"{#SERVER_IP}": "172.16.101.181", "{#TOMCAT_NAME}": "tomcat_10053", "{#TOMCAT_PORT}": "10054"}]}

if [ $serverObj ] ; then

jsonResult=\{\"data\":[$serverObj]\}

echo $jsonResult

else

echo ""

fi

驗證是否能獲取 jmx 監控數據

除了用 jconsole 的本地方式連接測試外,更推薦一種在 zabbix-server上通過 cmdline-jmxclient 驗證的方式,因為這樣能確保服務端可以連接上客戶端。

服務端下載 cmdline-jmxclient

wget http://crawler.archive.org/cmdline-jmxclient/cmdline-jmxclient-0.10.3.jar

測試

[root@host-172-16-102-253 ~]# java -jar cmdline-jmxclient-0.10.3.jar - 172.16.101.245:10057 java.lang:type=Memory NonHeapMemoryUsage

05/04/2020 14:53:19 +0800 org.archive.jmx.Client NonHeapMemoryUsage:

committed: 36372480

init: 2555904

max: -1

used: 33912184

注意:如果是有用戶名/密碼的 jmx 監控,那么需要把 ip 前面的 - 替換為我們設置的 admin:tomcat

tomcat自動發現腳本

獲取 tomcat 多個容器實例的 容器 ip、tomcat JMX 端口,uuid,輸出為 json 格式提供給 zabbix-server 獲取使用(沒辦法,只能自己寫腳本咯,:)。

jmx_tomcat_discovery.py

#!/usr/bin/python

# -*- encoding: utf-8 -*-

import urllib

import xml.etree.ElementTree as ET

import json

import os

import commands

import subprocess

def main():

data = []

(status, docker_ps_output) = commands.getstatusoutput('docker ps -q')

docker_ps_output_text = docker_ps_output.decode('utf-8')

if docker_ps_output_text:

container_id_list=docker_ps_output_text.split('\n')

for container_id in container_id_list:

out_bytes = subprocess.check_output(['docker','inspect',container_id])

out_text = out_bytes.decode('utf-8')

result=json.loads(out_text)

jmx=result[0]['Config']['Labels']

if('JMX_PORT' in jmx):

jmx_port=result[0]['Config']['Labels']['JMX_PORT']

jmx_monitor_uuid=result[0]['Config']['Labels']['JMX_MONITOR_UUID']

ip=result[0]['NetworkSettings']['Networks']['bridge']['IPAddress']

tomcat_instance={"{#CONTAINER_IP}":ip,"{#JMX_PORT}":jmx_port,"{#JMX_MONITOR_UUID}":jmx_monitor_uuid}

data.append(tomcat_instance)

print json.dumps({"data": data})

else:

print "empty result of docker ps -q"

if __name__ == "__main__":

main()

這個腳本我們直接放到了自制的 zabbix-agent 容器鏡像內,供我們的自定義 UserParameter 來調用。你也可以根據你的情況放到你認為合適的位置。

tomcat_jmx監控數據源腳本

監控模板參考zabbix監控自動發現監控tomcat(V1)修改而來,定義了我需要的CONTAINER_IP,JMX_PORT,JMX_MONITOR_UUID 三個自定義占位符。

tomcat_monitor.sh,這個腳本跟上面的 python 腳本一樣放到 zabbix-agent 的容器鏡像里,供我們的自定義 UserParameter 來調用。這里我針對自己的環境和需要的東西做了優化,跟你環境不合適的位置請自行修改。

#!/bin/bash

source /etc/profile

[ $# -ne 3 ] && echo 'The scripts need 3 parameters' && exit 1

CONTAINER_IP=$1

JMX_PORT=$2

ITEM=$3

authenticate="-"

# if no authenticate,use "-",otherwise,add authenticate jmx user and password code here

# jmx_user="akiya"

# jmx_password="akiya_password"

# if [ -n "$jmx_user" ] && [ -n "$jmx_password" ]; then

# authenticate="$jmx_user:$jmx_password"

# fi

# The PORT means the tomcat service default port in the server.xml

PORT=8080

# The cmd means the directory of cmdline-jmxclient jar

cmd=/etc/zabbix/scripts/tomcat/cmdline-jmxclient-0.10.3.jar

#logdir=/tmp/zabbix_tmp

#[ ! -d "$logdir" ] && mkdir -p $logdir && chmod 644 $logdir

#cd $logdir

LOGDIR=/etc/zabbix/scripts/tomcat/logs

function HeapMemoryUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=Memory HeapMemoryUsage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function EdenSpaceUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=MemoryPool,name=PS\ Eden\ Space Usage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function SurvivorSpaceUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=MemoryPool,name=PS\ Survivor\ Space Usage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function TenuredGenUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=MemoryPool,name=PS\ Old\ Gen Usage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function NonHeapMemoryUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=Memory NonHeapMemoryUsage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function MetaspaceUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=MemoryPool,name=Metaspace Usage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function CodeCacheUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=MemoryPool,name=Code\ Cache Usage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function CompressedClassSpaceUsage() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=MemoryPool,name=Compressed\ Class\ Space Usage 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function TotalLoadedClassCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=ClassLoading TotalLoadedClassCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function LoadedClassCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=ClassLoading LoadedClassCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function UnloadedClassCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=ClassLoading UnloadedClassCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function TotalStartedThreadCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=Threading TotalStartedThreadCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function ThreadCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=Threading ThreadCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function PeakThreadCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=Threading PeakThreadCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function maxThreads() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT Catalina:name=\"http-nio-$PORT\",type=ThreadPool maxThreads 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function currentThreadCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT Catalina:name=\"http-nio-$PORT\",type=ThreadPool currentThreadCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function currentThreadsBusy() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT Catalina:name=\"http-nio-$PORT\",type=ThreadPool currentThreadsBusy 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function GlobalRequestProcessor_bytesReceived() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT Catalina:name=\"http-nio-$PORT\",type=GlobalRequestProcessor bytesReceived 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function GlobalRequestProcessor_bytesSent() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT Catalina:name=\"http-nio-$PORT\",type=GlobalRequestProcessor bytesSent 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function requestCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT Catalina:name=\"http-nio-$PORT\",type=GlobalRequestProcessor requestCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function errorCount() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT Catalina:name=\"http-nio-$PORT\",type=GlobalRequestProcessor errorCount 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

function jvmUptime() {

java -jar $cmd $authenticate $CONTAINER_IP:$JMX_PORT java.lang:type=Runtime Uptime 2>$LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

}

case $ITEM in

HeapMemoryUsage.max)

HeapMemoryUsage

sed -n '4p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

HeapMemoryUsage.used)

HeapMemoryUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

HeapMemoryUsage.committed)

HeapMemoryUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

EdenSpaceUsage.max)

EdenSpaceUsage

sed -n '4p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

EdenSpaceUsage.used)

EdenSpaceUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

EdenSpaceUsage.committed)

EdenSpaceUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

SurvivorSpaceUsage.max)

SurvivorSpaceUsage

sed -n '4p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

SurvivorSpaceUsage.used)

SurvivorSpaceUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

SurvivorSpaceUsage.committed)

SurvivorSpaceUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

TenuredGenUsage.max)

TenuredGenUsage

sed -n '4p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

TenuredGenUsage.used)

TenuredGenUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

TenuredGenUsage.committed)

TenuredGenUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

NonHeapMemoryUsage.used)

NonHeapMemoryUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

NonHeapMemoryUsage.committed)

NonHeapMemoryUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

MetaspaceUsage.used)

MetaspaceUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

MetaspaceUsage.committed)

MetaspaceUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

CodeCacheUsage.max)

CodeCacheUsage

sed -n '4p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

CodeCacheUsage.used)

CodeCacheUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

CodeCacheUsage.committed)

CodeCacheUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

CompressedClassSpaceUsage.max)

CompressedClassSpaceUsage

sed -n '4p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

CompressedClassSpaceUsage.used)

CompressedClassSpaceUsage

sed -n '5p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

CompressedClassSpaceUsage.committed)

CompressedClassSpaceUsage

sed -n '2p' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT | awk '{print $2}'

;;

ClassLoading.TotalLoadedClassCount)

TotalLoadedClassCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

ClassLoading.LoadedClassCount)

LoadedClassCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

ClassLoading.UnloadedClassCount)

UnloadedClassCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

Threading.TotalStartedThreadCount)

TotalStartedThreadCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

ThreadCount)

ThreadCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

PeakThreadCount)

PeakThreadCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

maxThreads)

maxThreads

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

currentThreadCount)

currentThreadCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

currentThreadsBusy)

currentThreadsBusy

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

bytesReceived)

GlobalRequestProcessor_bytesReceived

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

bytesSent)

GlobalRequestProcessor_bytesSent

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

requestCount)

requestCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

errorCount)

errorCount

awk '{print $6}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT

;;

jvmUptime)

jvmUptime

[ $? -eq 0 ] && awk '{print $6/1000}' $LOGDIR/$CONTAINER_IP.$ITEM.$JMX_PORT || echo 0

;;

esac

我們的 userparameter_tomcat.conf 里配置如下:

UserParameter=tomcat.discovery,/usr/bin/python /etc/zabbix/scripts/tomcat/jmx_tomcat_discovery.py

UserParameter=tomcat.status[*],/bin/bash /etc/zabbix/scripts/tomcat/tomcat_monitor.sh $1 $2 $3

處理 zabbix-server 獲取不到 zabbix-agent 收集的數據問題

在 zabbix_server 端上使用 zabbix_get 測試的時候,會出現權限錯誤無數據,這個時候應該修改 zabbix-agent 容器里這些腳本的所屬用戶。

chown -R zabbix:zabbix /etc/zabbix/scripts/tomcat

chmod 775 /etc/zabbix/scripts/tomcat/cmdline-jmxclient-0.10.3.jar /etc/zabbix/scripts/tomcat/jmx_tomcat_discovery.py /etc/zabbix/scripts/tomcat/tomcat_monitor.sh

zabbix-agent 鏡像掛載容器外的 docker 進程時候報錯

因為,我們的腳本里用到 docker ps 、 docker inspect 等命令,所以需要在 zabbix-agent 容器里掛載宿主的 docker 進程,即 -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock 這個掛載參數,會出現這個錯誤:

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

這個時候需要修改權限解決,在容器啟動的時候修改權限(這個已經預制到我的 zabbix-agent 鏡像里了)

chmod 777 /var/run/docker.sock

測試

在 zabbix-server 可以用下面的命令來測試 jmx 的所有 Bean(只到 ip:port部分,不包括后面部分) 和 Bean 的值(包括具體的 Bean 名字和屬性)

# java -jar cmdline-jmxclient-0.10.3.jar - 172.16.101.245:10057

# java -jar cmdline-jmxclient-0.10.3.jar - 172.16.101.245:10057 java.lang:type=Memory NonHeapMemoryUsage

在 zabbix-server 的容器鏡像內,可以使用下面的命令來獲取用戶自定義參數 UserParameter 對應的 key 的值執行后獲取的結果,比如:下面的例子會執行 jmx_tomcat_discovery.py 腳本,獲取返回值。

# zabbix_get -s 172.16.102.96 -k tomcat.discovery

UserParameter=tomcat.discovery,/usr/bin/python /etc/zabbix/scripts/tomcat/jmx_tomcat_discovery.py

tomcat 監控

zabbix 主機管理頁面關聯 Templates App Tomcat 模版即可獲得多個 tomcat 的 docker 實例的監控數據

監控到的數據

監控原理

現在,是時候總結下 多個 docker 的 tomcat 實例監控的原理了。

開啟 tomcat 容器鏡像的 jmx 監控配置并配置對外映射端口

用我們的自定義用戶腳本,執行 jmx_tomcat_discovery.py 獲取到多個 tomcat 容器的端口號,ip 地址, uuid 等信息,供 zabbix-server 端的自動發現規則使用

我們用發現出來的 ip ,port ,uuid 填充我們監控模板中的鍵,這樣就保證了監控的每一個 key 都不一致(這個限制由 zabbix 本身決定了,也是為什么很多方案做不到監控多實例的原因),通過這個 key 去請求我們的 tomcat_monitor.sh 腳本,獲取到監控項的值。

主要參考資料

總結

以上是生活随笔為你收集整理的docker tomcat 多开 实例_Docker zabbix-agent 监控 docker tomcat 多实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。