shell 统计所有docker容器的 MongoDB连接数

2018-11-14  本文已影响0人  Yellowtail

需求

我们的MongoDB 经常发生连接数用完,导致报错

com.mongodb.MongoSocketReadException: Prematurely reached end of stream

所以想看下哪个docker容器占用最多,好排查问题
但是手工一个一个的去查看,过于繁琐,所以写了一个脚本,一劳永逸

脚本

#!/bin/bash

docker_id_list=(`docker ps|grep registry| awk '{print $1}'`)
docker_name_list=(`docker ps|grep registry| awk '{print $2}'`)

total=0
for((i=0;i<${#docker_id_list[*]};i++))
do
    docker_id=${docker_id_list[$i]}
    con_result=`docker exec -i ${docker_id} sh -c "ss -a |grep 3717|wc -l"`    
    #判断是不是数字,不是说明报错了,忽略之
    if echo ${con_result} | grep -q '^[0-9]\+$'; then
        docker_name_list[$i]="${docker_name_list[$i]}-------${con_result}"
        total=$(($total+$con_result))
    else
        docker_name_list[$i]="${docker_name_list[$i]}-------0"
    fi
done

#输出结果
for name in ${docker_name_list[*]}
do
    echo $name
done

echo "total is $total" 

截图


result

脚本解释

数组生成

docker_id_list=(`docker ps|grep registry| awk '{print $1}'`)
docker_name_list=(`docker ps|grep registry| awk '{print $2}'`)
  1. docker ps
    查看在运行的容器信息
  2. grep registry
    因为docker ps输出结果会带上标题,所以用个grep命令把标题消除
  3. awk '{print $1}'
    $1 是取第一列,也就是容器id, $2是第二列,也就是容器name
  4. docker_id_list=(` xxx `)
    这个语句是把xxx执行的结果保存到数组docker_id_list里面
  5. for((i=0;i<${#docker_id_list[*]};i++))
    带索引的方式去遍历数组,注意数组长度的写法是 ${#xxx[*]}
  6. docker_id=${docker_id_list[$i]}
    得到容器id,注意 取数组某个下标处的值是 ${xxx[$i]}, 最外面的${}一定要带上,不然就识别为字符串了
  7. ss -a |grep 3717|wc -l
    ss -a统计所有socket信息
    grep 3717 是过滤连接到数据库端口的socket
    wc -l是统计数量
  8. con_result=`docker exec -i ${docker_id} sh -c "ss -a |grep 3717|wc -l"`
    docker exec -it xxx sh -c "xxx" 这个是进入某个docker容器执行某个命令
    常见的docker exec -it xxx /bin/bash是进入容器,再输入命令执行,此处是一气呵成
  9. if echo ${con_result} | grep -q '^[0-9]\+$'; then
    因为ss -a |grep 3717|wc -l执行的时候,某些容器可能会报错,所以这里要判断下返回值是不是数字
  10. docker_name_list[$i]="${docker_name_list[$i]}-------${con_result}"
    数组修改值语句是 xxx[i]=abc,直接写索引,修改即可
    "${docker_name_list[$i]}-------${con_result}" 这个是取变量的语句,注意数组值的取法,要带上${}
    因为数组默认是空格隔开,所以这里用----来隔开name和数量,便于查看的同时,确保修改成功,用空格就变成两条了
  11. total=$(($total+$con_result))
    $(()) 最里层的语句会被当成表达式进行4则计算,其实就是total+=con_result
  12. for name in ${docker_name_list[*]}
    这个是另一种形式的遍历数组:不带索引,类似于Java里的语法糖 for(String x in list)

参考

数组的用法 https://blog.csdn.net/jerry_1126/article/details/52027539
docker exec https://docs.docker.com/engine/reference/commandline/exec/

上一篇下一篇

猜你喜欢

热点阅读