java生产环境出问题_记一次生产环境内存故障排查

本文记录了一次生产环境中Java服务频繁出现内存报警的排查过程。通过编写脚本定时检查内存并dump信息,最终发现是filebeat的json配置问题导致。禁用相关配置后,故障得以解决。
摘要由CSDN通过智能技术生成

最近生产环境经常有个服务器出现内存报警,上面跑了个java接口服务,但大概一段时间后会自动恢复。报警如下图:

5433c30d332e28a326aa3813af0f1097.png

由于故障已自动恢复,无法知道问题原因。只能写了个脚本定时检查服务器内存情况,如果有问题就dump内存和线程信息。

代码如下:

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

import os

import sys

import time

from utils import log_utils

def get_logger():

global _log_path, _logger, _log_file_name

if _logger is not None:

return _logger

_logger = log_utils.get_logger(os.path.join(_log_path, _log_file_name))

return _logger

def get_process_memory(processName):

''' 获取进程内存 '''

cmd = 'pgrep -f %s' % (processName)

pids = os.popen(cmd).readlines()

for pid in pids:

l = pid.strip()

if l is None or l == '':

return None

return int(l)

def get_os_memory():

''' 获取系统内存 '''

cmd = 'free '

memorys = os.popen(cmd).readlines()

i = 0

mem = {

'mem':{},

'swap':{}

}

for memory in memorys:

if 0 == i:

i =+ 1

continue

ms = memory.strip().split()

if len(ms) < 2:

continue

if 'mem' in ms[0].lower():

mem['mem'] = {

'total' : int(ms[1]),

'used': int(ms[2]),

'free': int(ms[3]),

'shared': int(ms[4]),

'buff': int(ms[5]),

'available': int(ms[6]),

}

continue

if 'swap' in ms[0].lower():

mem['swap'] = {

'total': int(ms[1]),

'used': int(ms[2]),

'free': int(ms[3]),

}

return mem

def run_cmd(cmd):

''' 执行系统命令返回输出 '''

results = os.popen(cmd).readlines()

return results

def get_os_memory_ratio():

''' 获得系统可用内存比例 '''

mem = get_os_memory()

if len(mem['mem'].keys()) < 2:

return None

total = mem['mem'].get('total', 0)

if total <= 0:

return None

active_mem = mem['mem'].get('used', 0) - mem['mem'].get('buff', 0)

ratio = active_mem / total

return ratio

def save_java_process_status():

global _os_memory_ratio, _process_name, _log_path

# 获取应用进程PID

pid = get_process_memory(_process_name)

if pid is None or pid <= 1:

return

ti = str(time.time())

dumpCmd = 'jmap -dump:live,format=b,file=%s %s' % (os.path.join(_log_path, 'jmap_' + ti + '.bin'), str(pid))

get_logger().info(dumpCmd)

run_cmd(dumpCmd)

stactCmd = 'jstack %s > %s' % (str(pid), str(os.path.join(_log_path, 'jstack_' + ti + '.log')))

get_logger().info(stactCmd)

run_cmd(stactCmd)

def check_memory():

global _os_memory_ratio, _process_name, _log_path

ratio = get_os_memory_ratio()

get_logger().info('now memory ratio: %s' % (str(ratio)))

if ratio is None or ratio < _os_memory_ratio:

return False

# 获取内存占用前三的进程

cmd = 'ps -aux | sort -k4nr | head -3'

results = run_cmd(cmd)

for r in results:

get_logger().info('process memory top: %s' % (r))

return True

def run():

global _time_interval

get_logger().info('check_memory start...')

save_time = 0

while(True):

if not check_memory():

time.sleep(65)

continue

now_time = time.time()

if (save_time + _time_interval) < now_time:

save_time = now_time

save_java_process_status()

# 日志文件路径

_log_path = '/data0/script/check-memory/logs'

_log_file_name = 'run.log'

_logger = None

# 内存占用比例

_os_memory_ratio = 0.8

# 进程名

_process_name = 'process-name'

# 每次dump时间间隔

_time_interval = 60 * 60 * 24

if __name__ == '__main__':

run()

过了几天,果然又报故障了,然而上去看了下果然有dump文件,但一看大小确却发现比较正常。

55df20b2bf7191922f8c8c17021484af.png

好在同时也记录了当时内存最大的前三进程:

586f88f0613f965c6535cd0558f4543c.png

检查了一下filebeat配置,怀疑是由于json相关配置导致

e22b326f5563603b1cbc165b1014f8b7.png

由于用不上,我们先把这些注掉观察,目前没有再出现异常情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值