k8s部署的微服务应用异常了该如何处理?

3 篇文章 0 订阅
当k8s部署的微服务应用出现异常时,通过查看服务日志发现连接注册中心超时,同时发现内存暴增和网络带宽增加。经过分析,确定问题由内存增长引起,但未找到OOM系统报错。使用jstack进行堆栈分析,并编写自动化脚本监控内存使用,当超过阈值时自动处理,以减轻手动干预负担。
摘要由CSDN通过智能技术生成

项目场景:

k8s部署的微服务应用,线上环境某个微服务应用异常了,怎么办,如何处理?


问题描述

1.前段时间,公司的采集服务,老是异常,导致线上功能用不了,甚至报错
2.尝试重启服务解决,但过几个小时,又来了。应用日志也不明显,找不到根本原因
3.为此,仅仅只是重启远远不够的,需要追究根本原因
4.那么,k8s部署的微服务应用,线上环境某个微服务应用异常了,怎么办,如何处理?


原因分析:

1.查看采集服务日志

[root@master ~]# kubectl get pod |grep collect
data-collector-service-zhizhi-5fb9df9586-shrhc    1/1     Running   0    41d
[root@master ~]# kubectl logs -f --tail=400  data-collector-service-zhizhi-5fb9df9586-shrhc
#关键日志如下,33030为eureka端口
Caused by: org.apache.http.NoHttpResponseException: 192.168.5.12:33030 failed to respond

由此判断,连接注册中心超时了,查看异常时,也从注册中心掉线了。但实际上服务不健康的时候就会导致连接不上eureka,所以这里的日志也只是表面日志,继续观察

2.查看zabbix节点负载情况,内存有徒增情况,但这只是节点级别的,这个节点有很多pod不能精准定位是哪个pod导致 的
3.于是通过promethues查看pod监控信息,发现异2个异常点
带宽异常
看图发现网络带宽徒增,貌似有问题
内存1
看图发现pod内存暴增到30G,平常正常的最多只用到2个G

4.判断分析,主要是由哪个指标导致的异常。
分析:首先这个是内网环境,节点之间网络传输达到几十M都是正常现象,所以网络带宽徒增并不是我们的问题所在。如果是公网环境还可以归根一下网络带宽是有问题的。故排除内网环境,带宽徒增导致的异常。

5.既然是内存暴增引起的,会不会是OOM导致的呢或者是jvm参数不够导致的,虽然日志并没有报错OOM,系统日志/var/log/messages也没有查到oom相关信息

[root@node01 ~]# grep -i oom /var/log/messages
[root@node01 ~]# 
#说明没有oom系统报错
#进到master主机看看jvm设置
[root@master ~]# cat collect_deployment.yml
env:
   - name: JAVA_OPTS
     value: '-Xmx4096m'
#将这个增大到10倍后再观察,但不能大于本机物理内存
[root@master ~]# cat collect_deployment.yml
env:
   - name: JAVA_OPTS
     value: '-Xmx40960m'          

6.很不辛,增大了,过了几个小时,异常还是复现了。最高到了30个G的内存使用

7.这个时候,日志不明显,重启又会经常复现,也没有oom,那我们只能导出jvm。常见的jvm工具很多,jmap,jstack等,我们这里演示使用jstack

8.基础镜像,保证有jstack命令,我这个环境没有jstack命令,需要改造基础镜像。

#改造过程中可能遇到问题,像这样
/ # jstack 1
1: Unable to get pid of LinuxThreads manager thread
#百度解决一下吧

9.将改造好的镜像上传到私服harbor,这里不演示了

10.重启微服务后,编写自动化脚本,避免凌晨还要自己去手动处理,直接自动化处理

#!/bin/bash
#function:此脚本通过检测pod内存指标,来备份坏的pod,启动新的好的pod。并通过检测是否下线来做出相应的重启操作,支持多实例的pod。脚本有前提条件,部署了kube-promethues才可以使用kubectl top命令哦

for i in `kubectl get pod --show-labels |grep collect|grep -v zhizhi-bak|awk '{print $1}'` ;
do
pod_mem=`kubectl top pod $i |awk 'NR>1 {print $3}'|awk -F 'M' '{print $1}'`
#echo ${pod_mem}
if [ "$pod_mem" -gt  27648 ];then
  date && echo $i 内存大于 27648 准备隔离pod
  kubectl label pod $i app=data-collector-service-zhizhi-bak --overwrite
  #保留3个bak标签的pod
  j=0
    while [ $j -lt 1 ]
    do
      bak_num=`kubectl get pod --show-labels --sort-by=.metadata.creationTimestamp |grep collect|grep zhizhi-bak|wc -l`
      if [ $bak_num -gt 3 ];then
         kubectl delete pod `kubectl get pod --show-labels --sort-by=.metadata.creationTimestamp |grep collect|grep zhizhi-bak |tail -2 |head -1 |awk '{print $1}'`
      else j=1
      fi
    done
  sleep 120
fi
a=`curl -s http://user:password@192.168.5.12:33030/eureka/apps/你的注册中心的服务名 |grep -i status`
echo $a |grep -i up
if [ "$?" != 0 ] ; then
  echo " 注册 failed"
  kubectl delete pod `kubectl get pod --show-labels |grep collect|grep -v zhizhi-bak|grep Running|awk '{print $1}'`
fi
done

11.解释一下脚本的算法,因为发现异常时,有时候会看到内存暴增现象,有时候会发现服务从注册中心掉线,所以对这2个情况都做了判断。循环只写了2层,避免了逻辑的复杂性。sleep时间,你自己根据你的环境进行调整即可,其他内容服务名,svc都要改成你的。

12.创建定时任务

[root@master data-collector]# chmod +x /root/test_pod_mem.sh
[root@master data-collector]# crontab  -e
#添加这一行后保存
*/4 * * * * /bin/bash /root/test_pod_mem.sh >>/root/test_pod_mem.log &

13.坐等异常发生,后使用jstack命令导出堆栈信息

[root@容器id data-collector]# top
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    6     1 root     S    3929m  44%   2   0% java -javaagent:/usr/skywalking/agent/skywalking-agent.jar
   85     0 root     S     1528   0%   2   0% /bin/sh
    1     0 root     S     1520   0%   1   0% /bin/sh -c java $JAVA_OPTS -jar /collect.jar
   91    85 root     R     1516   0%   2   0% top
[root@容器id data-collector]# jstack 6 >> dump.log
#退出容器,将文件cp出来
[root@master ~]# kubectl cp data-collector-service-zhizhi-5fb9df9586-shrhc:/opt/data-collector/dump.log  /root/dump.log

14.分析堆栈信息,如果你功力深厚可以直接根据线程排查到具体代码,像这样:
jstack排查java堆栈异常

15.当然,别人的代码你可能不想看,那自己把这个文件给研发排查吧


解决方案:

解决方案已在第二部分给出,请自提,还望网友斧正
原文地址请注明出处

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

day-day-up2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值